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


      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-2020 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 #if defined(BCM_HURRICANE4_SUPPORT)
    139 #include <soc/esw/cancun.h>
    140 #include <bcm_int/esw/hurricane4.h>
    141 #include <soc/hurricane4.h>
    142 #endif /* BCM_HURRICANE4_SUPPORT */
    143 #if defined(BCM_FIREBOLT6_SUPPORT)
    144 #include <soc/esw/cancun.h>
    145 #include <bcm_int/esw/firebolt6.h>
    146 #include <soc/firebolt6.h>
    147 #endif /* BCM_FIREBOLT6_SUPPORT */
    148 #if defined (BCM_HGPROXY_COE_SUPPORT)
    149 #include <bcm_int/esw/xgs5.h>
    150 #include <bcm_int/esw/subport.h>
    151 #endif /* BCM_HGPROXY_COE_SUPPORT */
    152 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
    153 #include <bcm_int/esw/tomahawk2.h>
    154 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
    155 #if defined(BCM_TOMAHAWK2_SUPPORT)
    156 #include <bcm_int/esw/xgs5.h>
    157 #include <soc/tomahawk2.h>
    158 #endif /* BCM_TOMAHAWK2_SUPPORT */
    159 #include <bcm_int/esw/xgs3.h>
    160 
    161 #include <bcm_int/esw/flex_ctr.h>
    162 #include <bcm_int/esw/policer.h>
    163 #if defined(BCM_KATANA2_SUPPORT)
    164 #include <bcm_int/esw/subport.h>
    165 #include <bcm_int/esw/katana2.h>
    166 #include <soc/katana2.h>
    167 #include <bcm/subport.h>
    168 #endif /* BCM_KATANA2_SUPPORT */
    169 #if defined(BCM_SABER2_SUPPORT)
    170 #include <bcm_int/esw/saber2.h>
    171 #include <soc/saber2.h>
    172 #endif /* BCM_SABER2_SUPPORT */
    173 #if defined(BCM_METROLITE_SUPPORT)
    174 #include <bcm_int/esw/metrolite.h>
    175 #include <soc/metrolite.h>
    176 #endif /* BCM_METROLITE_SUPPORT */
    177 #if defined(BCM_GREYHOUND_SUPPORT)
    178 #include <bcm_int/esw/greyhound.h>
    179 #endif /* BCM_GREYHOUND_SUPPORT */
    180 #if defined(BCM_HURRICANE3_SUPPORT)
    181 #include <bcm_int/esw/hurricane3.h>
    182 #include <soc/hurricane3.h>
    183 #endif /* BCM_HURRICANE3_SUPPORT */
    184 #if defined(BCM_GREYHOUND2_SUPPORT)
    185 #include <bcm_int/esw/greyhound2.h>
    186 #endif /* BCM_GREYHOUND2_SUPPORT */
    187 #if defined (BCM_EP_REDIRECT_VERSION_2)
    188 #include <bcm_int/esw/xgs5.h>
    189 #endif
    190 #if defined(BCM_HGPROXY_COE_SUPPORT)
    191 #include <bcm_int/esw/subport.h>
    192 #include <bcm_int/esw/xgs5.h>
    193 #endif /* BCM_HGPROXY_COE_SUPPORT */
    194 #if defined(BCM_PREEMPTION_SUPPORT)
    195 #include <bcm_int/esw/preemption.h>
    196 #include <bcm_int/esw/preemption_cnt.h>
    197 #endif /* BCM_PREEMPTION_SUPPORT */
    198 #include <bcm_int/esw_dispatch.h>
    199 
    200 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT)
    201 #include <bcm_int/esw/switch.h>
    202 #endif /* BCM_WARM_BOOT_SUPPORT */
    203 
    204 #if defined(BCM_TRIUMPH2_SUPPORT)
    205 #include <bcm_int/esw/qos.h>
    206 #endif /* BCM_TRIUMPH2_SUPPORT */
    207 
    208 #ifdef PORTMOD_SUPPORT
    209 #include <soc/portmod/portmod.h>
    210 #endif /* PORTMOD_SUPPORT */
    211 
    212 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
    213 #include <bcm_int/esw/xgs5.h>
    214 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
    215 
    216 #ifdef INCLUDE_FCMAP
    217 #include <../../phyident.h>
    218 #endif
    219 
    220 #define BCMI_GPORT_TYPE_VALID(port)         \
    221         (BCM_GPORT_IS_VLAN_PORT(port) ||     \
    222          BCM_GPORT_IS_NIV_PORT(port) ||      \
    223          BCM_GPORT_IS_EXTENDER_PORT(port) || \
    224          BCM_GPORT_IS_SUBPORT_PORT(port) ||  \
    225          BCM_GPORT_IS_VXLAN_PORT(port) ||  \
    226          BCM_GPORT_IS_L2GRE_PORT(port) ||  \
    227          BCM_GPORT_IS_MIM_PORT(port) || \
    228          BCM_GPORT_IS_MPLS_PORT(port) || \
    229          BCM_GPORT_IS_FLOW_PORT(port) || \
    230          BCM_GPORT_IS_TRUNK(port))
    231 
    232 
    233 #if defined (BCM_EP_REDIRECT_VERSION_2)
    234 #define BCMI_EP_REDIRECT_PORT (74)
    235 #endif
    236 
    237 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP 64
    238 #define _BCM_I2E_CLASS_ID_MAX   0x1ff
    239 
    240 /*
    241  * Define the macro for measuring the benchmark of speed change.
    242  */
    243 #define BCM_PORT_SPEED_CHANGE_BENCHMARK
    244 
    245 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    246 #define MODULE_ID_LOWER_6_BITS(a) ((a) = ((a) & 0x3f))
    247 #endif
    248 
    249 /*
    250  * Port Function Vector Driver
    251  */
    252 bcm_esw_port_drv_t    *bcm_esw_port_drv[BCM_MAX_NUM_UNITS] = {0};
    253 
    254 /*
    255  * Variable:
    256  *      bcm_port_info
    257  * Purpose:
    258  *      One entry for each SOC device containing port information
    259  *      for that device.  Use the PORT macro to access it.
    260  */
    261 static _bcm_port_info_t     *bcm_port_info[BCM_MAX_NUM_UNITS];
    262 
    263 STATIC _bcm_port_force_forward_linkstate_t p_linkstate[BCM_MAX_NUM_UNITS];
    264 
    265 #define PORT(unit, port)        bcm_port_info[unit][port]
    266 
    267 extern int inside_bcm_shutdown[BCM_MAX_NUM_UNITS];
    268 
    269 #if defined(BCM_XMAC_SUPPORT)
    270 extern int _mac_x_reinit(int unit, soc_port_t port);
    271 #endif
    272 
    273 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    274 extern src_modid_base_index_bookkeeping_t *src_modid_base_index_bk[BCM_MAX_NUM_UNITS];
    275 #endif
    276 
    277 #if defined(BCM_TRIDENT3_SUPPORT)
    278 extern int
    279 _bcm_fb2_egr_vlan_control_field_get(int unit, bcm_port_t port,
    280 soc_field_t field, uint32 *value);
    281 extern int
    282 _bcm_fb2_port_tpid_enable_set(int unit, bcm_port_t port, uint32 tpid_enable);
    283 extern int
    284 _bcm_fb2_port_tpid_enable_get(int unit, bcm_port_t port, uint32 *tpid_enable);
    285 #endif
    286 
    287 /* Accessor to bcm_port_info used by other modules */
    288 void _bcm_port_info_access(int unit, bcm_port_t port, _bcm_port_info_t **info)
    289 {
    290     (bcm_port_info[unit] != NULL) ? (*info = &PORT(unit, port)):(*info = NULL);
    291     return;
    292 }
    293 
    294 /* Return On error with port mutex unlocked */
    295 #define _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(op)  \
    296     do {                                        \
    297         int __rv__;                             \
    298         if (((__rv__ = (op)) < 0)) {            \
    299             PORT_UNLOCK(unit);                  \
    300             _SHR_ERROR_TRACE(__rv__);           \
    301             return(__rv__);                     \
    302         }                                       \
    303     } while(0)
    304 
    305 int
    306 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port,
    307                                   bcm_port_t *local_port, int *phyn,
    308                                   int *phy_lane, int *sys_side);
    309 
    310 #if defined(BCM_KATANA2_SUPPORT)
    311    int _bcm_kt2_update_port_mode(int unit, uint8 port, int speed);
    312    int _bcm_kt2_cosq_dynamic_port_encap_change(int unit, bcm_port_t port);
    313 #endif
    314 
    315 #if defined(BCM_METROLITE_SUPPORT)
    316 int _bcm_ml_update_port_mode(int unit, uint8 port, int speed);
    317 #endif
    318 #if defined(BCM_SABER2_SUPPORT)
    319 int _bcm_sb2_update_port_mode(int unit, uint8 port, int speed);
    320 #ifdef BCM_WARM_BOOT_SUPPORT
    321 int bcm_sb2_wb_v2_flexio_update = 0;
    322 #endif
    323 #endif
    324 #if defined(BCM_TRIUMPH3_SUPPORT)
    325 STATIC int
    326 _bcm_port_force_forward_add(int unit, bcm_port_t local_port,
    327                                     bcm_port_t egr_port);
    328 
    329 STATIC int
    330 _bcm_port_force_forward_init(int unit);
    331 
    332 STATIC int
    333 _bcm_port_force_forward_deinit(int unit);
    334 
    335 #ifdef BCM_WARM_BOOT_SUPPORT
    336 STATIC int
    337 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr);
    338 
    339 STATIC int
    340 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr);
    341 
    342 STATIC int
    343 _bcm_port_force_forward_scache_size(int unit, int *size);
    344 #endif /* BCM_WARM_BOOT_SUPPORT */
    345 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
    346 
    347 /*
    348  * Define:
    349  *      PORT_INIT
    350  * Purpose:
    351  *      Causes a routine to return BCM_E_INIT if port is not yet initialized.
    352  */
    353 
    354 #define PORT_INIT(unit) \
    355         if (bcm_port_info[unit] == NULL) { return BCM_E_INIT; }
    356 
    357 /*
    358  * Define:
    359  *      PORT_PARAM_CHECK
    360  * Purpose:
    361  *      Check unit and port parameters for most bcm_port api calls
    362  */
    363 #define PORT_PARAM_CHECK(unit, port) do { \
    364         PORT_INIT(unit); \
    365         if (!SOC_PORT_VALID(unit, port)) { return BCM_E_PORT; } \
    366         } while (0);
    367 
    368 /*
    369  * Define:
    370  *      PORT_SWITCHED_CHECK
    371  * Purpose:
    372  *      Check unit and port for switching feature support
    373  */
    374 #define PORT_SWITCHED_CHECK(unit, port) do { \
    375         if (IS_ST_PORT(unit, port)) { \
    376             return BCM_E_PORT; \
    377         } else { \
    378             if (IS_CPU_PORT(unit, port)) { \
    379                 if (!soc_feature(unit, soc_feature_cpuport_switched)) { \
    380                     return BCM_E_PORT; \
    381                 } \
    382             } \
    383         } \
    384         } while (0);
    385 
    386 
    387 /*
    388  * Define:
    389  *      PORT_INFO_RX_LOS_SET
    390  * Purpose:
    391  *      Records the SW RX LOS configuration used for warmboot recovery
    392  */
    393 #define PORT_INFO_RX_LOS_SET(_u, _p, _type, _val) do {                  \
    394         if (_type == BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS) {            \
    395             PORT(_u, _p).rx_los = _val;                                 \
    396         }                                                               \
    397     } while (0);
    398 
    399 
    400 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) \
    401     || defined(BCM_TRIUMPH3_SUPPORT)
    402  #define BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ 64
    403 #endif
    404 #ifdef BCM_TRIUMPH2_SUPPORT
    405 typedef int _port_src_mod_egr_prof_ptr_t;
    406 STATIC _port_src_mod_egr_prof_ptr_t
    407     port_src_mod_egr_prof_ptr[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS];
    408 #define PORT_SRC_MOD_EGR_PROF_PTR(_u, _p) port_src_mod_egr_prof_ptr[_u][_p]
    409 
    410 STATIC soc_profile_mem_t *_bcm_src_mod_egr_profile[BCM_MAX_NUM_UNITS];
    411 #define PORT_SRC_MOD_EGR_PROFILE(_u) _bcm_src_mod_egr_profile[_u]
    412 
    413 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    414 STATIC
    415 bcm_error_t _bcm_esw_port_stat_get_table_info(
    416                    int                        unit,
    417                    bcm_gport_t                port,
    418                    uint32                     *num_of_tables,
    419                    bcm_stat_flex_table_info_t *table_info);
    420 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT */
    421 #endif /* BCM_TRIUMPH2_SUPPORT */
    422 
    423 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\
    424 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
    425 /* EEE standard compliance Work Around:
    426  * To Maintain software state of native eee in MAC*/
    427 STATIC int eee_cfg[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS];
    428 #endif
    429 
    430 #ifdef BCM_TRIUMPH3_SUPPORT
    431 STATIC int _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value);
    432 STATIC int _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value);
    433 #endif /* BCM_TRIUMPH3_SUPPORT */
    434 
    435 /*
    436  * The Port Monitor Thread is intended for handling work-arounds
    437  * that are unneeded in most cases. In order to avoid unnecessary
    438  * processing overhead the thread is not started by default, but
    439  * only if so requested through configuration parameters.
    440  */
    441 
    442 typedef struct _port_mon_ctrl_s
    443 {
    444     char taskname[16];
    445     sal_sem_t sema;
    446     int interval;
    447     int running;
    448     int stop;
    449     int unit;
    450     uint32 gtuc;
    451     uint32 gtmca;
    452     uint32 gtbca;
    453     uint32 gtlcl;
    454     uint32 gtpok;
    455 } _port_mon_ctrl_t;
    456 
    457 STATIC _port_mon_ctrl_t _bcm_esw_port_mon_ctrl[BCM_MAX_NUM_UNITS];
    458 
    459 #define PORT_MON_CTRL(_u) (&_bcm_esw_port_mon_ctrl[_u])
    460 
    461 #define PORT_MON_INTERVAL_MIN   100000
    462 
    463 int
    464 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay);
    465 
    466 #if defined(BCM_TRIDENT3_SUPPORT)
    467 STATIC int
    468 _bcm_esw_td3_asf_init(int unit, soc_td3_asf_mode_e asf_mode);
    469 STATIC int
    470 _bcm_esw_td3_port_asf_mode_set(int unit, bcm_port_t port, int mode);
    471 #endif
    472 
    473 #if defined(BCM_MAVERICK2_SUPPORT)
    474 STATIC int
    475 _bcm_esw_mv2_asf_init(int unit, soc_mv2_asf_mode_e asf_mode);
    476 STATIC int
    477 _bcm_esw_mv2_port_asf_mode_set(int unit, bcm_port_t port, int mode);
    478 #endif
    479 
    480 #if defined(BCM_TOMAHAWK_SUPPORT)
    481 STATIC int
    482 _bcm_esw_asf_init(int unit, soc_th_asf_mode_e asf_mode);
    483 
    484 STATIC int
    485 _bcm_esw_asf_deinit(int unit);
    486 
    487 #ifdef BCM_WARM_BOOT_SUPPORT
    488 STATIC int
    489 _bcm_esw_asf_wb_memsz_get(int unit, uint32* const mem_sz, uint16 scache_ver);
    490 
    491 STATIC int
    492 _bcm_esw_asf_wb_sync(int unit, uint8* wb_data);
    493 
    494 STATIC int
    495 _bcm_esw_asf_wb_recover(int unit, uint8* const wb_data, uint16 scache_ver);
    496 
    497 STATIC int
    498 _bcm_esw_sflow_wb_recover(int unit);
    499 
    500 STATIC int
    501 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem);
    502 #endif /* BCM_WARM_BOOT_SUPPORT */
    503 #endif /* BCM_TOMAHAWK_SUPPORT */
    504 
    505 #ifdef BCM_WARM_BOOT_SUPPORT
    506 
    507 /* Enum mapped to string for scache printing.
    508  * Usage format is SPT_<enum> */
    509 #define SCACHE_PORT_DEFS                                            \
    510     SCACHE_PORT_DEF(PBVL, "pbvl")                                   \
    511     SCACHE_PORT_DEF(VLAN_PROT_PTR, "vlan_prot_ptr")                 \
    512     SCACHE_PORT_DEF(VP_COUNT, "vp_count")                           \
    513     SCACHE_PORT_DEF(DTM_PBMP, "dtm_pbmp")                           \
    514     SCACHE_PORT_DEF(COSMASK, "cosmask")                             \
    515     SCACHE_PORT_DEF(METERING_INFO, "metering_info")                 \
    516     SCACHE_PORT_DEF(PORT_FLAGS, "port_flags")                       \
    517     SCACHE_PORT_DEF(PORT_NUM_LANES, "port_num_lanes")               \
    518     SCACHE_PORT_DEF(RX_LOS, "rx_los")                               \
    519     SCACHE_PORT_DEF(PORT_ENABLE, "port_enable")                     \
    520     SCACHE_PORT_DEF(ASF, "asf")                                     \
    521     SCACHE_PORT_DEF(LATENCY, "latency")                             \
    522     SCACHE_PORT_DEF(IFG, "ifg")                                     \
    523     SCACHE_PORT_DEF(DSCP_MAP, "dscp_map")                           \
    524     SCACHE_PORT_DEF(PORT_INTF_TYPE, "port_intf_type")
    525 
    526 typedef enum scache_port_type_e {
    527 #define SCACHE_PORT_DEF(_e, _s) SPT_##_e,
    528     SCACHE_PORT_DEFS
    529 #undef SCACHE_PORT_DEF
    530     SCACHE_PORT_TYPE_MAX
    531 } scache_port_type_t;
    532 
    533 static const char *port_scache_strs[] = {
    534 #define SCACHE_PORT_DEF(_e, _s) _s,
    535     SCACHE_PORT_DEFS
    536 #undef SCACHE_PORT_DEF
    537     "invalid"
    538 };
    539 
    540 typedef struct scache_port_print_port_s {
    541     struct scache_port_print_port_s *next; /* pointer to next */
    542     uint8 *val;                     /* pointer to value in scache */
    543     int len;                        /* len of value in scache */
    544     int port;                       /* logical port number */
    545 } scache_port_print_port_t;
    546 
    547 /* pointers to head of linked list */
    548 static scache_port_print_port_t *scache_head[SCACHE_PORT_TYPE_MAX];
    549 /* pointers to tail of linked list */
    550 static scache_port_print_port_t *scache_tail[SCACHE_PORT_TYPE_MAX];
    551 
    552 STATIC int
    553 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr);
    554 
    555 STATIC int
    556 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr);
    557 #endif
    558 
    559 STATIC int
    560 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed);
    561 STATIC int
    562 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode);
    563 
    564 
    565 #if defined(BCM_GREYHOUND_SUPPORT)
    566 /* Treat Packet Priority as dot1p ref_cnt structure */
    567 typedef struct bcmi_esw_treat_pktpri_as_dot1p_s {
    568     sal_mutex_t ref_cnt_mutex;
    569     int ref_cnt;
    570 } bcmi_esw_treat_pktpri_as_dot1p_t;
    571 
    572 STATIC bcmi_esw_treat_pktpri_as_dot1p_t
    573     bcmi_treat_pktpri_as_dot1p[BCM_MAX_NUM_UNITS];
    574 
    575 /* Treat Packet Priority as dot1p ref_cnt lock/unlock */
    576 #define TREAT_PKTPRI_AS_DOT1P_LOCK(_unit_)                           \
    577     sal_mutex_take(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex, \
    578                    sal_mutex_FOREVER)
    579 #define TREAT_PKTPRI_AS_DOT1P_UNLOCK(_unit_)                         \
    580     sal_mutex_give(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex)
    581 
    582 /*
    583  * Function:
    584  *    bcmi_esw_port_treat_pktpri_as_dot1p_cleanup
    585  * Purpose:
    586  *    cleanup resource after detach
    587  * Parameters:
    588  *    unit - (IN) Device Number
    589  * Return Value:
    590  *    BCM_E_XXX
    591  * Notes:
    592  */
    593 STATIC int
    594 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(int unit)
    595 {
    596     if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex != NULL) {
    597         sal_mutex_destroy(bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex);
    598         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = NULL;
    599     }
    600 
    601     return BCM_E_NONE;
    602 }
    603 
    604 /*
    605  * Function:
    606  *    bcmi_esw_port_treat_pktpri_as_dot1p_init
    607  * Purpose:
    608  *    Initialize the ref_cnt of enabling treat packet priority
    609  *    as dot1p priority for different packet types or port controls.
    610  * Parameters:
    611  *    unit - (IN) Device Number
    612  * Return Value:
    613  *    BCM_E_XXX
    614  * Notes:
    615  *    The ref_cnt of treat packet priority as dot1p priority is system-wise.
    616  */
    617 STATIC int
    618 bcmi_esw_port_treat_pktpri_as_dot1p_init(int unit)
    619 {
    620     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    621         return BCM_E_UNAVAIL;
    622     }
    623 
    624     /* Create protection mutex. */
    625     if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) {
    626         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex =
    627             sal_mutex_create("treat_pktpri_as_dot1p.lock");
    628         if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) {
    629             return BCM_E_RESOURCE;
    630         }
    631     }
    632 
    633     bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0;
    634 
    635     return BCM_E_NONE;
    636 }
    637 
    638 /*
    639  * Function:
    640  *    bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    641  * Purpose:
    642  *    Update the ref_cnt of enabling treat packet priority
    643  *    as dot1p priority for various packet types or port controls.
    644  * Parameters:
    645  *    unit - (IN) Device Number
    646  *    incr_decr_flag - (IN) If TRUE, increment ref_cnt, else decrease ref_cnt
    647  * Return Value:
    648  *    BCM_E_XXX
    649  * Notes:
    650  *    The ref_cnt of treat packet priority as dot1p priority is system-wise.
    651  */
    652 STATIC int
    653 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update(
    654     int unit, int incr_decr_flag)
    655 {
    656     int rv = BCM_E_NONE;
    657     uint64 regval64;
    658 
    659     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    660         return BCM_E_UNAVAIL;
    661     }
    662 
    663     /* Input parameter check */
    664     if ((incr_decr_flag != 1) && (incr_decr_flag != -1)) {
    665         return BCM_E_PARAM;
    666     }
    667 
    668     TREAT_PKTPRI_AS_DOT1P_LOCK(unit);
    669     if (incr_decr_flag == 1) {
    670         /* Increment */
    671         /* Need to set TREAT_PKTPRI_AS_DOT1Pf for the first ref_cnt */
    672         if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) {
    673             COMPILER_64_ZERO(regval64);
    674             rv = READ_ING_CONFIG_64r(unit, &regval64);
    675             if (BCM_FAILURE(rv)) {
    676                 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    677                 return rv;
    678             }
    679             soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
    680                                   TREAT_PKTPRI_AS_DOT1Pf, 1);
    681             rv = WRITE_ING_CONFIG_64r(unit, regval64);
    682             if (BCM_FAILURE(rv)) {
    683                 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    684                 return rv;
    685             }
    686         }
    687         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt++;
    688     } else {
    689         /* Decrement */
    690         if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt >= 1) {
    691             bcmi_treat_pktpri_as_dot1p[unit].ref_cnt--;
    692             /* Need to unset TREAT_PKTPRI_AS_DOT1Pf when ref_cnt = 0 */
    693             if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) {
    694                 COMPILER_64_ZERO(regval64);
    695                 rv = READ_ING_CONFIG_64r(unit, &regval64);
    696                 if (BCM_FAILURE(rv)) {
    697                     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    698                     return rv;
    699                 }
    700                 soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
    701                                       TREAT_PKTPRI_AS_DOT1Pf, 0);
    702                 rv = WRITE_ING_CONFIG_64r(unit, regval64);
    703                 if (BCM_FAILURE(rv)) {
    704                     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    705                     return rv;
    706                 }
    707             }
    708         }
    709     }
    710     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    711 
    712     return rv;
    713 }
    714 
    715 #ifdef BCM_WARM_BOOT_SUPPORT
    716 /*
    717  * Function:
    718  *    bcmi_esw_port_treat_pktpri_as_dot1p_reinit
    719  * Purpose:
    720  *    Recovery the ref_cnt of enabling treat packet priority
    721  *    as dot1p priority for different packet types or port contols.
    722  * Parameters:
    723  *    unit - (IN) Device Number
    724  * Return Value:
    725  *    BCM_E_XXX
    726  */
    727 STATIC int
    728 bcmi_esw_port_treat_pktpri_as_dot1p_reinit(int unit)
    729 {
    730     int rv = BCM_E_NONE;
    731     bcm_port_t port_idx;
    732     int pri_en = 0;
    733     uint64 regval64;
    734 
    735     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    736         return BCM_E_UNAVAIL;
    737     }
    738 
    739     bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0;
    740 
    741     COMPILER_64_ZERO(regval64);
    742     BCM_IF_ERROR_RETURN(
    743         READ_ING_CONFIG_64r(unit, &regval64));
    744     if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
    745                               TREAT_PKTPRI_AS_DOT1Pf) == 0x1) {
    746         BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port_idx) {
    747             /* Recover ref_cnt for Egress VLAN internal priority mapping */
    748             rv = bcm_esw_port_control_get
    749                      (unit, port_idx,
    750                       bcmPortControlEgressVlanPriUsesPktPri, &pri_en);
    751             if (BCM_FAILURE(rv)) {
    752                 return rv;
    753             }
    754             if (pri_en) {
    755                 BCM_IF_ERROR_RETURN(
    756                     bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    757                         (unit, 1));
    758             }
    759 
    760             /* Recover ref_cnt for ETAG internal priority mapping */
    761             if (soc_feature(unit, soc_feature_port_extension)) {
    762                 rv = bcm_esw_port_control_get(unit, port_idx,
    763                                               bcmPortControlUseEtagPri, &pri_en);
    764                 if (BCM_FAILURE(rv)) {
    765                     return rv;
    766                 }
    767                 if (pri_en) {
    768                     BCM_IF_ERROR_RETURN(
    769                         bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    770                             (unit, 1));
    771                 }
    772             }
    773 #ifdef BCM_HURRICANE3_SUPPORT
    774             /* Recover ref_cnt for MiML internal priority mapping */
    775             if (soc_feature(unit, soc_feature_miml)) {
    776                 rv = bcm_esw_port_control_get(unit, port_idx,
    777                                               bcmPortControlTrustMimlPri, &pri_en);
    778                 if (BCM_FAILURE(rv)) {
    779                     return rv;
    780                 }
    781                 if (pri_en) {
    782                     BCM_IF_ERROR_RETURN(
    783                         bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    784                             (unit, 1));
    785                 }
    786             }
    787 #endif /* BCM_HURRICANE3_SUPPORT */
    788         }
    789     }
    790 
    791     return rv;
    792 }
    793 #endif /* BCM_WARM_BOOT_SUPPORT */
    794 #endif /* BCM_GREYHOUND_SUPPORT */
    795 
    796 /*
    797  * Function:
    798  *      _bcm_esw_port_mon_unimac_lock_up
    799  * Description:
    800  *      Check for UniMAC half duplex collision lock-up issue
    801  * Parameters:
    802  *      pmc  - (IN) port monitor control data
    803  * Return Value:
    804  *      None
    805  * Notes:
    806  *      See errata 56020-ES105-R for additional details.
    807  */
    808 STATIC void
    809 _bcm_esw_port_mon_unimac_lock_up(_port_mon_ctrl_t *pmc)
    810 {
    811     int unit = pmc->unit;
    812     int port, rv, link_up, fulld, lock_up;
    813     uint32 gtuc, gtmca, gtbca, gtlcl, gtpok;
    814     uint32 ccnt, rcnt, txfifo;
    815 
    816     if (!soc_feature(unit, soc_feature_unimac)) {
    817         return;
    818     }
    819 
    820     PBMP_E_ITER(unit, port) {
    821         /* Check only half duplex ports */
    822         rv = _bcm_esw_link_get(unit, port, &link_up);
    823         if (BCM_FAILURE(rv) || !link_up) {
    824             continue;
    825         }
    826         rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &fulld);
    827         if (BCM_FAILURE(rv) || fulld) {
    828             continue;
    829         }
    830 
    831         lock_up = 0;
    832         rv = 0;
    833 
    834         /* Collect test counters */
    835         rv += soc_counter_get32(unit, port, GTUCr, 0, &gtuc);
    836         rv += soc_counter_get32(unit, port, GTMCAr, 0, &gtmca);
    837         rv += soc_counter_get32(unit, port, GTBCAr, 0, &gtbca);
    838         rv += soc_counter_get32(unit, port, GTLCLr, 0, &gtlcl);
    839         rv += soc_counter_get32(unit, port, GTPOKr, 0, &gtpok);
    840 
    841         /* Test lock-up conditions */
    842         if (gtuc == pmc->gtuc &&
    843             gtmca == pmc->gtmca &&
    844             gtbca == pmc->gtbca) {
    845             if (gtlcl != pmc->gtlcl &&
    846                 gtpok != pmc->gtpok) {
    847                 lock_up = 2;
    848             } else {
    849                 rcnt = ccnt = 0;
    850                 if (SOC_REG_IS_VALID(unit, GE0_GBODE_CELL_CNTr)) {
    851                     uint32 reg, addr, idx;
    852                     idx = (port < 6) ? (port - 1) : ((port - 6) % 12);
    853                     reg = GE0_GBODE_CELL_CNTr;
    854                     addr = soc_reg_addr(unit, reg, port, 0);
    855                     addr += idx;
    856                     rv += soc_reg32_read(unit, addr, &ccnt);
    857                     reg = GE0_GBODE_CELL_REQ_CNTr;
    858                     addr = soc_reg_addr(unit, reg, port, 0);
    859                     addr += idx;
    860                     rv += soc_reg32_read(unit, addr, &rcnt);
    861                 } else if (SOC_REG_IS_VALID(unit, GE_GBODE_CELL_CNTr)) {
    862                     rv += READ_GE_GBODE_CELL_CNTr(unit, port, &ccnt);
    863                     rv += READ_GE_GBODE_CELL_REQ_CNTr(unit, port, &rcnt);
    864                 }
    865                 if (gtlcl && rcnt == 0 && ccnt == 4) {
    866                     lock_up = 1;
    867                 }
    868             }
    869         }
    870         if (lock_up == 0) {
    871             rv += READ_TXFIFO_STATr(unit, port, &txfifo);
    872             if (soc_reg_field_get(unit, TXFIFO_STATr,
    873                                   txfifo, TXFIFO_UNDERRUNf)) {
    874                 lock_up = 2;
    875             }
    876         }
    877 
    878         /* Reset MAC if lock-up is detected */
    879         if (rv == 0 && lock_up) {
    880             LOG_VERBOSE(BSL_LS_BCM_PORT,
    881                         (BSL_META_U(unit,
    882                                     "Port %s: UniMAC lock up (%d) detected\n"),
    883                          SOC_PORT_NAME(unit, port), lock_up));
    884             PORT_LOCK(unit);
    885             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
    886                             SOC_MAC_CONTROL_SW_RESET, TRUE);
    887             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
    888                             SOC_MAC_CONTROL_SW_RESET, FALSE);
    889             PORT_UNLOCK(unit);
    890         }
    891 
    892         /* Sync test counters */
    893         pmc->gtuc = gtuc;
    894         pmc->gtmca = gtmca;
    895         pmc->gtbca = gtbca;
    896         pmc->gtlcl = gtlcl;
    897         pmc->gtpok = gtpok;
    898     }
    899 }
    900 
    901 /*
    902  * Function:
    903  *      _bcm_esw_port_mon_ctrl_thread
    904  * Description:
    905  *      Port monitor thread
    906  * Parameters:
    907  *      context  - (IN) Port monitor control data
    908  * Return Value:
    909  *      None
    910  */
    911 STATIC void
    912 _bcm_esw_port_mon_ctrl_thread(void *context)
    913 {
    914     _port_mon_ctrl_t *pmc = (_port_mon_ctrl_t *)context;
    915 
    916     LOG_VERBOSE(BSL_LS_BCM_PORT,
    917                 (BSL_META("Port monitor started on unit %d\n"), pmc->unit));
    918 
    919     pmc->running = 1;
    920     while (!pmc->stop) {
    921         _bcm_esw_port_mon_unimac_lock_up(pmc);
    922         (void)sal_sem_take(pmc->sema, pmc->interval);
    923     }
    924     pmc->running = 0;
    925 }
    926 
    927 /*
    928  * Function:
    929  *      _bcm_esw_port_mon_start
    930  * Description:
    931  *      Start port monitor thread
    932  * Parameters:
    933  *      unit  - (IN) BCM device number
    934  * Return Value:
    935  *      BCM_E_NONE if thread started successfully
    936  */
    937 int
    938 _bcm_esw_port_mon_start(int unit)
    939 {
    940     _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit);
    941     int cnt;
    942 
    943     pmc->interval = soc_property_get(unit, spn_PORTMON_INTERVAL, 0);
    944     if (pmc->interval == 0) {
    945         return BCM_E_NONE;
    946     }
    947 
    948     if (pmc->interval < PORT_MON_INTERVAL_MIN) {
    949         pmc->interval = PORT_MON_INTERVAL_MIN;
    950     }
    951 
    952     pmc->unit = unit;
    953     if (pmc->running) {
    954         LOG_VERBOSE(BSL_LS_BCM_PORT,
    955                     (BSL_META_U(unit,
    956                                 "Port monitor already running on unit %d\n"),
    957                      pmc->unit));
    958     } else {
    959         if (pmc->sema == NULL) {
    960             pmc->sema = sal_sem_create("port_mon_SLEEP", sal_sem_BINARY, 0);
    961             if (pmc->sema == NULL) {
    962                 return BCM_E_MEMORY;
    963             }
    964         }
    965         sal_snprintf(pmc->taskname, sizeof (pmc->taskname),
    966                      "bcmPortMon.%d", unit);
    967         pmc->stop = 0;
    968         if (sal_thread_create(pmc->taskname, SAL_THREAD_STKSZ,
    969                               soc_property_get(unit,
    970                                                spn_PORTMON_THREAD_PRI,
    971                                                50),
    972                               _bcm_esw_port_mon_ctrl_thread,
    973                               pmc) == SAL_THREAD_ERROR) {
    974             return BCM_E_MEMORY;
    975         }
    976         cnt = 10;
    977         while (!pmc->running && cnt--) {
    978             sal_usleep(100000);
    979         }
    980         if (!pmc->running) {
    981             LOG_ERROR(BSL_LS_BCM_PORT,
    982                       (BSL_META_U(unit,
    983                                   "%s: Thread did not start\n"), pmc->taskname));
    984             return BCM_E_TIMEOUT;
    985         }
    986     }
    987     return BCM_E_NONE;
    988 }
    989 
    990 /*
    991  * Function:
    992  *      _bcm_esw_port_mon_stop
    993  * Description:
    994  *      Stop port monitor thread
    995  * Parameters:
    996  *      unit  - (IN) BCM device number
    997  * Return Value:
    998  *      BCM_E_NONE if thread stopped successfully
    999  */
   1000 int
   1001 _bcm_esw_port_mon_stop(int unit)
   1002 {
   1003     int cnt;
   1004     _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit);
   1005 
   1006     if (pmc->sema == NULL) {
   1007         return BCM_E_NONE;
   1008     }
   1009 
   1010     pmc->stop = 1;
   1011     sal_sem_give(pmc->sema);
   1012     cnt = 10;
   1013     while (pmc->running && cnt--) {
   1014         sal_usleep(100000);
   1015     }
   1016     if (pmc->running) {
   1017         LOG_ERROR(BSL_LS_BCM_PORT,
   1018                   (BSL_META_U(unit,
   1019                               "%s: Thread did not start\n"), pmc->taskname));
   1020         return BCM_E_TIMEOUT;
   1021     }
   1022     sal_sem_destroy(pmc->sema);
   1023     pmc->sema = NULL;
   1024 
   1025     return BCM_E_NONE;
   1026 }
   1027 
   1028 #ifdef BCM_TRIUMPH3_SUPPORT
   1029 static _port_ibod_ctrl_t *_port_ibod_ctrl[BCM_MAX_NUM_UNITS];
   1030 static int txerr_trigger_flag[SOC_MAX_NUM_PORTS];
   1031 
   1032 #define IBOD_RECOVERY_GROUP_MAX  ((SOC_MAX_NUM_PORTS + 3) /4)
   1033 #define IBOD_RECOVERY_GROUP_VALID(grp) ((grp) >= 0 && (grp) < IBOD_RECOVERY_GROUP_MAX)
   1034 #define IBOD_RECOVERY_GROUP(phy_port) ((phy_port - 1)/4)
   1035 static sal_mutex_t ibod_port_group_recovery_lock[BCM_MAX_NUM_UNITS][IBOD_RECOVERY_GROUP_MAX];
   1036 
   1037 #define TR3_IARB_TDM_TABLE_LENGTH      512
   1038 
   1039 #define IBOD_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \
   1040         if (SOC_FAILURE(rv)) {   \
   1041             soc_ibod_recovery_in_progress_set(unit, 0); \
   1042             _bcm_esw_ibod_recovery_port_unlock(unit, port); \
   1043             PORT_UNLOCK(unit);       \
   1044             return rv;               \
   1045         }
   1046 
   1047 #define TXERR_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \
   1048         if (SOC_FAILURE(rv)) {   \
   1049             _bcm_esw_ibod_recovery_port_unlock(unit, port); \
   1050             PORT_UNLOCK(unit);       \
   1051             _bcm_esw_lc_unlock(unit);\
   1052             return rv;               \
   1053         }
   1054 
   1055 /*#define IBOD_DEBUG
   1056 #define TXERR_DEBUG */
   1057 
   1058 int _ibod_debug_flag = 0;
   1059 
   1060 void _bcm_esw_ibod_debug_flag_set(int unit, int flag)
   1061 {
   1062     _ibod_debug_flag = flag;
   1063     cli_out("IBOD debug flag:0X%x\n", _ibod_debug_flag);
   1064 }
   1065 
   1066 static int _bcm_esw_ibod_recovery_lock_init(int unit)
   1067 {
   1068     int rv = BCM_E_NONE;
   1069     int group, rollback_group;
   1070 
   1071     for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) {
   1072         ibod_port_group_recovery_lock[unit][group] = sal_mutex_create("IBOD_GROUP_LOCK");
   1073         if (ibod_port_group_recovery_lock[unit][group] == NULL) {
   1074             rv = BCM_E_MEMORY;
   1075             break;
   1076         }
   1077     }
   1078     /* Recycle the memory */
   1079     if (SOC_FAILURE(rv)) {
   1080         for (rollback_group = group - 1; rollback_group >= 0; rollback_group--) {
   1081             sal_mutex_destroy(ibod_port_group_recovery_lock[unit][rollback_group]);
   1082         }
   1083     }
   1084     return BCM_E_NONE;
   1085 }
   1086 
   1087 static void _bcm_esw_ibod_recovery_lock_deinit(int unit)
   1088 {
   1089     int group;
   1090 
   1091     for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) {
   1092         if (ibod_port_group_recovery_lock[unit][group] != NULL) {
   1093             sal_mutex_destroy(ibod_port_group_recovery_lock[unit][group]);
   1094         }
   1095     }
   1096 }
   1097 
   1098 void _bcm_esw_ibod_recovery_port_lock(int unit, bcm_port_t port)
   1099 {
   1100     int phy_port;
   1101     int group;
   1102     /* coverity[overrun-local : FALSE] */
   1103     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1104     group = IBOD_RECOVERY_GROUP(phy_port);
   1105     if (IBOD_RECOVERY_GROUP_VALID(group) &&
   1106         ibod_port_group_recovery_lock[unit][group] != NULL) {
   1107         sal_mutex_take(ibod_port_group_recovery_lock[unit][group], sal_mutex_FOREVER);
   1108     }
   1109 }
   1110 
   1111 void _bcm_esw_ibod_recovery_port_unlock(int unit, bcm_port_t port)
   1112 {
   1113     int phy_port;
   1114     int group;
   1115 
   1116     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1117     group = IBOD_RECOVERY_GROUP(phy_port);
   1118     if (IBOD_RECOVERY_GROUP_VALID(group) &&
   1119         ibod_port_group_recovery_lock[unit][group] != NULL) {
   1120         sal_mutex_give(ibod_port_group_recovery_lock[unit][group]);
   1121     }
   1122 }
   1123 
   1124 STATIC int _bcm_tr3_port_is_control_port(int unit, soc_port_t port)
   1125 {
   1126     int phy_port, phy_port_base;
   1127     soc_info_t *si = &SOC_INFO(unit);
   1128 
   1129     phy_port = si->port_l2p_mapping[port];
   1130     if (phy_port == -1) {
   1131         return FALSE;
   1132     }
   1133 
   1134     phy_port_base = ((phy_port - 1) & ~0x3) + 1;
   1135     if (phy_port == phy_port_base) {
   1136         return TRUE;
   1137     }
   1138 
   1139     return FALSE;
   1140 }
   1141 
   1142 STATIC int
   1143 _bcm_tr3_ibod_mac_x_enable_set(int unit, soc_port_t port, int enable)
   1144 {
   1145     uint64 ctrl, octrl;
   1146     pbmp_t mask;
   1147 
   1148     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
   1149     octrl = ctrl;
   1150     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1151     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1);
   1152     if (enable) {
   1153         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1);
   1154     } else {
   1155         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0);
   1156     }
   1157     if (COMPILER_64_NE(ctrl, octrl)) {
   1158         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
   1159         sal_udelay(10);
   1160     }
   1161 
   1162     /* Put the XMAC in a soft reset state when disabled to allow packets to
   1163      * drain from the TX FIFO */
   1164     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf,
   1165                           enable ? 0 : 1);
   1166     if (COMPILER_64_NE(ctrl, octrl)) {
   1167         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
   1168     }
   1169 
   1170     if (enable) {
   1171         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume,
   1172                                                PHY_STOP_MAC_DIS));
   1173     } else {
   1174         soc_link_mask2_get(unit, &mask);
   1175         SOC_PBMP_PORT_REMOVE(mask, port);
   1176         SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
   1177         SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0));
   1178         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop,
   1179                                                PHY_STOP_MAC_DIS));
   1180     }
   1181 
   1182     return SOC_E_NONE;
   1183 }
   1184 
   1185 STATIC int
   1186 _bcm_tr3_ibod_port_isolate(int unit, int port_enable, bcm_port_t port,
   1187                                   int *port_dis_untag, int *port_dis_tag)
   1188 {
   1189     port_tab_entry_t ptab_entry;
   1190 
   1191     /* Isolate, drain and remove port from epc link */
   1192     BCM_IF_ERROR_RETURN
   1193         (_bcm_tr3_ibod_mac_x_enable_set(unit, port, FALSE));
   1194 
   1195     if (port_enable) {
   1196         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1197                     (BSL_META_U(unit,
   1198                                "Port %d enable case..\n"), port));
   1199         /* Enable phy so that packets can loopback */
   1200         SOC_IF_ERROR_RETURN
   1201             (soc_phyctrl_enable_set(unit, port, TRUE));
   1202     } else {
   1203         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1204                     (BSL_META_U(unit,
   1205                                 "Port %d Runt received case..\n"), port));
   1206     }
   1207 
   1208     SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE));
   1209 
   1210     /* Enable MAC so that packets can loopback from phy */
   1211     BCM_IF_ERROR_RETURN
   1212         (_bcm_tr3_ibod_mac_x_enable_set(unit, port, TRUE));
   1213 
   1214     /* Discard tag and untag packet at IP before send packets */
   1215     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry));
   1216     *port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf);
   1217     *port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf);
   1218     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1);
   1219     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1);
   1220     BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry));
   1221 
   1222     return SOC_E_NONE;
   1223 }
   1224 
   1225 STATIC int
   1226 _bcm_tr3_ibod_port_resume(int unit, bcm_port_t port, int port_dis_untag, int port_dis_tag)
   1227 {
   1228     pbmp_t epc_pbm;
   1229     port_tab_entry_t ptab_entry;
   1230 
   1231     /* Remove MAC loopback */
   1232     SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, FALSE));
   1233 
   1234     /* Restore port discard tag and untag at IP  */
   1235     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry));
   1236     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag);
   1237     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag);
   1238     BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry));
   1239 
   1240     /* Restore port in epc link bmap */
   1241     soc_link_mask2_get(unit, &epc_pbm);
   1242     SOC_PBMP_PORT_ADD(epc_pbm, port);
   1243     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, epc_pbm));
   1244 
   1245     return SOC_E_NONE;
   1246 }
   1247 
   1248 STATIC int
   1249 _bcm_hx4_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_group_iter,
   1250                                  bcm_port_t port)
   1251 {
   1252     bcm_pbmp_t pbmp;
   1253     bcm_port_t port_iter;
   1254     uint32 port_mode;
   1255     uint32 rval, rval_1, port_dis_tag=0, port_dis_untag=0, xmac_mode=0;
   1256     uint64 rval64,tmp64;
   1257     uint64 egress_meter[4];
   1258     int unit=ibod_ctrl->unit;
   1259     int rv = BCM_E_NONE;
   1260     bcm_pkt_t *pkt = &ibod_ctrl->pkt;
   1261     pbmp_t mask, mask1, mask1_restore, mask_restore;
   1262     uint64 rrpkt, rrbyt, count64, count64_1;
   1263     int count, count_1, i;
   1264     soc_timeout_t timeout;
   1265     egr_enable_entry_t egr_en;
   1266     soc_info_t *si = &SOC_INFO(unit);
   1267     port_tab_entry_t ptab_entry;
   1268     egr_mmu_requests_entry_t mmu_entry;
   1269     int rx_llfc_en[4], rx_pfc_en[4], pause_rx[4], rx_lss[4], rx_lss_1[4], rx_en[4];
   1270     uint32 max_used_entry, ep_level, overflow0, overflow1, total_cell;
   1271     static const soc_reg_t lls_port_credit_reg[] = {
   1272         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   1273         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   1274         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   1275         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   1276         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   1277         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   1278         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   1279         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   1280         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   1281         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   1282         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   1283         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   1284         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   1285         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   1286         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   1287         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   1288         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   1289         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   1290         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   1291         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   1292         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   1293     }; 
   1294     sal_usecs_t time1, time2;
   1295 
   1296     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   1297 
   1298     rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp);
   1299     if (BCM_FAILURE(rv)) {
   1300         LOG_ERROR(BSL_LS_BCM_PORT,
   1301                   (BSL_META_U(unit, "\n Error in retreiving the subsidiary ports"
   1302                   "for port %s"), SOC_PORT_NAME(unit,port)));
   1303         return BCM_E_NONE;
   1304     }
   1305 
   1306     count=0;
   1307     BCM_PBMP_ITER(pbmp, port_iter) {
   1308         rv = READ_XMAC_MODEr(unit, port_iter, &rval64);
   1309         if (BCM_FAILURE(rv)) {
   1310             return BCM_E_NONE;
   1311         }
   1312         xmac_mode = soc_reg64_field32_get(unit, XMAC_MODEr,rval64, HDR_MODEf);
   1313         if ((xmac_mode == 1) || (xmac_mode == 2)) {
   1314             count++;
   1315         }
   1316     }
   1317 
   1318     if (!count) {
   1319          return BCM_E_NONE;
   1320     }
   1321 
   1322     BCM_PBMP_ITER(pbmp, port_iter) {
   1323         SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   1324         if (rval) {
   1325             LOG_ERROR(BSL_LS_BCM_PORT,
   1326                       (BSL_META_U(unit, "ENTER VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR"
   1327                       " failed on port:%d\n\r"), port_iter ));
   1328         }
   1329     }
   1330 
   1331     _bcm_esw_lc_lock(unit);
   1332 
   1333     soc_link_fwd_get(unit, &mask1);
   1334     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   1335      BCM_PBMP_ITER(pbmp, port_iter) {
   1336         BCM_PBMP_PORT_REMOVE(mask1,port_iter);
   1337      }
   1338     rv = soc_link_fwd_set(unit, mask1);
   1339     if (BCM_FAILURE(rv)) {
   1340         _bcm_esw_lc_unlock(unit);
   1341         LOG_ERROR(BSL_LS_BCM_PORT,
   1342                   (BSL_META_U(unit, "\n Error in setting the mask FWD"
   1343                   " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   1344         return BCM_E_NONE;
   1345     }
   1346 
   1347     /* Hold the ibod recovery port group lock */
   1348     _bcm_esw_ibod_recovery_port_lock(unit, port);
   1349     PORT_LOCK(unit);
   1350 
   1351     soc_link_mask2_get(unit, &mask);
   1352     SOC_PBMP_ASSIGN(mask_restore, mask);
   1353     BCM_PBMP_ITER(pbmp, port_iter) {
   1354         BCM_PBMP_PORT_REMOVE(mask,port_iter);
   1355     }
   1356     rv = soc_link_mask2_set(unit, mask);
   1357     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1358 
   1359 
   1360     BCM_PBMP_ITER(pbmp, port_iter) {
   1361         rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port_iter,
   1362                           &ptab_entry);
   1363         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1364         port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf);
   1365         port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf);
   1366         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1);
   1367         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1);
   1368         rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port_iter,
   1369                            &ptab_entry);
   1370         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1371     }
   1372 
   1373     count=0;
   1374     BCM_PBMP_ITER(pbmp, port_iter) {
   1375         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1376         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1377         rx_en[count] = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf);
   1378         count++;
   1379         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   1380         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1381         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1382     }
   1383 
   1384     BCM_PBMP_ITER(pbmp, port_iter) {
   1385         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1386         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1387         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0);
   1388         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1389         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1390     }
   1391 
   1392     BCM_PBMP_ITER(pbmp, port_iter) {
   1393         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1394         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1395         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1);
   1396         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1397         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1398     }
   1399 
   1400     BCM_PBMP_ITER(pbmp, port_iter) {
   1401         rv = READ_XPORT_TO_MMU_BKPr(unit, port_iter, &rval);
   1402         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1403         soc_reg_field_set(unit, XPORT_TO_MMU_BKPr, &rval, PRI15_0_BKPf, 0);
   1404         rv = WRITE_XPORT_TO_MMU_BKPr(unit, port_iter, 0);
   1405         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1406     }
   1407 
   1408     count=0;
   1409     BCM_PBMP_ITER(pbmp, port_iter) {
   1410         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   1411         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1412         pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf);
   1413         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0);
   1414         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   1415         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1416 
   1417         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   1418         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1419         rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf);
   1420         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0);
   1421         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   1422         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1423 
   1424         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   1425         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1426         rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf);
   1427         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0);
   1428         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   1429         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1430         count++;
   1431     }
   1432 
   1433     count=0;
   1434     BCM_PBMP_ITER(pbmp, port_iter) {
   1435         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   1436         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1437         egress_meter[count]=rval64;
   1438         COMPILER_64_ZERO(tmp64);
   1439         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64);
   1440         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1441         count++;
   1442     }
   1443 
   1444     count=0;
   1445     BCM_PBMP_ITER(pbmp, port_iter) {
   1446         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   1447         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1448         rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   1449                                        DROP_TX_DATA_ON_LOCAL_FAULTf);
   1450         rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   1451                                        DROP_TX_DATA_ON_REMOTE_FAULTf);
   1452         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   1453         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   1454         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   1455         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1456         count++;
   1457     }
   1458 
   1459     COMPILER_64_SET(tmp64, pbmp.pbits[1], pbmp.pbits[0]);
   1460     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   1461     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1462     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, tmp64);
   1463     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   1464     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1465 
   1466     BCM_PBMP_ITER(pbmp, port_iter) {
   1467         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   1468         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1469         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   1470         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   1471         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1472     }
   1473 
   1474     count_1=0;
   1475     soc_timeout_init(&timeout, 30000, 0);
   1476     do {
   1477         if (soc_timeout_check(&timeout)) {
   1478             rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   1479             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1480             soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   1481             rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   1482             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1483             /* coverity[overrun-local : FALSE] */
   1484             rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL,
   1485                                             si->port_l2p_mapping[port],
   1486                                             &max_used_entry);
   1487             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1488             ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   1489             if(ep_level == 0) {
   1490                 ibod_ctrl->drain_timeout_flag = 1;
   1491             }
   1492             else {
   1493                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   1494                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1495                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   1496                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1497                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell);
   1498                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1499                 LOG_ERROR(BSL_LS_BCM_PORT,
   1500                     (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, "
   1501                     "ep_level:%d, overflow0:%d, overflow1:%d,total_cell:%d\n"),
   1502                     ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1,total_cell));
   1503             }
   1504             break;
   1505         } else {
   1506             BCM_PBMP_ITER(pbmp, port_iter) {
   1507                rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1508                              REG_PORT_ANY, 0, &rval);
   1509                TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1510                if (!rval) {
   1511                    count_1++;
   1512                    rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   1513                                      si->port_l2p_mapping[port_iter],
   1514                                      &mmu_entry);
   1515                    TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1516                    rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   1517                    rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1518                                  REG_PORT_ANY, 0, rval);
   1519                    TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1520                }
   1521             }
   1522             count=0;
   1523             BCM_PBMP_ITER(pbmp, port_iter) {
   1524                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval);
   1525                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1526                 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   1527                 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   1528                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1529                 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   1530             }
   1531        }
   1532     } while (count);
   1533 
   1534     BCM_PBMP_ITER(pbmp, port_iter) {
   1535         /* coverity[overrun-local : FALSE] */
   1536         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   1537                           si->port_l2p_mapping[port_iter], &mmu_entry);
   1538         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1539         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   1540         /* coverity[overrun-local : FALSE] */
   1541         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1542                       REG_PORT_ANY, 0, &rval_1);
   1543         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1544         if (rval != rval_1) {
   1545             /* coverity[overrun-local : FALSE] */
   1546             rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1547                           REG_PORT_ANY, 0, rval);
   1548             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1549         }
   1550     }
   1551 
   1552     count = 0;
   1553     BCM_PBMP_ITER(pbmp, port_iter) {
   1554         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]);
   1555         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1556         count++;
   1557     }
   1558 
   1559     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1560     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1561     port_mode = soc_reg_field_get(unit, PORT_MODE_REGr,
   1562                                 rval, XPORT0_CORE_PORT_MODEf);
   1563 
   1564     BCM_PBMP_ITER(pbmp, port_iter) {
   1565         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   1566         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1567         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   1568         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   1569         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1570     }
   1571 
   1572     BCM_PBMP_ITER(pbmp, port_iter) {
   1573         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   1574         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1575         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   1576         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   1577         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1578     }
   1579 
   1580     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   1581     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1582     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   1583     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   1584     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1585 
   1586     BCM_PBMP_ITER(pbmp, port_iter) {
   1587         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   1588         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1589         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   1590         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   1591         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1592     }
   1593 
   1594     BCM_PBMP_ITER(pbmp, port_iter) {
   1595         rv = READ_RRPKTr(unit, port_iter, &rrpkt);
   1596         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1597         rv = READ_RRBYTr(unit, port_iter, &rrbyt);
   1598         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1599         /* coverity[overrun-local : FALSE] */
   1600         ibod_ctrl->rrpkt[port_iter] = rrpkt;
   1601         ibod_ctrl->rrbyt[port_iter] = rrbyt;
   1602     }
   1603 
   1604     BCM_PBMP_ITER(pbmp, port_iter) {
   1605         /* coverity[overrun-local : FALSE] */
   1606         rv = READ_EGR_ENABLEm(
   1607                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1608         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1609         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0);
   1610         rv = WRITE_EGR_ENABLEm(
   1611                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1612         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1613     }
   1614 
   1615     BCM_PBMP_ITER(pbmp, port_iter) {
   1616         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1617         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1618         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   1619         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1620         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1621     }
   1622 
   1623     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1624     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1625     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0);
   1626     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0);
   1627     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0);
   1628     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0);
   1629     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1630     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1631 
   1632     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1633     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1634     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   1635                                 rval, XPORT0_CORE_PORT_MODEf);
   1636     if(port_mode) {
   1637         soc_reg_field_set(unit, PORT_MODE_REGr,
   1638                            &rval, XPORT0_CORE_PORT_MODEf,0);
   1639     }
   1640     else {
   1641         soc_reg_field_set(unit, PORT_MODE_REGr,
   1642                            &rval, XPORT0_CORE_PORT_MODEf,1);
   1643     }
   1644     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1645     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1646     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1647     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1648     soc_reg_field_set(unit, PORT_MODE_REGr,
   1649                       &rval, XPORT0_CORE_PORT_MODEf,port_mode);
   1650     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1651     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1652 
   1653     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1654     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1655     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1);
   1656     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1);
   1657     if (port_mode == 2) {
   1658         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1);
   1659         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1);
   1660     }
   1661     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1662     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1663 
   1664     BCM_PBMP_ITER(pbmp, port_iter) {
   1665         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1666         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1667         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   1668         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1669         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1670     }
   1671 
   1672     BCM_PBMP_ITER(pbmp, port_iter) {
   1673         rv = READ_EGR_ENABLEm(
   1674                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1675         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1676         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1);
   1677         rv = WRITE_EGR_ENABLEm(
   1678                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1679         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1680     }
   1681 
   1682     BCM_PBMP_ITER(pbmp, port_iter) {
   1683         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1684         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1685         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1);
   1686         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1687         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1688     }
   1689 
   1690     BCM_PBMP_ITER(pbmp, port_iter) {
   1691         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1692         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1693         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1);
   1694         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 1);
   1695         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1696         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1697     }
   1698     BCM_PBMP_ITER(pbmp, port_iter) {
   1699         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1700         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1701         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0);
   1702         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1703         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1704     }
   1705     sal_udelay(200);
   1706     /* Send 80-byte packets to fill IBOD FIFO */
   1707     BCM_PBMP_ITER(pbmp, port_iter) {
   1708         rv = READ_RPKTr(unit, port_iter, &rval64);
   1709         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1710         count64 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1711         for (i=0;i<2;i++)
   1712         {
   1713             BCM_PKT_TX_LEN_SET(pkt, 68);
   1714             BCM_PKT_HDR_VTAG_CONTROL_SET(pkt, VLAN_CTRL(0, 0, 1));
   1715             BCM_PKT_PORT_SET(pkt, port_iter, FALSE, FALSE);
   1716             rv = bcm_common_tx(unit, pkt, NULL);
   1717             if (BCM_FAILURE(rv)) {
   1718                 LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U(unit,"IBOD 80-byte packet transmit"
   1719                           "failed[%d] on port:%d\n\r"), rv, port_iter));
   1720                 ibod_ctrl->port_recovery_failed_flag = 1;
   1721                 break;
   1722             }
   1723             sal_udelay(200);
   1724 
   1725         }
   1726         if (ibod_ctrl->port_recovery_failed_flag) {
   1727             break;
   1728         }
   1729 
   1730         rv = READ_RPKTr(unit, port_iter, &rval64);
   1731         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1732         count64_1 =  soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1733         COMPILER_64_SET(tmp64, 0, 2);
   1734         COMPILER_64_SUB_64(count64_1, count64);
   1735         if (COMPILER_64_LT(count64_1, tmp64)) {
   1736             sal_udelay(1000);
   1737             rv = READ_RPKTr(unit, port_iter, &rval64);
   1738             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1739             count64_1 =  soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1740             COMPILER_64_SUB_64(count64_1, count64);
   1741             if (COMPILER_64_LT(count64_1, tmp64)) {
   1742                 LOG_WARN(BSL_LS_BCM_PORT,
   1743                      (BSL_META_U(unit,"\n HELIX4 IBOD loopback packet"
   1744                                  " not received in port %s"),SOC_PORT_NAME(unit,port_iter)));
   1745             }
   1746         }
   1747     }
   1748 
   1749     BCM_PBMP_ITER(pbmp, port_iter) {
   1750         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1751         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1752         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   1753         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1754         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1755     }
   1756 
   1757     BCM_PBMP_ITER(pbmp, port_iter) {
   1758         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1759         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1760         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0);
   1761         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1762         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1763     }
   1764 
   1765     BCM_PBMP_ITER(pbmp, port_iter) {
   1766         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1767         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1768         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1);
   1769         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1770         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1771     }
   1772 
   1773     BCM_PBMP_ITER(pbmp, port_iter) {
   1774         rv = READ_EGR_ENABLEm(
   1775                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1776         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1777         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0);
   1778         rv = WRITE_EGR_ENABLEm(
   1779                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1780         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1781     }
   1782 
   1783     BCM_PBMP_ITER(pbmp, port_iter) {
   1784         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1785         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1786         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   1787         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1788         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1789     }
   1790 
   1791     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1792     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1793     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0);
   1794     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0);
   1795     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0);
   1796     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0);
   1797     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1798     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1799 
   1800     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1801     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1802     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   1803                                 rval, XPORT0_CORE_PORT_MODEf);
   1804     if(port_mode) {
   1805         soc_reg_field_set(unit, PORT_MODE_REGr,
   1806                            &rval, XPORT0_CORE_PORT_MODEf,0);
   1807     }
   1808     else {
   1809         soc_reg_field_set(unit, PORT_MODE_REGr,
   1810                            &rval, XPORT0_CORE_PORT_MODEf,1);
   1811     }
   1812     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1813     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1814     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1815     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1816     soc_reg_field_set(unit, PORT_MODE_REGr,
   1817                       &rval, XPORT0_CORE_PORT_MODEf,port_mode);
   1818     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1819     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1820 
   1821     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1822     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1823     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1);
   1824     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1);
   1825     if (port_mode == 2) {
   1826         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1);
   1827         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1);
   1828     }
   1829     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1830     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1831 
   1832     BCM_PBMP_ITER(pbmp, port_iter) {
   1833         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1834         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1835         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   1836         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1837         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1838     }
   1839 
   1840     BCM_PBMP_ITER(pbmp, port_iter) {
   1841         rv = READ_EGR_ENABLEm(
   1842                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1843         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1844         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1);
   1845         rv = WRITE_EGR_ENABLEm(
   1846                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1847         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1848     }
   1849 
   1850     switch(port_group_iter) {
   1851         case 0:
   1852           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1853           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1854           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1855                  &rval, CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1856           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1857                  &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1858           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1859           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1860           break;
   1861         case 1:
   1862           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1863           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1864           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1865                  &rval, CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1866           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1867                  &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1868           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1869           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1870           break;
   1871         case 2:
   1872           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1873           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1874           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1875                  &rval, CL2_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1876           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1877                  &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1878           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1879           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1880           break;
   1881         default:
   1882           break;
   1883     }
   1884 
   1885     rv = READ_MEM_FAIL_INT_STAT_64r(unit, &rval64);
   1886     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1887     soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r,
   1888                           &rval64, START_BY_START_ERRf, 0);
   1889     rv = WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64);
   1890     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1891 
   1892     rv = READ_MEM_FAIL_INT_CTRr(unit, &rval);
   1893     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1894     soc_reg_field_set(unit, MEM_FAIL_INT_CTRr, &rval, INT_CTRf, 0);
   1895     rv = WRITE_MEM_FAIL_INT_CTRr(unit, rval);
   1896     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1897 
   1898     BCM_PBMP_ITER(pbmp, port_iter) {
   1899         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1900         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1901         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 0);
   1902         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1903         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1904     }
   1905 
   1906     BCM_PBMP_ITER(pbmp, port_iter) {
   1907         rv = soc_mem_read(
   1908                 unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, &ptab_entry);
   1909         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1910         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag);
   1911         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag);
   1912         rv = soc_mem_write(
   1913                 unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, &ptab_entry);
   1914         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1915     }
   1916 
   1917     count=0;
   1918     BCM_PBMP_ITER(pbmp, port_iter) {
   1919         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   1920         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1921         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]);
   1922         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]);
   1923         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   1924         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1925         count++;
   1926     }
   1927 
   1928     count=0;
   1929     BCM_PBMP_ITER(pbmp, port_iter) {
   1930         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   1931         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1932         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]);
   1933         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   1934         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1935 
   1936         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   1937         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1938         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]);
   1939         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   1940         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1941 
   1942         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   1943         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1944         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]);
   1945         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   1946         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1947         count++;
   1948     }
   1949 
   1950     BCM_PBMP_ITER(pbmp, port_iter) {
   1951         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1952         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1953         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0);
   1954         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1955         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1956     }
   1957 
   1958     count=0;
   1959     BCM_PBMP_ITER(pbmp, port_iter) {
   1960         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1961         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1962         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1);
   1963         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, rx_en[count]);
   1964         count++;
   1965         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1966         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1967     }
   1968     sal_udelay(200);
   1969     rv = soc_link_mask2_set(unit, mask_restore);
   1970     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1971 
   1972     PORT_UNLOCK(unit);
   1973     /* Release the ibod recovery port group lock */
   1974     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   1975 
   1976     rv = soc_link_fwd_set(unit, mask1_restore);
   1977     if (BCM_FAILURE(rv)) {
   1978         _bcm_esw_lc_unlock(unit);
   1979         LOG_ERROR(BSL_LS_BCM_PORT,
   1980                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   1981                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   1982         return BCM_E_NONE;
   1983     }
   1984     _bcm_esw_lc_unlock(unit);
   1985 
   1986     BCM_PBMP_ITER(pbmp, port_iter) {
   1987         SOC_IF_ERROR_RETURN(
   1988             READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   1989         if (rval) {
   1990             LOG_ERROR(BSL_LS_BCM_PORT,
   1991                       (BSL_META_U(unit," EXIT VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR"
   1992                              " failed on port:%d\n\r"), port_iter));
   1993         }
   1994     }
   1995     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   1996     ibod_ctrl->event_count++;
   1997     ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count - 1) +
   1998             time2 - time1) /ibod_ctrl->event_count;
   1999 
   2000     return SOC_E_NONE;
   2001 
   2002 }
   2003 
   2004 STATIC int
   2005 _bcm_hx4_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl,
   2006                                  bcm_port_t port)
   2007 {
   2008     bcm_pbmp_t pbmp;
   2009     bcm_port_t port_iter;
   2010     uint32 port_mode;
   2011     uint32 rval, rval_1;
   2012     uint64 rval64, txerr, flush_enable_pbm, tmp64;
   2013     uint64 egress_meter[4];
   2014     int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE;
   2015     pbmp_t      mask, mask1, mask1_restore, mask_restore;
   2016     soc_timeout_t timeout;
   2017     int count,count_1;
   2018     soc_info_t *si = &SOC_INFO(unit);
   2019     egr_mmu_requests_entry_t mmu_entry;
   2020     int rx_llfc_en[4],rx_pfc_en[4],pause_rx[4], rx_lss[4], rx_lss_1[4];
   2021     uint32 max_used_entry, ep_level, overflow0, overflow1;
   2022     static const soc_reg_t lls_port_credit_reg[] = {
   2023         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   2024         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   2025         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   2026         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   2027         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   2028         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   2029         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   2030         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   2031         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   2032         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   2033         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   2034         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   2035         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   2036         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   2037         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   2038         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   2039         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   2040         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   2041         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   2042         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   2043         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   2044     }; 
   2045     sal_usecs_t time1, time2;
   2046 
   2047     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2048 
   2049     SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
   2050     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   2051                                 rval, XPORT0_CORE_PORT_MODEf);
   2052     sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t));
   2053     if (port_mode) {
   2054         rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp);
   2055         if (BCM_FAILURE(rv)) {
   2056             LOG_ERROR(BSL_LS_BCM_PORT,
   2057                       (BSL_META_U(unit,"\n Error in retreiving the subsidiary ports"
   2058                                      " for port %s"), SOC_PORT_NAME(unit,port)));
   2059             return BCM_E_NONE;
   2060         }
   2061     } else {
   2062         SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   2063         if (okay) {
   2064             SOC_PBMP_PORT_ADD(pbmp, port);
   2065         } else {
   2066             return SOC_E_NONE;
   2067         }
   2068     }
   2069 
   2070     BCM_PBMP_ITER(pbmp, port_iter) {
   2071         SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   2072         if (rval) {
   2073             LOG_ERROR(BSL_LS_BCM_PORT,
   2074                       (BSL_META_U(unit,"IBOD PORT_CDC_TXFIFO_OVRFLW ERR"
   2075                          " failed on port:%d\n\r"), port_iter));
   2076         }
   2077     }
   2078 
   2079     count=0;
   2080     BCM_PBMP_ITER(pbmp, port_iter) {
   2081        SOC_IF_ERROR_RETURN(READ_TERRr(unit, port_iter, &txerr));
   2082        /* coverity[overrun-local : FALSE] */
   2083        if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port_iter], txerr)) {
   2084            ibod_ctrl->txerrpkt[port_iter] = txerr;
   2085            count++;
   2086        }
   2087     }
   2088     BCM_PBMP_ITER(pbmp, port_iter) {
   2089         SOC_IF_ERROR_RETURN(READ_XMAC_FIFO_STATUSr(unit, port_iter, &rval64));
   2090         if (!count) {
   2091             count = soc_reg64_field32_get(unit, XMAC_FIFO_STATUSr, rval64, TX_PKT_UNDERFLOWf);
   2092         }
   2093     }
   2094 
   2095     if (!count) {
   2096         return SOC_E_NONE;
   2097     }
   2098 
   2099     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2100              (BSL_META_U(unit,"\n WAR Trigerred by TXERR in subports %s"),SOC_PORT_NAME(unit,port)));
   2101 
   2102     _bcm_esw_lc_lock(unit);
   2103     soc_link_fwd_get(unit, &mask1);
   2104     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   2105     BCM_PBMP_ITER(pbmp, port_iter) {
   2106         BCM_PBMP_PORT_REMOVE(mask1,port_iter);
   2107     }
   2108     rv = soc_link_fwd_set(unit, mask1);
   2109     if (BCM_FAILURE(rv)) {
   2110         _bcm_esw_lc_unlock(unit);
   2111         LOG_ERROR(BSL_LS_BCM_PORT,
   2112                       (BSL_META_U(unit,"\n Error in setting the mask FWD"
   2113                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   2114         return BCM_E_NONE;
   2115     }
   2116 
   2117     /* Hold the ibod recovery port group lock */
   2118     _bcm_esw_ibod_recovery_port_lock(unit, port);
   2119     PORT_LOCK(unit);
   2120 
   2121     soc_link_mask2_get(unit, &mask);
   2122     SOC_PBMP_ASSIGN(mask_restore,mask);
   2123     BCM_PBMP_ITER(pbmp, port_iter) {
   2124         BCM_PBMP_PORT_REMOVE(mask,port_iter);
   2125     }
   2126     rv = soc_link_mask2_set(unit, mask);
   2127     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2128 
   2129 
   2130     count=0;
   2131     BCM_PBMP_ITER(pbmp, port_iter) {
   2132         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   2133         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2134         pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf);
   2135         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0);
   2136         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   2137         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2138 
   2139         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   2140         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2141         rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf);
   2142         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0);
   2143         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   2144         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2145 
   2146         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   2147         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2148         rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf);
   2149         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0);
   2150         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   2151         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2152         count++;
   2153     }
   2154 
   2155     count=0;
   2156     BCM_PBMP_ITER(pbmp, port_iter) {
   2157         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   2158         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2159         egress_meter[count] = rval64;
   2160         COMPILER_64_ZERO(tmp64);
   2161         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64);
   2162         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2163         count++;
   2164     }
   2165 
   2166     count=0;
   2167     BCM_PBMP_ITER(pbmp, port_iter) {
   2168         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2169         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2170         rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2171                                        DROP_TX_DATA_ON_LOCAL_FAULTf);
   2172         rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2173                                        DROP_TX_DATA_ON_REMOTE_FAULTf);
   2174         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   2175         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   2176         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2177         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2178         count++;
   2179     }
   2180 
   2181     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2182     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2183     COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]);
   2184     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm);
   2185     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2186     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2187 
   2188     BCM_PBMP_ITER(pbmp, port_iter) {
   2189         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   2190         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2191         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   2192         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   2193         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2194     }
   2195     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   2196     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2197     port_mode = soc_reg_field_get(unit, PORT_MODE_REGr,
   2198                                   rval, XPORT0_CORE_PORT_MODEf);
   2199 
   2200     soc_timeout_init(&timeout, 30000, 0);
   2201     count_1=0;
   2202     do {
   2203         if (soc_timeout_check(&timeout)) {
   2204             ep_level = 0;
   2205             BCM_PBMP_ITER(pbmp, port_iter) {
   2206                 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   2207                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2208                 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   2209                 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   2210                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2211                 /* coverity[overrun-local : FALSE] */
   2212                 rv = READ_EGR_MAX_USED_ENTRIESm(
   2213                         unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port_iter],
   2214                         &max_used_entry);
   2215                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2216                 ep_level += soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   2217             }
   2218             if(ep_level == 0) {
   2219                 ibod_ctrl->drain_timeout_flag = 1;
   2220             }
   2221             else {
   2222                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   2223                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2224                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   2225                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2226                 LOG_ERROR(BSL_LS_BCM_PORT,
   2227                     (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, "
   2228                         "total ep_level:%d, overflow0:%d, overflow1:%d\n"),
   2229                         ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1));
   2230             }
   2231             break;
   2232         } else {
   2233             BCM_PBMP_ITER(pbmp, port_iter) {
   2234                 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2235                                      REG_PORT_ANY, 0, &rval);
   2236                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2237                 if (!rval) {
   2238                     count_1++;
   2239                     rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   2240                                       si->port_l2p_mapping[port_iter],
   2241                                       &mmu_entry);
   2242                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2243                     rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2244                     rv = soc_reg32_set(unit,
   2245                         lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2246                         REG_PORT_ANY, 0, rval);
   2247                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2248                 }
   2249             }
   2250             count=0;
   2251             BCM_PBMP_ITER(pbmp, port_iter) {
   2252                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval);
   2253                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2254                 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   2255                 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2256                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2257                 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   2258 
   2259             }
   2260        }
   2261     } while (count);
   2262 
   2263     BCM_PBMP_ITER(pbmp, port_iter) {
   2264         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   2265                           si->port_l2p_mapping[port_iter], &mmu_entry);
   2266         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2267         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2268         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2269                                             REG_PORT_ANY, 0, &rval_1);
   2270         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2271         if (rval != rval_1) {
   2272             rv = soc_reg32_set(unit,
   2273                 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2274                 REG_PORT_ANY, 0, rval);
   2275             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2276         }
   2277     }
   2278 
   2279     BCM_PBMP_ITER(pbmp, port_iter) {
   2280         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   2281         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2282         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   2283         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   2284         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2285     }
   2286 
   2287     BCM_PBMP_ITER(pbmp, port_iter) {
   2288         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   2289         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2290         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   2291         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   2292         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2293     }
   2294 
   2295     count=0;
   2296     BCM_PBMP_ITER(pbmp, port_iter) {
   2297         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]);
   2298         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2299         count++;
   2300     }
   2301 
   2302     BCM_PBMP_ITER(pbmp, port_iter) {
   2303         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   2304         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2305         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   2306         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   2307         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2308     }
   2309 
   2310     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2311     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2312     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   2313     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2314     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2315 
   2316     count=0;
   2317     BCM_PBMP_ITER(pbmp, port_iter) {
   2318         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2319         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2320         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]);
   2321         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]);
   2322         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2323         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2324         count++;
   2325     }
   2326 
   2327     count=0;
   2328     BCM_PBMP_ITER(pbmp, port_iter) {
   2329         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   2330         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2331         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]);
   2332         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   2333         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2334 
   2335         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   2336         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2337         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]);
   2338         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   2339         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2340 
   2341         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   2342         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2343         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]);
   2344         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   2345         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2346         count++;
   2347     }
   2348 
   2349     rv = soc_link_mask2_set(unit, mask_restore);
   2350     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2351     PORT_UNLOCK(unit);
   2352     /* Release the ibod recovery port group lock */
   2353     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   2354 
   2355     rv = soc_link_fwd_set(unit, mask1_restore);
   2356     if (BCM_FAILURE(rv)) {
   2357         _bcm_esw_lc_unlock(unit);
   2358         LOG_ERROR(BSL_LS_BCM_PORT,
   2359                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   2360                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   2361         return BCM_E_NONE;
   2362     }
   2363 
   2364     _bcm_esw_lc_unlock(unit);
   2365     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2366     ibod_ctrl->txerr_count++;
   2367     ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) +
   2368             time2 - time1) /ibod_ctrl->txerr_count;
   2369 
   2370     return SOC_E_NONE;
   2371 }
   2372 
   2373 
   2374 STATIC int
   2375 _bcm_tr3_mmu_recovery(_port_ibod_ctrl_t *ibod_ctrl)
   2376 {
   2377     mac_driver_t *macd;
   2378     bcm_port_t port_iter;
   2379     uint32 rval, rval_1, count;
   2380     uint64 rval64,txerr, val64;
   2381     int unit=ibod_ctrl->unit, rv = BCM_E_NONE;
   2382     soc_info_t *si = &SOC_INFO(unit);
   2383     egr_mmu_requests_entry_t mmu_entry;
   2384     int linkscan_interval, counter_interval;
   2385     uint32 counter_flags;
   2386     uint32    l2x_flags;
   2387     int scan_rate, l2x_running = 0, mem_scan_running = 0;
   2388     sal_usecs_t l2x_interval, scan_interval;
   2389     bcm_pbmp_t rx_en_pbmp, rx_llfc_en_pbmp, tx_llfc_en_pbmp;
   2390     bcm_pbmp_t rx_pfc_en_pbmp, tx_pfc_en_pbmp;
   2391     bcm_pbmp_t pause_rx_pbmp, pause_tx_pbmp;
   2392     bcm_pbmp_t rx_lss_local_pbmp,rx_lss_remote_pbmp, counter_pbmp;
   2393     uint64 egrmeteringconfig[_SOC_TR3_MAX_NUM_LPORTS];
   2394     soc_timeout_t timeout;
   2395     int num_mmu_port, mmu_port, phy_port, port;
   2396     pbmp_t  pbm;
   2397     epc_link_bmap_entry_t entry, epc_lin_bmap_entry;
   2398     static const soc_reg_t lls_port_credit_reg[] = {
   2399         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   2400         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   2401         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   2402         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   2403         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   2404         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   2405         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   2406         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   2407         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   2408         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   2409         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   2410         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   2411         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   2412         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   2413         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   2414         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   2415         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   2416         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   2417         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   2418         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   2419         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   2420     }; 
   2421     sal_usecs_t time1, time2;
   2422 
   2423     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2424 
   2425     /*****"Preparation and Stop ingress traffic Start*****/
   2426     /*1.  Disable all back ground threads to prevent any SBUS acitivities (software handling)*/
   2427     BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_get(unit, &linkscan_interval));
   2428     BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_set(unit, 0));
   2429     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &counter_flags,
   2430                     &counter_interval, &counter_pbmp));
   2431     BCM_IF_ERROR_RETURN(soc_counter_stop(unit));
   2432     if (soc_l2x_running(unit, &l2x_flags, &l2x_interval)) {
   2433         l2x_running = 1;
   2434         BCM_IF_ERROR_RETURN(soc_l2x_stop(unit));
   2435     }
   2436 #ifdef INCLUDE_MEM_SCAN
   2437     if (soc_mem_scan_running(unit, &scan_rate, &scan_interval)) {
   2438         mem_scan_running = 1;
   2439         BCM_IF_ERROR_RETURN(soc_mem_scan_stop(unit));
   2440     }
   2441 #endif
   2442 
   2443     /*2.  Disable "TX" API to prevent CPU packet from going into MMU (software handling)*/
   2444     PBMP_PORT_ITER(unit, port_iter){
   2445         _bcm_esw_ibod_recovery_port_lock(unit, port_iter);
   2446     }
   2447 
   2448     /*3. Stop all ingress ports traffic to prevent any packet from going into MMU */
   2449     sal_memset(&rx_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2450     PBMP_PORT_ITER(unit, port_iter){
   2451         macd = PORT(unit, port_iter).p_mac;
   2452         rv = MAC_CONTROL_GET(macd,unit, port_iter, SOC_MAC_CONTROL_RX_SET, (int *)&rval);
   2453         if (BCM_FAILURE(rv)) {
   2454             goto end;
   2455         }
   2456         if (rval) {
   2457             BCM_PBMP_PORT_ADD(rx_en_pbmp, port_iter);
   2458         }
   2459         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 0);
   2460         if (BCM_FAILURE(rv)) {
   2461             goto end;
   2462         }
   2463     }
   2464 
   2465     /*4. Stop all AXP traffic to prevent any packet from going into MMU */
   2466     sal_memset(&pbm, 0, sizeof(pbmp_t));
   2467     /*    coverity[check_return]    */
   2468     rv = READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   2469     if (BCM_FAILURE(rv)) {
   2470         goto end;
   2471     }
   2472     sal_memcpy(&epc_lin_bmap_entry, &entry, sizeof(epc_link_bmap_entry_t));
   2473     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   2474     rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   2475     if (BCM_FAILURE(rv)) {
   2476         goto end;
   2477     }
   2478     /*****"Preparation and Stop ingress traffic End*****/
   2479 
   2480     /*****Packet Drain Start*****/
   2481     /* 1.Stop all pauses to speed up draining*/
   2482     sal_memset(&pause_rx_pbmp, 0, sizeof(bcm_pbmp_t));
   2483     sal_memset(&pause_tx_pbmp, 0, sizeof(bcm_pbmp_t));
   2484 
   2485     PBMP_PORT_ITER(unit, port_iter){
   2486         macd = PORT(unit, port_iter).p_mac;
   2487         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2488         if (BCM_FAILURE(rv)) {
   2489             goto end;
   2490         }
   2491         if (rval) {
   2492             BCM_PBMP_PORT_ADD(pause_tx_pbmp, port_iter);
   2493         }
   2494         if (rval_1) {
   2495             BCM_PBMP_PORT_ADD(pause_rx_pbmp, port_iter);
   2496         }
   2497         rv = MAC_PAUSE_SET(macd, unit, port_iter, 0, 0);
   2498         if (BCM_FAILURE(rv)) {
   2499             goto end;
   2500         }
   2501     }
   2502 
   2503     sal_memset(&rx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2504     sal_memset(&tx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2505     PBMP_PORT_ITER(unit, port_iter){
   2506         macd = PORT(unit, port_iter).p_mac;
   2507         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, (int *)&rval);
   2508         if (BCM_FAILURE(rv)) {
   2509             goto end;
   2510         }
   2511         if (rval) {
   2512             BCM_PBMP_PORT_ADD(tx_llfc_en_pbmp, port_iter);
   2513         }
   2514         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 0);
   2515         if (BCM_FAILURE(rv)) {
   2516             goto end;
   2517         }
   2518         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, (int *)&rval);
   2519         if (BCM_FAILURE(rv)) {
   2520             goto end;
   2521         }
   2522         if (rval) {
   2523             BCM_PBMP_PORT_ADD(rx_llfc_en_pbmp, port_iter);
   2524         }
   2525         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 0);
   2526         if (BCM_FAILURE(rv)) {
   2527             goto end;
   2528         }
   2529     }
   2530 
   2531     sal_memset(&tx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2532     sal_memset(&rx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2533     PBMP_PORT_ITER(unit, port_iter){
   2534         macd = PORT(unit, port_iter).p_mac;
   2535         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, (int *)&rval);
   2536         if (BCM_FAILURE(rv)) {
   2537             goto end;
   2538         }
   2539         if (rval) {
   2540             BCM_PBMP_PORT_ADD(tx_pfc_en_pbmp, port_iter);
   2541         }
   2542         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 0);
   2543         if (BCM_FAILURE(rv)) {
   2544             goto end;
   2545         }
   2546         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, (int *)&rval);
   2547         if (BCM_FAILURE(rv)) {
   2548             goto end;
   2549         }
   2550         if (rval) {
   2551             BCM_PBMP_PORT_ADD(rx_pfc_en_pbmp, port_iter);
   2552         }
   2553         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0);
   2554         if (BCM_FAILURE(rv)) {
   2555             goto end;
   2556         }
   2557     }
   2558 
   2559     /*2. Set XMAC LLS CTRL to ignore Serdes fault signal which may prevent packets from draining at cable unplug case*/
   2560     sal_memset(&rx_lss_local_pbmp, 0, sizeof(bcm_pbmp_t));
   2561     sal_memset(&rx_lss_remote_pbmp, 0, sizeof(bcm_pbmp_t));
   2562     PBMP_PORT_ITER(unit, port_iter){
   2563         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2564         if (BCM_FAILURE(rv)) {
   2565             goto end;
   2566         }
   2567         rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2568                                         DROP_TX_DATA_ON_LOCAL_FAULTf);
   2569         if (0 == rval) {
   2570             BCM_PBMP_PORT_ADD(rx_lss_local_pbmp, port_iter);
   2571             soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   2572         }
   2573 
   2574         rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2575                                         DROP_TX_DATA_ON_REMOTE_FAULTf);
   2576         if (0 == rval) {
   2577             BCM_PBMP_PORT_ADD(rx_lss_remote_pbmp, port_iter);
   2578             soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   2579         }
   2580         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2581         if (BCM_FAILURE(rv)) {
   2582             goto end;
   2583         }
   2584     }
   2585 
   2586     /*3. Enable IPMC fast flush */
   2587     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2588     if (BCM_FAILURE(rv)) {
   2589         goto end;
   2590     }
   2591 
   2592     COMPILER_64_SET(val64, 0x3fffffff, 0xffffffff);
   2593     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, val64);
   2594     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2595     if (BCM_FAILURE(rv)) {
   2596         goto end;
   2597     }
   2598 
   2599     /*4. Set PORT fast flush */
   2600     PBMP_PORT_ITER(unit, port_iter){
   2601         rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter,
   2602                 DROP_ENf, 1);
   2603         if (BCM_FAILURE(rv)) {
   2604             goto end;
   2605         }
   2606     }
   2607 
   2608     /*5.Stop MMU egress */
   2609     PBMP_PORT_ITER(unit, port_iter){
   2610         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   2611         if (BCM_FAILURE(rv)) {
   2612             goto end;
   2613         }
   2614 
   2615         COMPILER_64_SET(egrmeteringconfig[port_iter], COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2616         COMPILER_64_SET(val64, 0, 0);
   2617         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, REFRESHf, val64);
   2618         COMPILER_64_SET(val64, 0, 1);
   2619         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, THD_SELf, val64);
   2620         COMPILER_64_SET(val64, 0, 0);
   2621         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, METER_GRANf, val64);
   2622         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, rval64);
   2623         if (BCM_FAILURE(rv)) {
   2624             goto end;
   2625         }
   2626     }
   2627 
   2628     /*6.Wait until all PORT TXFIFO count == 0*/
   2629     soc_timeout_init(&timeout, 30000, 0);
   2630     do {
   2631         if (soc_timeout_check(&timeout)) {
   2632             LOG_ERROR(BSL_LS_BCM_PORT,
   2633                       (BSL_META_U(unit, "\n MMU Recovery Timeout Ports Drain packets unit:%d"), ibod_ctrl->unit));
   2634             break;
   2635         }
   2636         count=0;
   2637         PBMP_PORT_ITER(unit, port_iter){
   2638             rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2639             if (BCM_FAILURE(rv)) {
   2640                 goto end;
   2641             }
   2642             count += soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr,rval, CELL_CNTf);
   2643             rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2644             if (BCM_FAILURE(rv)) {
   2645                 goto end;
   2646             }
   2647             count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   2648         }
   2649     } while (count);
   2650 
   2651     /*****Packet Drain End*****/
   2652 
   2653     /*****MMU reset Start*****/
   2654     /*1. Backup all necessary MMU configurations */
   2655     rv = soc_tr3_mmu_register_store(unit);
   2656     if (BCM_FAILURE(rv)) {
   2657         goto end;
   2658     }
   2659     rv = soc_tr3_mmu_memory_store(unit);
   2660     if (BCM_FAILURE(rv)) {
   2661         goto end;
   2662     }
   2663 
   2664     /*2. Do TOP level MMU reset*/
   2665     rv = READ_TOP_SOFT_RESET_REGr(unit, &rval);
   2666     if (BCM_FAILURE(rv)) {
   2667         goto end;
   2668     }
   2669     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0);
   2670     rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   2671     if (BCM_FAILURE(rv)) {
   2672         goto end;
   2673     }
   2674     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   2675     rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   2676     if (BCM_FAILURE(rv)) {
   2677         goto end;
   2678     }
   2679      /* 3. REFRESH_ENF*/
   2680     rv = soc_reg32_get(unit, MISCCONFIGr, REG_PORT_ANY, 0, &rval);
   2681     if (BCM_FAILURE(rv)) {
   2682         goto end;
   2683     }
   2684     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   2685     rv = soc_reg32_set(unit, MISCCONFIGr, REG_PORT_ANY, 0, rval);
   2686     if(BCM_FAILURE(rv)) {
   2687         goto end;
   2688     }
   2689 
   2690     /*4. Call soc_mmu_init to init MMU*/
   2691     rv = soc_mmu_init(unit);
   2692     if (BCM_FAILURE(rv)) {
   2693         goto end;
   2694     }
   2695 
   2696      /*5.Restore Registers/Memories which are called in MMU init (following MMU init sequence)*/
   2697     rv = soc_tr3_mmu_init_restore(unit);
   2698     if (BCM_FAILURE(rv)) {
   2699     goto end;
   2700     }
   2701 
   2702     /*6.Restore other MMU registers without sequence*/
   2703     rv = soc_tr3_mmu_register_restore(unit);
   2704     if (BCM_FAILURE(rv)) {
   2705         goto end;
   2706     }
   2707 
   2708     /*7.Restore other MMU memories without sequence*/
   2709     rv = soc_tr3_mmu_memory_restore(unit);
   2710     if (BCM_FAILURE(rv)) {
   2711         goto end;
   2712     }
   2713 
   2714     /*8.Restore MMU2PHY port mapping and MMU2LOGIC port mapping*/
   2715     num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr);
   2716     for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) {
   2717         phy_port = si->port_m2p_mapping[mmu_port];
   2718         port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port];
   2719 
   2720         rval = 0;
   2721         soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf,
   2722                           phy_port == -1 ? 0x7f : phy_port);
   2723         rv = WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval);
   2724         if (BCM_FAILURE(rv)) {
   2725             goto end;
   2726         }
   2727         rval = 0;
   2728         soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf,
   2729                           port == -1 ? 0x3f : port);
   2730         rv = WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval);
   2731         if (BCM_FAILURE(rv)) {
   2732             goto end;
   2733         }
   2734     }
   2735 
   2736     /* 9. Restore MMU to EP credicts after EP restore because EP port enable will update EGR_MMU_REQUESTSm*/
   2737     PBMP_ALL_ITER(unit, port_iter){
   2738         if (!IS_CPU_PORT(unit, port_iter) && !IS_PORT(unit, port_iter)) {
   2739             continue;
   2740         }
   2741         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port_iter], &mmu_entry);
   2742         if (BCM_FAILURE(rv)) {
   2743             goto end;
   2744         }
   2745         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2746         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2747                            REG_PORT_ANY, 0, &rval_1);
   2748         if (BCM_FAILURE(rv)) {
   2749             goto end;
   2750         }
   2751         if (rval != rval_1) {
   2752             rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2753                               REG_PORT_ANY, 0, rval);
   2754             if(BCM_FAILURE(rv)) {
   2755                 goto end;
   2756             }
   2757         }
   2758     }
   2759     /*restore axp credit*/
   2760     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[58]]],
   2761                       REG_PORT_ANY, 0, 0x14);
   2762     if (BCM_FAILURE(rv)) {
   2763         goto end;
   2764     }
   2765     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[59]]],
   2766                       REG_PORT_ANY, 0, 0x14);
   2767     if (BCM_FAILURE(rv)) {
   2768         goto end;
   2769     }
   2770     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[60]]],
   2771                       REG_PORT_ANY, 0, 4);
   2772     if (BCM_FAILURE(rv)) {
   2773         goto end;
   2774     }
   2775     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[61]]],
   2776                       REG_PORT_ANY, 0, 0x14);
   2777     if (BCM_FAILURE(rv)) {
   2778         goto end;
   2779     }
   2780     /*****MMU reset End*****/
   2781 
   2782     /***** Resume ingress traffic Start*****/
   2783     /*1.Restore XMAC_RX_LSS_CTRL setting*/
   2784     BCM_PBMP_ITER(rx_lss_local_pbmp, port_iter){
   2785         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2786         if (BCM_FAILURE(rv)) {
   2787             goto end;
   2788         }
   2789         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0);
   2790         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2791         if (BCM_FAILURE(rv)) {
   2792             goto end;
   2793         }
   2794     }
   2795     BCM_PBMP_ITER(rx_lss_remote_pbmp, port_iter){
   2796         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2797         if (BCM_FAILURE(rv)) {
   2798             goto end;
   2799         }
   2800         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0);
   2801         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 0);
   2802         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2803         if (BCM_FAILURE(rv)) {
   2804             goto end;
   2805         }
   2806     }
   2807 
   2808     /*2.Restore MMU egress */
   2809     PBMP_PORT_ITER(unit, port_iter){
   2810         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egrmeteringconfig[port_iter]);
   2811         if (BCM_FAILURE(rv)) {
   2812             goto end;
   2813         }
   2814     }
   2815 
   2816     /*3.Disable PORT fast flush*/
   2817     PBMP_PORT_ITER(unit, port_iter){
   2818         rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter,
   2819                 DROP_ENf, 0);
   2820         if (BCM_FAILURE(rv)) {
   2821             goto end;
   2822         }
   2823     }
   2824     /*4.Disable IPMC fast flush  */
   2825     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2826     if (BCM_FAILURE(rv)) {
   2827         goto end;
   2828     }
   2829     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   2830     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2831     if (BCM_FAILURE(rv)) {
   2832         goto end;
   2833     }
   2834     /* 5.Restore pause settings*/
   2835     BCM_PBMP_ITER(pause_tx_pbmp, port_iter){
   2836         macd = PORT(unit, port_iter).p_mac;
   2837         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2838         if (BCM_FAILURE(rv)) {
   2839             goto end;
   2840         }
   2841         rv = MAC_PAUSE_SET(macd, unit, port_iter, 1, rval_1);
   2842         if (BCM_FAILURE(rv)) {
   2843             goto end;
   2844         }
   2845     }
   2846     BCM_PBMP_ITER(pause_rx_pbmp, port_iter){
   2847         macd = PORT(unit, port_iter).p_mac;
   2848         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2849         if (BCM_FAILURE(rv)) {
   2850             goto end;
   2851         }
   2852         rv = MAC_PAUSE_SET(macd, unit, port_iter, rval, 1);
   2853         if (BCM_FAILURE(rv)) {
   2854             goto end;
   2855         }
   2856     }
   2857     BCM_PBMP_ITER(tx_llfc_en_pbmp, port_iter){
   2858         macd = PORT(unit, port_iter).p_mac;
   2859         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 1);
   2860         if (BCM_FAILURE(rv)) {
   2861             goto end;
   2862         }
   2863     }
   2864     BCM_PBMP_ITER(rx_llfc_en_pbmp, port_iter){
   2865         macd = PORT(unit, port_iter).p_mac;
   2866         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 1);
   2867         if (BCM_FAILURE(rv)) {
   2868             goto end;
   2869         }
   2870     }
   2871     BCM_PBMP_ITER(tx_pfc_en_pbmp, port_iter){
   2872         macd = PORT(unit, port_iter).p_mac;
   2873         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 1);
   2874         if (BCM_FAILURE(rv)) {
   2875             goto end;
   2876         }
   2877     }
   2878     BCM_PBMP_ITER(rx_pfc_en_pbmp, port_iter){
   2879         macd = PORT(unit, port_iter).p_mac;
   2880         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 1);
   2881         if (BCM_FAILURE(rv)) {
   2882             goto end;
   2883         }
   2884     }
   2885     /* 6. Refresh FLOW CONTROL XOFF state*/
   2886     PBMP_PORT_ITER(unit, port_iter){
   2887         rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0xff);
   2888         if (BCM_FAILURE(rv)) {
   2889             goto end;
   2890         }
   2891         rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0);
   2892         if (BCM_FAILURE(rv)) {
   2893             goto end;
   2894         }
   2895     }
   2896     /*Wait until all EDATABUF FIFO count == 0 (Optional ?)*/
   2897     /*7.Do IBOD reset for all ports*/
   2898     rv = READ_IBOD_BOD_FIFO_CONTROLr(unit, &rval);
   2899     if (BCM_FAILURE(rv)) {
   2900         goto end;
   2901     }
   2902     soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 0);
   2903     rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval);
   2904     if (BCM_FAILURE(rv)) {
   2905         goto end;
   2906     }
   2907     soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 1);
   2908     rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval);
   2909     if (BCM_FAILURE(rv)) {
   2910         goto end;
   2911     }
   2912 
   2913     /*8. Restore EPC  link*/
   2914     rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&epc_lin_bmap_entry);
   2915     if (BCM_FAILURE(rv)) {
   2916         goto end;
   2917     }
   2918 
   2919     if (SOC_IS_HELIX4(unit)) {
   2920     /*9. Update txerrpkt after modules reset*/
   2921         PBMP_ITER(PBMP_XW_ALL(unit), port) {
   2922             rv = READ_TERRr(unit, port, &txerr);
   2923             if (SOC_FAILURE(rv)) {
   2924                 continue;
   2925             }
   2926             /* coverity[overrun-local : FALSE] */
   2927             ibod_ctrl->txerrpkt[port] = txerr;
   2928         }
   2929     }
   2930     else {
   2931         /*9. Update txerrpkt and tuflpkt after modules reset*/
   2932         PBMP_CL_ITER(unit, port_iter){
   2933             rv = READ_TERRr(unit, port_iter, &rval64);
   2934             if(BCM_FAILURE(rv)) {
   2935                 goto end;
   2936             }
   2937             COMPILER_64_SET(ibod_ctrl->txerrpkt[port_iter],
   2938                              COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2939             rv = READ_TUFLr(unit, port_iter, &rval64);
   2940             if(BCM_FAILURE(rv)) {
   2941                 goto end;
   2942             }
   2943             COMPILER_64_SET(ibod_ctrl->tuflpkt[port_iter],
   2944                              COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2945         }
   2946 
   2947         /* MAC RESET*/
   2948         PBMP_PORT_ITER(unit, port_iter){
   2949             SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port_iter, &rval64));
   2950             soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   2951             rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   2952             if (BCM_FAILURE(rv)) {
   2953                 goto end;
   2954             }
   2955             soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   2956             rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   2957             if (BCM_FAILURE(rv)) {
   2958                 goto end;
   2959             }
   2960         }
   2961     }
   2962 
   2963     /*10.Resume ingress traffic*/
   2964     BCM_PBMP_ITER(rx_en_pbmp, port_iter){
   2965         macd = PORT(unit, port_iter).p_mac;
   2966         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 1);
   2967         if (BCM_FAILURE(rv)) {
   2968             goto end;
   2969         }
   2970     }
   2971     /***** Resume ingress traffic End*****/
   2972 
   2973     /***** Enable software handling Start*****/
   2974     /*1.  Enable all back ground threads to prevent any SBUS acitivities (software handling)*/
   2975     rv = bcm_esw_linkscan_enable_set(unit, linkscan_interval);
   2976     if (BCM_FAILURE(rv)) {
   2977         goto end;
   2978     }
   2979     rv = soc_counter_start(unit, counter_flags, counter_interval, counter_pbmp);
   2980     if (BCM_FAILURE(rv)) {
   2981         goto end;
   2982     }
   2983     if (l2x_running) {
   2984         rv = soc_l2x_start(unit, l2x_flags, l2x_interval);
   2985         if (BCM_FAILURE(rv)) {
   2986             goto end;
   2987         }
   2988     }
   2989 #ifdef INCLUDE_MEM_SCAN
   2990     if (mem_scan_running) {
   2991         rv = soc_mem_scan_start(unit, scan_rate, scan_interval);
   2992         if (BCM_FAILURE(rv)) {
   2993             goto end;
   2994         }
   2995     }
   2996 #endif
   2997 
   2998 end:
   2999     /*2.  Enable "TX" API to prevent CPU packet from going into MMU (software handling)*/
   3000     PBMP_PORT_ITER(unit, port_iter){
   3001         _bcm_esw_ibod_recovery_port_unlock(unit, port_iter);
   3002     }
   3003 
   3004     /***** Enable software handling End*****/
   3005     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3006     ibod_ctrl->mmu_war_count++;
   3007     ibod_ctrl->mmu_avg_time= (ibod_ctrl->mmu_avg_time*(ibod_ctrl->mmu_war_count-1)
   3008                                 + time2 - time1) /ibod_ctrl->mmu_war_count;
   3009 
   3010     return rv;
   3011 }
   3012 
   3013 STATIC int
   3014 _bcm_tr3_mmu_check_and_recovery(_port_ibod_ctrl_t *ibod_ctrl)
   3015 {
   3016     int rv = BCM_E_NONE;
   3017     uint32 overflow0,overflow1;
   3018     int ibod_timeout_flag = 0;
   3019     int txerr_timeout_flag = 0;
   3020     int port_recovery_failed_flag = 0;
   3021     int unit = ibod_ctrl->unit;
   3022 
   3023     overflow0 = 0;
   3024     overflow1 = 0;
   3025 
   3026     rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   3027     if (SOC_FAILURE(rv)) {
   3028         LOG_ERROR(BSL_LS_BCM_PORT,
   3029                    (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0")));
   3030         return rv;
   3031     }
   3032     rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   3033     if (SOC_FAILURE(rv)) {
   3034         LOG_ERROR(BSL_LS_BCM_PORT,
   3035                    (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1")));
   3036         return rv;
   3037     }
   3038 
   3039     _soc_egress_drain_timeout_flag_get(unit, &ibod_timeout_flag);
   3040     txerr_timeout_flag = ibod_ctrl->drain_timeout_flag;
   3041     port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag;
   3042 
   3043     if ((overflow0 != 0) || (overflow1 != 0) || ibod_timeout_flag || txerr_timeout_flag
   3044         || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) {
   3045         rv = _bcm_tr3_mmu_recovery(ibod_ctrl);
   3046         if (txerr_timeout_flag) {
   3047             ibod_ctrl->drain_timeout_flag = 0;
   3048             ibod_ctrl->drain_timeout_count++;
   3049         }
   3050         if  (port_recovery_failed_flag) {
   3051             ibod_ctrl->port_recovery_failed_flag = 0;
   3052             ibod_ctrl->port_recovery_failed_count++;
   3053         }
   3054         if (ibod_timeout_flag) {
   3055             _soc_egress_drain_timeout_flag_set(unit, 0);
   3056             ibod_ctrl->egress_drain_timeout_count++;
   3057         }
   3058         if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) {
   3059             _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER);
   3060         }
   3061         if (SOC_FAILURE(rv)) {
   3062             LOG_ERROR(BSL_LS_BCM_PORT,
   3063                         (BSL_META_U(unit, "\n Error in MMU recovery ")));
   3064         }
   3065     }
   3066 
   3067     return rv;
   3068 }
   3069 
   3070 STATIC int
   3071 _bcm_tr3_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl,
   3072                                  bcm_port_t port)
   3073 {
   3074     bcm_pbmp_t pbmp;
   3075     uint32 rval;
   3076     uint64 rval64, txerr, tufl, flush_enable_pbm, tmp64;
   3077     uint64 egress_meter;
   3078     int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE;
   3079     pbmp_t      mask, mask1, mask1_restore, mask_restore;
   3080     soc_timeout_t timeout;
   3081     int txerr_status,tufl_status, underflow_status, lanes;
   3082     uint32 cur_cells, new_cells, mmu_cells,credit_set;
   3083     uint32 cdc_fifo_cells, tx_fifo_cells;
   3084     uint32 overflow0, overflow1, total_cell;
   3085     soc_info_t *si = &SOC_INFO(unit);
   3086     egr_mmu_requests_entry_t mmu_entry;
   3087     uint32 max_used_entry;
   3088 #ifdef TXERR_DEBUG
   3089     uint64 tpkt, tfcs;
   3090     uint32 ep_max_level = 0;
   3091 #endif
   3092     uint32 credit, mmu_req, ep_level;
   3093     int rx_llfc_en,rx_pfc_en,pause_rx, rx_lss, rx_lss_1;
   3094     soc_reg_t temp_reg_id;
   3095     static const soc_reg_t lls_port_credit_reg[] = {
   3096         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   3097         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   3098         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   3099         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   3100         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   3101         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   3102         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   3103         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   3104         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   3105         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   3106         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   3107         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   3108         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   3109         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   3110         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   3111         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   3112         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   3113         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   3114         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   3115         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   3116         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   3117     }; 
   3118     sal_usecs_t time1, time2;
   3119 
   3120     sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t));
   3121     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   3122     if (okay) {
   3123         SOC_PBMP_PORT_ADD(pbmp, port);
   3124     } else {
   3125         return SOC_E_NONE;
   3126     }
   3127 
   3128     txerr_status = 0;
   3129     /* check and update tx err counter */
   3130     SOC_IF_ERROR_RETURN(READ_TERRr(unit, port, &txerr));
   3131     if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port], txerr)) {
   3132        ibod_ctrl->txerrpkt[port] = txerr;
   3133        txerr_status = 1;
   3134     }
   3135 
   3136     tufl_status = 0;
   3137     /* check and update tx underflow counter */
   3138     SOC_IF_ERROR_RETURN(READ_TUFLr(unit, port, &tufl));
   3139     if (COMPILER_64_NE(ibod_ctrl->tuflpkt[port], tufl)) {
   3140        ibod_ctrl->tuflpkt[port] = tufl;
   3141        tufl_status = 1;
   3142     }
   3143     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_FIFO_STATUSr : XMAC_FIFO_STATUSr;
   3144     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, temp_reg_id, port, 0, &rval64));
   3145     underflow_status = soc_reg64_field32_get(unit, temp_reg_id, rval64, TX_PKT_UNDERFLOWf);
   3146 
   3147     /* check tx error and tx underflow */
   3148     if ((txerr_status == 0) && (tufl_status == 0) &&(underflow_status == 0) &&
   3149         (txerr_trigger_flag[port] == 0)) {
   3150         return SOC_E_NONE;
   3151     }
   3152 
   3153     if ((txerr_status != 0) || (tufl_status != 0) || (underflow_status != 0)) {
   3154         txerr_trigger_flag[port] = 1;
   3155     }
   3156     else if (txerr_trigger_flag[port] == 1) {
   3157         txerr_trigger_flag[port] = 0;
   3158     }
   3159 
   3160 #ifdef TXERR_DEBUG
   3161     cli_out("WAR TER Trigerred  [port %d]:txerr_status:%d, tufl_status:%d, underflow_status:%d\r\n",
   3162             port, txerr_status,  tufl_status, underflow_status);
   3163 #endif
   3164     rv = (soc_tr3_port_lanes_get(unit, port, &lanes));
   3165     if (BCM_FAILURE(rv)) {
   3166        return rv;
   3167     }
   3168 
   3169     switch (lanes) {
   3170     case 10: /* 100G */
   3171         si->port_credit[port] = 108;
   3172         break;
   3173     case 4: /* SINGLE  */
   3174         si->port_credit[port] = 36;
   3175         break;
   3176     case 2: /* DUAL */
   3177         si->port_credit[port] = 18;
   3178         break;
   3179     case 1: /* QUAD */
   3180         si->port_credit[port] = 9;
   3181         break;
   3182     default:
   3183         si->port_credit[port] = 36;
   3184         break;
   3185     }
   3186 
   3187     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3188 
   3189     _bcm_esw_lc_lock(unit);
   3190     soc_link_fwd_get(unit, &mask1);
   3191     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   3192     BCM_PBMP_PORT_REMOVE(mask1,port);
   3193     rv = soc_link_fwd_set(unit, mask1);
   3194     if (BCM_FAILURE(rv)) {
   3195         _bcm_esw_lc_unlock(unit);
   3196         LOG_ERROR(BSL_LS_BCM_PORT,
   3197                       (BSL_META_U(unit,"\n Error in setting the mask FWD"
   3198                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   3199         return BCM_E_NONE;
   3200     }
   3201 
   3202     PORT_LOCK(unit);
   3203     _bcm_esw_ibod_recovery_port_lock(unit, port);
   3204 
   3205     /* move port from EPC_LINK_BMAP */
   3206     soc_link_mask2_get(unit, &mask);
   3207     SOC_PBMP_ASSIGN(mask_restore,mask);
   3208     BCM_PBMP_PORT_REMOVE(mask,port);
   3209     rv = soc_link_mask2_set(unit, mask);
   3210     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3211 
   3212     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr;
   3213     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3214     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3215     pause_rx = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PAUSE_ENf);
   3216     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, 0);
   3217     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3218     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3219 
   3220     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr;
   3221     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3222     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3223     rx_pfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PFC_ENf);
   3224     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, 0);
   3225     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3226     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3227 
   3228     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr;
   3229     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3230     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3231     rx_llfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_LLFC_ENf);
   3232     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, 0);
   3233     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3234     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3235 
   3236     rv = READ_EGRMETERINGCONFIG_64r(unit, port, &rval64);
   3237     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3238     egress_meter = rval64;
   3239     COMPILER_64_ZERO(tmp64);
   3240     rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, tmp64);
   3241     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3242 
   3243     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr;
   3244     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3245     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3246     rx_lss = soc_reg64_field32_get(unit, temp_reg_id, rval64,
   3247                                    DROP_TX_DATA_ON_LOCAL_FAULTf);
   3248     rx_lss_1 = soc_reg64_field32_get(unit, temp_reg_id, rval64,
   3249                                    DROP_TX_DATA_ON_REMOTE_FAULTf);
   3250     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   3251     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   3252     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3253     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3254 
   3255     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   3256     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3257     COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]);
   3258     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm);
   3259     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   3260     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3261 
   3262     /* drop packets */
   3263     rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
   3264     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3265     soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   3266     rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
   3267     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3268 
   3269     cur_cells = 0xffffffff;
   3270     soc_timeout_init(&timeout, 30000, 0);
   3271 
   3272     while(1) {
   3273 #ifdef TXERR_DEBUG
   3274         /* check epc_link_bmap for debug */
   3275         pbmp_t  pbm;
   3276         epc_link_bmap_entry_t entry;
   3277         READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   3278         soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   3279         if (SOC_PBMP_MEMBER(pbm, port)) {
   3280             LOG_WARN(BSL_LS_BCM_PORT,
   3281                      (BSL_META_U(unit, "TXERR recovery:uint %d port %d still in epc link bitmap 0x%x\r\n"),
   3282                       unit, port, pbm.pbits[0]));
   3283         }
   3284 #endif
   3285         new_cells=0;
   3286 
   3287         /*1. check MMU cell */
   3288         rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &rval);
   3289         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3290         mmu_cells = soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   3291         new_cells += mmu_cells;
   3292 
   3293         /*2. check port CDC fifo */
   3294         rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port, &rval);
   3295         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3296         cdc_fifo_cells = soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   3297         new_cells += cdc_fifo_cells;
   3298 
   3299         /*3. check port tx fifo */
   3300         rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &rval);
   3301         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3302         tx_fifo_cells = soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   3303         new_cells += tx_fifo_cells;
   3304 
   3305         /* read MMU credit */
   3306         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3307         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3308 
   3309         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3310         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3311         mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3312 
   3313         /* read EP level */
   3314         rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   3315         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3316         soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   3317         rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   3318         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3319         rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry);
   3320         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3321         ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   3322 
   3323         /* Update cur_cells and give more time to drain packets.  */
   3324         if (new_cells < cur_cells) {
   3325             soc_timeout_init(&timeout, 30000, 0);
   3326             cur_cells = new_cells;
   3327         }
   3328         else {
   3329 #ifdef TXERR_DEBUG
   3330             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",
   3331                      new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req);
   3332 #endif
   3333             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]);
   3334             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3335         }
   3336 
   3337         if (soc_timeout_check(&timeout)) {
   3338             if(ep_level == 0) {
   3339                 ibod_ctrl->drain_timeout_flag = 1;
   3340             }
   3341             else {
   3342                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   3343                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3344                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   3345                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3346                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit,port, &total_cell);
   3347                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3348                 LOG_ERROR(BSL_LS_BCM_PORT,
   3349                           (BSL_META_U(unit, "\n TXERR recovery Timeout Drain packets %d PORT: %s, "
   3350                             "ep_level:%d, overflow0:%d, overflow1:%d total_cell %d "
   3351                             "credit %d mmu_req %d \n"),
   3352                             ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0,
   3353                             overflow1, total_cell, credit, mmu_req));
   3354             }
   3355             break;
   3356         }
   3357 #ifdef TXERR_DEBUG
   3358         /* for debug */
   3359         uint32 mmu_req_1;
   3360 
   3361         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3362         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3363         mmu_req_1 = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3364         if(mmu_req_1 != mmu_req){
   3365             cli_out("TXERR recovery: credit %d mmu_req %d is not equal mmu_req_1 %d  !!!!!\r\n",credit, mmu_req, mmu_req_1);
   3366 
   3367         }
   3368 #endif
   3369         /* All packets were drained */
   3370         if (new_cells == 0) {
   3371             if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3372                 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3373                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3374             }
   3375 #ifdef TXERR_DEBUG
   3376             rv = _soc_egress_drain_ep_max_level_get(unit, port, &ep_max_level);
   3377             if(rv == BCM_E_NONE)
   3378             {
   3379                  cli_out("TXERR recovery: MacDrainOK max_level %d  !!!!!\r\n", ep_max_level);
   3380             }
   3381 
   3382             rv = READ_TPKTr(unit, port, &tpkt);
   3383             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3384             rv = READ_TFCSr(unit, port, &tfcs);
   3385             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3386 
   3387             cli_out("TXERR recovery: MacDrainOK credit = %d, Port:%d, tpkt:%lld, tfcs=%lld\r\n",  credit, port, tpkt, tfcs);
   3388 #endif
   3389             rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3390             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3391             if(credit == 0) {
   3392                 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]],
   3393                     REG_PORT_ANY, 0, si->port_credit[port]);
   3394                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3395             }
   3396             break;
   3397         }
   3398         else if (mmu_cells){  /* some packets still stay in MMU */
   3399             if((credit == 0)) {
   3400                 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3401                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3402                 if(credit == 0) {
   3403                     rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3404                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3405                     mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3406 
   3407                     if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3408                         rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3409                         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3410                     }
   3411                 }
   3412                 else {
   3413 #ifdef TXERR_DEBUG
   3414                     _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3415 #endif
   3416                 }
   3417             }
   3418             else {
   3419 #ifdef TXERR_DEBUG
   3420                 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3421 #endif
   3422             }
   3423         }
   3424     }
   3425 
   3426     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_CLEAR_FIFO_STATUSr : XMAC_CLEAR_FIFO_STATUSr;
   3427     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3428     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3429     soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   3430     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3431     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3432 
   3433     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3434     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3435     soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   3436     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3437     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3438 
   3439     rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, egress_meter);
   3440     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3441 
   3442     rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
   3443     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3444     soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   3445     rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
   3446     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3447 
   3448     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   3449     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3450     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   3451     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   3452     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3453 
   3454     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr;
   3455     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3456     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3457     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss);
   3458     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1);
   3459     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3460     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3461 
   3462     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr;
   3463     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3464     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3465     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, pause_rx);
   3466     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3467     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3468 
   3469     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr;
   3470     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3471     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3472     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, rx_pfc_en);
   3473     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3474     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3475 
   3476     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr;
   3477     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3478     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3479     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, rx_llfc_en);
   3480     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3481     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3482 
   3483     /* restore port from EPC_LINK_BMAP */
   3484     rv = soc_link_mask2_set(unit, mask_restore);
   3485     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3486 
   3487     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3488     PORT_UNLOCK(unit);
   3489     rv = soc_link_fwd_set(unit, mask1_restore);
   3490     if (BCM_FAILURE(rv)) {
   3491         _bcm_esw_lc_unlock(unit);
   3492         LOG_ERROR(BSL_LS_BCM_PORT,
   3493                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   3494                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   3495         return BCM_E_NONE;
   3496     }
   3497 
   3498     _bcm_esw_lc_unlock(unit);
   3499 
   3500     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3501     ibod_ctrl->txerr_count++;
   3502     ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) +
   3503             time2 - time1) /ibod_ctrl->txerr_count;
   3504 
   3505     return SOC_E_NONE;
   3506 }
   3507 
   3508 STATIC int
   3509 _bcm_tr3_ibod_port_check(
   3510 _port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port, int *need_recovery)
   3511 {
   3512     int rv, unit = ibod_ctrl->unit;
   3513     uint64 rrpkt, rrbyt;
   3514     uint64 rrpkt_diff, rrbyt_diff;
   3515     uint64 rval64;
   3516     int runt_threshold;
   3517 
   3518     /* Only check HG port */
   3519     if (!IS_HG_PORT(unit, port)) {
   3520         return BCM_E_NONE;
   3521     }
   3522 
   3523     /* Check if any new runt packet logged in RRPKT */
   3524     rv = READ_RRPKTr(unit, port, &rrpkt);
   3525     if (SOC_FAILURE(rv)) {
   3526         return BCM_E_FAIL;
   3527     }
   3528     if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   3529         return BCM_E_NONE;
   3530     }
   3531 
   3532     /* Check total runt byte count */
   3533     rv = READ_RRBYTr(unit, port, &rrbyt);
   3534     if (SOC_FAILURE(rv)) {
   3535         return BCM_E_FAIL;
   3536     }
   3537 
   3538     /* It's very unlikely both packet and byte counters wrap around
   3539                * and stop at 0, the code assume this is from clear counter */
   3540     if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   3541         ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port];
   3542         ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port];
   3543         ibod_ctrl->rrpkt[port] = rrpkt;
   3544         ibod_ctrl->rrbyt[port] = rrbyt;
   3545         return BCM_E_NONE;
   3546     }
   3547 
   3548     rrpkt_diff = rrpkt;
   3549     rrbyt_diff = rrbyt;
   3550     COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   3551     COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   3552     ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port];
   3553     ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port];
   3554     ibod_ctrl->rrpkt[port] = rrpkt;
   3555     ibod_ctrl->rrbyt[port] = rrbyt;
   3556 #ifdef IBOD_DEBUG
   3557     cli_out("WAR IBOD Check [port %d] rrbyt %lld rrpkt %lld, rrpkt_diff %lld rrbyt_diff %lld\r\n",
   3558             port, ibod_ctrl->rrbyt[port], ibod_ctrl->rrpkt[port], rrpkt_diff, rrbyt_diff);
   3559 #endif
   3560     rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   3561     if (SOC_FAILURE(rv)) {
   3562         return BCM_E_FAIL;
   3563     }
   3564 
   3565     runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   3566 
   3567     /* Recovery is needed only for packet size between 33 and threshold */
   3568     if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   3569         COMPILER_64_LO(rrpkt_diff) == 1) {
   3570         if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   3571             return BCM_E_NONE;
   3572         }
   3573     }
   3574     if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   3575         COMPILER_64_LO(rrbyt_diff) <= 32) {
   3576         return BCM_E_NONE;
   3577     }
   3578 
   3579     *need_recovery = TRUE;
   3580 
   3581     return BCM_E_NONE;
   3582 }
   3583 
   3584 STATIC int
   3585 _bcm_tr3_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_set,
   3586                                  bcm_port_t port)
   3587 {
   3588     int idx, fifo_len, send_time;
   3589     int rv = BCM_E_NONE;
   3590     int rv1 = BCM_E_NONE;
   3591     int enable, tdm_length;
   3592     uint64 rrpkt, rrbyt;
   3593     uint64 rpkt, tpkt;
   3594     pbmp_t  pbm;
   3595     epc_link_bmap_entry_t entry;
   3596     int lanes, unit = ibod_ctrl->unit;
   3597     soc_info_t *si = &SOC_INFO(unit);
   3598     int phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3599     uint32 *tdm_array;
   3600     int port_dis_tag=0, port_dis_untag=0;
   3601     bcm_pkt_t *pkt = &ibod_ctrl->pkt;
   3602     SHR_BITDCLNAME(used_bmp, TR3_IARB_TDM_TABLE_LENGTH);
   3603     uint32 _tdm_array_hw[380] = {-1};
   3604     int pause_tx, pause_rx, pfc_rx, llfc_rx;
   3605     iarb_tdm_table_entry_t new_entry;
   3606     uint32 rval;
   3607     pbmp_t mask, mask1, mask1_restore;
   3608     int ibod_data_fifo_full_intr_status = 0;
   3609     soc_field_t cl_data_fifo_full_err_intr_status = 0;
   3610     soc_field_t cl_ctrl_fifo_full_err_intr_status = 0;
   3611 #ifdef IBOD_DEBUG
   3612     uint64 rpkt, tpkt;
   3613     uint64 rpkt_fin, tpkt_fin, rrpkt_fin, rrbyt_fin;
   3614 #endif
   3615 
   3616     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3617     rv = (soc_tr3_port_lanes_get(unit, port, &lanes));
   3618     if (BCM_FAILURE(rv)) {
   3619        return rv;
   3620     }
   3621 
   3622     switch (lanes) {
   3623     case 10: /* 100G */
   3624         fifo_len = 34;
   3625         si->port_credit[port] = 108;
   3626         break;
   3627     case 4: /* SINGLE  */
   3628         fifo_len = 34;
   3629         si->port_credit[port] = 36;
   3630         break;
   3631     case 2: /* DUAL */
   3632         fifo_len = 34;
   3633         si->port_credit[port] = 18;
   3634         break;
   3635     case 1: /* QUAD */
   3636         fifo_len = 34;
   3637         si->port_credit[port] = 9;
   3638         break;
   3639     default:
   3640         fifo_len = 34;
   3641         si->port_credit[port] = 36;
   3642         break;
   3643     }
   3644 
   3645     
   3646     if ((phy_port >= 53)  && (phy_port <= 64 )){
   3647         cl_data_fifo_full_err_intr_status = CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf;
   3648         cl_ctrl_fifo_full_err_intr_status = CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf;
   3649     }
   3650     else if ((phy_port >= 69) && (phy_port <= 80)) {
   3651         cl_data_fifo_full_err_intr_status = CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf;
   3652         cl_ctrl_fifo_full_err_intr_status = CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf;
   3653     }
   3654     else {
   3655         LOG_ERROR(BSL_LS_BCM_PORT,
   3656                  (BSL_META_U(unit, "IBOD port:%d is not CL port\n\r"), port));
   3657         return BCM_E_PORT;
   3658     }
   3659     fifo_len = soc_property_get(unit, "ibod_fifo_len", fifo_len);
   3660 
   3661     soc_link_fwd_get(unit, &mask1);
   3662     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   3663     BCM_PBMP_PORT_REMOVE(mask1,port);
   3664     rv = soc_link_fwd_set(unit, mask1);
   3665     if (BCM_FAILURE(rv)) {
   3666        LOG_ERROR(BSL_LS_BCM_PORT,
   3667                  (BSL_META_U(unit,
   3668                   "IBOD Link fwd set failed[%d] on port:%d\n\r"),
   3669                   rv, port));
   3670        return rv;
   3671     }
   3672 
   3673     PORT_LOCK(unit); /* Begin port atomic */
   3674     _bcm_esw_ibod_recovery_port_lock(unit, port);
   3675     soc_ibod_recovery_in_progress_set(unit, 1);
   3676 
   3677     if (port_set == 0) {
   3678         soc_link_mask2_get(unit, &mask);
   3679         rv = bcm_esw_port_enable_get(unit, port, &enable);
   3680         IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3681         /* port is disabled */
   3682         if ((enable == 0) || !SOC_PBMP_MEMBER(mask, port)) {
   3683             soc_ibod_recovery_in_progress_set(unit, 0);
   3684             _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3685             PORT_UNLOCK(unit);
   3686             rv = soc_link_fwd_set(unit, mask1_restore);
   3687             /*
   3688              *  Since the recovery is not run when the port is down the
   3689              *  rrpkt is updated back to the original value, as the
   3690              *  recovery will happen when the port is up
   3691              */
   3692             ibod_ctrl->rrpkt[port] = ibod_ctrl->rrpkt_old[port];
   3693             ibod_ctrl->rrbyt[port] = ibod_ctrl->rrbyt_old[port];
   3694             LOG_INFO(BSL_LS_BCM_PORT,
   3695                       (BSL_META_U(unit,
   3696                                   "Skip ibod sync war if port %d is disabled %d.\n"),
   3697                                   port, enable));
   3698             return rv;
   3699         }
   3700     }
   3701 
   3702     /* Isolate port */
   3703     rv = _bcm_tr3_ibod_port_isolate(unit, port_set, port, &port_dis_untag, &port_dis_tag);
   3704     if (BCM_FAILURE(rv)) {
   3705         soc_ibod_recovery_in_progress_set(unit, 0);
   3706         _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3707         PORT_UNLOCK(unit);
   3708         rv1 = soc_link_fwd_set(unit, mask1_restore);
   3709         LOG_ERROR(BSL_LS_BCM_PORT,
   3710                   (BSL_META_U(unit, "IBOD port(%d) isolate Failed[%d %d]\n\r"),
   3711                    port, rv, rv1));
   3712         return rv;
   3713     }
   3714 
   3715     sal_memset(&used_bmp, 0, sizeof(used_bmp));
   3716 
   3717     /* Remove the port from IARB_TDM_TABLE */
   3718     tdm_length = _soc_tr3_tdm_size;
   3719     for (idx = 0; idx < _soc_tr3_tdm_size; idx++) {
   3720         /*    coverity[unchecked_value]    */
   3721         (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry);
   3722         _tdm_array_hw[idx] =
   3723               soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf);
   3724     }
   3725     tdm_array = _tdm_array_hw;
   3726 
   3727     sal_memset(&new_entry, 0, sizeof(iarb_tdm_table_entry_t));
   3728     soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 127);
   3729     for (idx = 0; idx < _soc_tr3_tdm_size; idx++) {
   3730         if (tdm_array[idx] != phy_port) {
   3731             continue;
   3732         }
   3733         (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,
   3734                             &new_entry);
   3735         SHR_BITSET(used_bmp, idx);
   3736     }
   3737     sal_udelay(10000);
   3738 
   3739     /* Disable pause/pfc/llfc function */
   3740     rv = soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx);
   3741     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3742 
   3743     rv = soc_mac_x.md_pause_set(unit, port, 0, 0);
   3744     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3745 
   3746     rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, &pfc_rx);
   3747     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3748 
   3749     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0);
   3750     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3751 
   3752     rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,&llfc_rx);
   3753     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3754 
   3755     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,0);
   3756     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3757 
   3758     /* check epc_link_bmap */
   3759     /* coverity[check_return] */
   3760     READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   3761     soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   3762     if (SOC_PBMP_MEMBER(pbm, port)) {
   3763         LOG_WARN(BSL_LS_BCM_PORT,
   3764                   (BSL_META_U(unit, "uint %d port %d still in epc link bitmap 0x%x\r\n"),
   3765                    unit, port, pbm.pbits[0]));
   3766     }
   3767 
   3768     rv = READ_RRBYTr(unit, port, &rrbyt);
   3769     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3770 
   3771     rv = READ_RRPKTr(unit, port, &rrpkt);
   3772     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3773 
   3774     rv = READ_RPKTr(unit, port, &rpkt);
   3775     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3776     rv = READ_TPKTr(unit, port, &tpkt);
   3777     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3778 #ifdef IBOD_DEBUG
   3779     cli_out("WAR Trigerred IBOD recovery [port %d] enable %d orign rrbyt %lld rrpkt %lld rpkt %lld tpkt %lld\r\n",
   3780         port, port_set, rrbyt, rrpkt, rpkt, tpkt );
   3781 #endif
   3782     send_time = 0;
   3783 
   3784     /* send loopback packets untill fifo full error occurred. */
   3785     do {
   3786         /* Send 80-byte packets to fill IBOD FIFO */
   3787         for (idx = 0; idx < fifo_len; idx++) {
   3788             BCM_PKT_TX_LEN_SET(pkt, 68);
   3789             BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   3790             BCM_PKT_HGHDR_REQUIRE(pkt);
   3791             rv = bcm_common_tx(unit, pkt, NULL);
   3792             if (BCM_FAILURE(rv)) {
   3793                 LOG_ERROR(BSL_LS_BCM_PORT,
   3794                           (BSL_META_U(unit, "IBOD 80-byte packet transmit"
   3795                            " failed[%d] on port:%d, send_time:%d\n\r"), rv, port, send_time));
   3796                 ibod_ctrl->port_recovery_failed_flag = 1;
   3797                 break;
   3798             }
   3799         }
   3800         if (ibod_ctrl->port_recovery_failed_flag) {
   3801             break;
   3802         }
   3803 
   3804         send_time ++;
   3805         rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   3806         IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3807         ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3808              rval, cl_data_fifo_full_err_intr_status);
   3809 #ifdef IBOD_DEBUG
   3810         if (!ibod_data_fifo_full_intr_status){
   3811             cli_out("%s IBOD intr data fifo full err status is 0 !!!!!!!%d\r\n",
   3812             (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status);
   3813         }
   3814 #endif
   3815 
   3816         if (send_time >= 5) {
   3817 #ifdef IBOD_DEBUG
   3818             int lb = 0;
   3819             MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &lb);
   3820 
   3821             rv = READ_RPKTr(unit, port, &rpkt_fin);
   3822             IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3823             rv = READ_TPKTr(unit, port, &tpkt_fin);
   3824             IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3825 
   3826             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"),
   3827                       ibod_ctrl->unit, SOC_PORT_NAME(unit,port),rpkt_fin,tpkt_fin, lb));
   3828 #else
   3829             LOG_ERROR(BSL_LS_BCM_PORT,
   3830                   (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed\r\n"),
   3831                   unit, SOC_PORT_NAME(unit,port)));
   3832 #endif
   3833            ibod_ctrl->port_recovery_failed_flag = 1;
   3834            break;
   3835         }
   3836     }while (ibod_data_fifo_full_intr_status == 0);
   3837 
   3838 #ifdef IBOD_DEBUG
   3839     rv = READ_RRBYTr(unit, port, &rrbyt);
   3840     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3841 
   3842     rv = READ_RRPKTr(unit, port, &rrpkt);
   3843     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3844 
   3845     rv = READ_RPKTr(unit, port, &rpkt_fin);
   3846     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3847 
   3848     rv = READ_TPKTr(unit, port, &tpkt_fin);
   3849     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3850     cli_out("WAR Trigerred IBOD recovery [port %d] normal rrbyt %lld rrpkt %lld rpkt_fin %lld tpkt_fin %lld send_time %d\r\n",
   3851         port, rrbyt, rrpkt, rpkt_fin,tpkt_fin, send_time);
   3852     if((rpkt_fin - rpkt) != fifo_len * send_time ) {
   3853         cli_out("IBOD recovery loopback regular counter is not right!!!!!!! \r\n");
   3854         if((rpkt_fin - rpkt) < fifo_len * send_time ) {
   3855             cli_out("IBOD recovery loopback regular counter is less than tx!!!!!!!! \r\n");
   3856         }
   3857     }
   3858 #endif
   3859     /* Restore IARB_TDM_TABLE */
   3860     soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf,
   3861                         phy_port);
   3862     for (idx = 0; idx < tdm_length; idx++) {
   3863         if (!SHR_BITGET(used_bmp, idx)) {
   3864             continue;
   3865         }
   3866         (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,
   3867                             &new_entry);
   3868     }
   3869 
   3870     for (idx = 0; idx < tdm_length; idx++) {
   3871         if (tdm_array[idx] != phy_port) {
   3872             continue;
   3873         }
   3874 #ifdef IBOD_DEBUG
   3875         (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry);
   3876         _tdm_array_hw[idx] = soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf);
   3877         if(_tdm_array_hw[idx] != phy_port){
   3878             cli_out("IBOD IARB TDM port number idx %d _tdm_array_hw[idx] %d !!!!!!\r\n",idx, _tdm_array_hw[idx]);
   3879         }
   3880 #endif
   3881     }
   3882     /* waiting for IARB_TDM_TABLE ready */
   3883     sal_udelay(30000);
   3884     /* Send 72-byte RUNT packet */
   3885     if (BCM_SUCCESS(rv)) {
   3886         BCM_PKT_TX_LEN_SET(pkt, 60);
   3887         BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   3888         rv = bcm_common_tx(unit, pkt, NULL);
   3889         if (BCM_FAILURE(rv)) {
   3890             LOG_ERROR(BSL_LS_BCM_PORT,
   3891                       (BSL_META_U(unit,
   3892                        "IBOD Runt Pkt transmit failed[%d] on port:%d\n\r"),
   3893                        rv, port));
   3894             ibod_ctrl->port_recovery_failed_flag = 1;
   3895         }
   3896     }
   3897 
   3898 #ifdef IBOD_DEBUG
   3899     rv = READ_RRPKTr(unit, port, &rrpkt_fin);
   3900     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3901     rv = READ_RRBYTr(unit, port, &rrbyt_fin);
   3902     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3903     rv = READ_RPKTr(unit, port, &rpkt_fin);
   3904     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3905     rv = READ_TPKTr(unit, port, &tpkt_fin);
   3906     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3907 
   3908     cli_out("recovery runt rrbyt_fin %lld rrpkt_fin %lld rpkt_fin %lld tpkt_fin %lld\r\n",rrbyt_fin, rrpkt_fin,
   3909     rpkt_fin, tpkt_fin);
   3910 
   3911     if((rrpkt_fin - rrpkt) != 1 ) {
   3912         cli_out("IBOD recovery loopback runt counter is not right!!!! \r\n");
   3913     }
   3914 #endif
   3915     /* Update ibod_ctrl rrbyt and rrpkt */
   3916     rv = READ_RRPKTr(unit, port, &rrpkt);
   3917     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3918     rv = READ_RRBYTr(unit, port, &rrbyt);
   3919     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3920 
   3921     ibod_ctrl->rrpkt[port] = rrpkt;
   3922     ibod_ctrl->rrbyt[port] = rrbyt;
   3923 
   3924     /* Restore original pause/pfc/llfc configuration */
   3925     rv = soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx);
   3926     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3927 
   3928     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, pfc_rx);
   3929     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3930     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,llfc_rx);
   3931     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3932 
   3933     /* clear and check IBOD FIFO full interrupt */
   3934     rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   3935     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3936     ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3937          rval, cl_data_fifo_full_err_intr_status);
   3938     soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   3939          &rval, cl_data_fifo_full_err_intr_status, 1);
   3940     soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   3941          &rval, cl_ctrl_fifo_full_err_intr_status, 1);
   3942     rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   3943     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3944 #ifdef IBOD_DEBUG
   3945     READ_IBOD_INTR_STATUSr(unit, &rval);
   3946     ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3947          rval, cl_data_fifo_full_err_intr_status);
   3948     cli_out("after set. %s IBOD intr data fifo full err status %d\r\n",
   3949         (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status);
   3950 #endif
   3951     /* Restore port operation */
   3952     rv = _bcm_tr3_ibod_port_resume(unit, port, port_dis_untag, port_dis_tag);
   3953     if (BCM_FAILURE(rv)) {
   3954         soc_ibod_recovery_in_progress_set(unit, 0);
   3955         _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3956         PORT_UNLOCK(unit);
   3957         rv1 = soc_link_fwd_set(unit, mask1_restore);
   3958         LOG_ERROR(BSL_LS_BCM_PORT,
   3959                   (BSL_META_U(unit,
   3960                   "IBOD Port[%d] Resume failed[%d %d]\n\r"), port, rv, rv1));
   3961         return rv;
   3962     }
   3963 
   3964     soc_ibod_recovery_in_progress_set(unit, 0);
   3965     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3966     PORT_UNLOCK(unit); /* End port atomic */
   3967 
   3968     rv = soc_link_fwd_set(unit, mask1_restore);
   3969     if (BCM_FAILURE(rv)) {
   3970        LOG_ERROR(BSL_LS_BCM_PORT,
   3971                  (BSL_META_U(unit,
   3972                  "IBOD link fwd set failed[%d] on port:%d\n\r"), rv, port));
   3973        return rv;
   3974     }
   3975 
   3976     return rv;
   3977 }
   3978 
   3979 STATIC int
   3980 _bcm_tr3_ibod_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port)
   3981 {
   3982     int rv = BCM_E_NONE;
   3983     int need_recovery = FALSE;
   3984     sal_usecs_t time1, time2;
   3985 
   3986     /* Check and update runt counter */
   3987     rv = _bcm_tr3_ibod_port_check(ibod_ctrl, port, &need_recovery);
   3988     if (BCM_FAILURE(rv)) {
   3989         LOG_ERROR(BSL_LS_BCM_PORT,
   3990                       (BSL_META_U(ibod_ctrl->unit,
   3991                                   "Ibod recovery port %d check error\n"), port));
   3992        return rv;
   3993     }
   3994     else if(need_recovery == FALSE){
   3995         return BCM_E_NONE;
   3996     }
   3997 
   3998     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3999 
   4000     rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 0, port);
   4001 
   4002     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   4003     ibod_ctrl->event_count++;
   4004     ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count-1) +
   4005             time2 - time1) /ibod_ctrl->event_count;
   4006 
   4007     return rv;
   4008 }
   4009 
   4010 STATIC void
   4011 _bcm_tr3_ibod_sync_recovery_thread(void *context)
   4012 {
   4013     _port_ibod_ctrl_t *ibod_ctrl = context;
   4014     int port, rv, unit = ibod_ctrl->unit;
   4015 
   4016     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4017                 (BSL_META_U(unit,
   4018                             "IBOD recovery started on unit %d\n"), ibod_ctrl->unit));
   4019 
   4020     ibod_ctrl->running = 1;
   4021     while (!ibod_ctrl->stop) {
   4022         if (!SOC_IS_DONE_INIT(unit)) {
   4023             (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4024             continue;
   4025         }
   4026         /* Need to wait until warmboot recovery of ibod related stats is done */
   4027         if (!SOC_WARM_BOOT(unit)) {
   4028             PBMP_CL_ITER(unit, port) {
   4029                 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   4030                     continue;
   4031                 }
   4032                 ibod_ctrl->start_time = sal_time_usecs();
   4033                 if(!IS_C_PORT(unit, port)) {
   4034                     (void)_bcm_tr3_ibod_recovery_port(ibod_ctrl, port);
   4035                 }
   4036 
   4037                 rv = _bcm_tr3_txerr_recovery_port(ibod_ctrl, port);
   4038                 if (SOC_FAILURE(rv)) {
   4039                     LOG_ERROR(BSL_LS_BCM_PORT,
   4040                                  (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,port)));
   4041                 }
   4042             }
   4043 
   4044             rv = _bcm_tr3_mmu_check_and_recovery(ibod_ctrl);
   4045             if (SOC_FAILURE(rv)) {
   4046                 LOG_ERROR(BSL_LS_BCM_PORT,
   4047                     (BSL_META_U(unit, "\n Error in MMU recovery ")));
   4048             }
   4049 
   4050         }
   4051         (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4052     }
   4053     ibod_ctrl->running = 0;
   4054 }
   4055 
   4056 STATIC void
   4057 _bcm_hx4_ibod_sync_recovery_thread(void *context)
   4058 {
   4059     _port_ibod_ctrl_t *ibod_ctrl = context;
   4060     int port, flex_port=0, rv, unit = ibod_ctrl->unit;
   4061     uint64 rrpkt, rrbyt;
   4062     uint64 rrpkt_diff, rrbyt_diff;
   4063     uint32 rval,rval_1,port_mode=0,encap_mode=0,next_flex_port=0;
   4064     int port_group_iter;
   4065     int flex_port_arr[3]={-1,-1,-1},cou,i;
   4066     uint64 rval64;
   4067     int runt_threshold;
   4068     uint64 txerr;
   4069     int egress_drain_timeout, port_drain_timeout, port_recovery_failed_flag;
   4070 
   4071     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4072                 (BSL_META_U(unit, "IBOD recovery started on unit %d\n"),ibod_ctrl->unit));
   4073 
   4074     cou=0;
   4075     PBMP_ITER(PBMP_XW_ALL(unit), port) {
   4076         (void) READ_PORT_MODE_REGr(unit, port, &rval);
   4077         port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   4078                                     rval, XPORT0_CORE_PORT_MODEf);
   4079 
   4080         if (port_mode != 3) {
   4081             /* coverity[overrun-call : FALSE] */
   4082             if (_bcm_tr3_port_is_control_port(unit, port)) {
   4083                 flex_port_arr[cou] = port;
   4084                 cou++;
   4085             }
   4086         }
   4087         rv = READ_RRPKTr(unit, port, &rrpkt);
   4088         if (SOC_FAILURE(rv)) {
   4089            LOG_ERROR(BSL_LS_BCM_PORT,
   4090                          (BSL_META_U(unit, "Error in reading RRPKTr %d\n"),ibod_ctrl->unit));
   4091 
   4092         }
   4093 
   4094         rv = READ_RRBYTr(unit, port, &rrbyt);
   4095         if (SOC_FAILURE(rv)) {
   4096            LOG_ERROR(BSL_LS_BCM_PORT,
   4097                          (BSL_META_U(unit, "Error in reading RRBYTr %d\n"),ibod_ctrl->unit));
   4098         }
   4099         /* coverity[overrun-local : FALSE] */
   4100         ibod_ctrl->rrpkt[port] = rrpkt;
   4101         /* coverity[overrun-local : FALSE] */
   4102         ibod_ctrl->rrbyt[port] = rrbyt;
   4103     }
   4104 
   4105     ibod_ctrl->running = 1;
   4106     while (!ibod_ctrl->stop) {
   4107         if (!SOC_IS_DONE_INIT(unit)) {
   4108             (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4109             continue;
   4110         }
   4111         /* Need to wait until warmboot recovery of ibod related stats is done */
   4112         if (!SOC_WARM_BOOT(unit)) {
   4113             next_flex_port=0;
   4114             port_group_iter=-1;
   4115             PBMP_ITER(PBMP_XW_ALL(unit), port) {
   4116                 if (!((IS_HG_PORT(unit,port)) || (IS_XE_PORT(unit,port)))) {
   4117                     continue;
   4118                 }
   4119                 /* coverity[overrun-local : FALSE] */
   4120                 if (SOC_INFO(unit).port_speed_max[port] >= 100000) {
   4121                     continue;
   4122                 }
   4123                 ibod_ctrl->start_time = sal_time_usecs();
   4124                 /* coverity[overrun-call : FALSE] */
   4125                 if (_bcm_tr3_port_is_control_port(unit, port)) {
   4126                     flex_port=port;
   4127                     next_flex_port=0;
   4128                     port_group_iter++;
   4129                 }
   4130                 if (next_flex_port) {
   4131                     continue;
   4132                 }
   4133                 (void) READ_PORT_EHG_RX_CONTROLr(unit, port, &rval);
   4134                 encap_mode = soc_reg_field_get(unit, PORT_EHG_RX_CONTROLr,
   4135                                             rval, MODEf);
   4136                 if (encap_mode) {
   4137                     (void) READ_PORT_EHG_RX_PKT_DROPr(unit, port, &rval);
   4138                     if (rval) {
   4139                         LOG_VERBOSE(BSL_LS_BCM_PORT,
   4140                                      (BSL_META_U(unit, "\n WAR Trigerred by Embedded HG RX control")));
   4141                         rv = BCM_E_NONE;
   4142                         /* coverity[overrun-call : FALSE] */
   4143                         rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4144                         if (SOC_FAILURE(rv)) {
   4145                             PORT_UNLOCK(unit);
   4146                             /* Release the ibod recovery port group lock */
   4147                             /* coverity[overrun-call : FALSE] */
   4148                             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4149                             _bcm_esw_lc_unlock(unit);
   4150                             LOG_ERROR(BSL_LS_BCM_PORT,
   4151                                      (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4152                         }
   4153                         soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0);
   4154                         for (i=0; i<3; i++) {
   4155                         if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) {
   4156                              rv = BCM_E_NONE;
   4157                              rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]);
   4158                              if (SOC_FAILURE(rv)) {
   4159                                  PORT_UNLOCK(unit);
   4160                                  /* Release the ibod recovery port group lock */
   4161                                 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]);
   4162                                  _bcm_esw_lc_unlock(unit);
   4163                                  LOG_ERROR(BSL_LS_BCM_PORT,
   4164                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i])));
   4165                              }
   4166                             }
   4167                         }
   4168                         next_flex_port=1;
   4169                         continue;
   4170                     }
   4171                 }
   4172 
   4173                 rv = READ_TERRr(unit, port, &txerr);
   4174                 if (SOC_FAILURE(rv)) {
   4175                     continue;
   4176                 }
   4177                 /* coverity[overrun-local : FALSE] */
   4178                 if (COMPILER_64_NE(txerr, ibod_ctrl->txerrpkt[port])) {
   4179                     /* coverity[overrun-call : FALSE] */
   4180                     rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port);
   4181                     if (SOC_FAILURE(rv)) {
   4182                         PORT_UNLOCK(unit);
   4183                         /* Release the ibod recovery port group lock */
   4184                         /* coverity[overrun-call : FALSE] */
   4185                         _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4186                         _bcm_esw_lc_unlock(unit);
   4187                         LOG_ERROR(BSL_LS_BCM_PORT,
   4188                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4189                     }
   4190                 }
   4191                 /* Check if any new runt packet logged in RRPKT */
   4192                 rv = READ_RRPKTr(unit, port, &rrpkt);
   4193                 if (SOC_FAILURE(rv)) {
   4194                     continue;
   4195                 }
   4196                 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   4197                     continue;
   4198                 }
   4199                 /* Check total runt byte count */
   4200                 rv = READ_RRBYTr(unit, port, &rrbyt);
   4201                 if (SOC_FAILURE(rv)) {
   4202                     continue;
   4203                 }
   4204 
   4205                 /* It's very unlikely both packet and byte counters wrap around
   4206                  * and stop at 0, the code assume this is from clear counter */
   4207                 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   4208                     ibod_ctrl->rrpkt[port] = rrpkt;
   4209                     ibod_ctrl->rrbyt[port] = rrbyt;
   4210                     continue;
   4211                 }
   4212 
   4213                 rrpkt_diff = rrpkt;
   4214                 rrbyt_diff = rrbyt;
   4215                 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   4216                 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   4217                 ibod_ctrl->rrpkt[port] = rrpkt;
   4218                 ibod_ctrl->rrbyt[port] = rrbyt;
   4219 
   4220                 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   4221                 if (SOC_FAILURE(rv)) {
   4222                     continue;
   4223                 }
   4224                 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   4225 
   4226                 /* Recovery is needed only for packet size between 33 and 76 */
   4227                 if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   4228                     COMPILER_64_LO(rrpkt_diff) == 1) {
   4229                     if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   4230                         continue;
   4231                     }
   4232                 }
   4233                 if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   4234                     COMPILER_64_LO(rrbyt_diff) <= 32) {
   4235                     continue;
   4236                 }
   4237                 LOG_VERBOSE(BSL_LS_BCM_PORT,
   4238                       (BSL_META_U(unit,"\n WAR Trigerred by RRPKT/RRBYT")));
   4239                 /* coverity[overrun-call : FALSE] */
   4240                 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4241                 if (SOC_FAILURE(rv)) {
   4242                     PORT_UNLOCK(unit);
   4243                     /* Release the ibod recovery port group lock */
   4244                     /* coverity[overrun-call : FALSE] */
   4245                     _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4246                     _bcm_esw_lc_unlock(unit);
   4247                     LOG_ERROR(BSL_LS_BCM_PORT,
   4248                                      (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4249                 }
   4250                 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0);
   4251                 for (i=0; i<3; i++) {
   4252                     if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) {
   4253                         rv = BCM_E_NONE;
   4254                         rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]);
   4255                         if (SOC_FAILURE(rv)) {
   4256                             PORT_UNLOCK(unit);
   4257                             /* Release the ibod recovery port group lock */
   4258                             /* coverity[overrun-call : FALSE] */
   4259                             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]);
   4260                             _bcm_esw_lc_unlock(unit);
   4261                             LOG_ERROR(BSL_LS_BCM_PORT,
   4262                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i])));
   4263                         }
   4264                     }
   4265                 }
   4266                 next_flex_port=1;
   4267             }
   4268 
   4269              _soc_egress_drain_timeout_flag_get(unit, &egress_drain_timeout);
   4270              port_drain_timeout = ibod_ctrl->drain_timeout_flag;
   4271              port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag;
   4272 
   4273             rv = READ_PQEFIFOOVERFLOW0r(unit, &rval);
   4274             if (SOC_FAILURE(rv)) {
   4275                 LOG_ERROR(BSL_LS_BCM_PORT,
   4276                          (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0")));
   4277             }
   4278             rv = READ_PQEFIFOOVERFLOW1r(unit, &rval_1);
   4279             if (SOC_FAILURE(rv)) {
   4280                 LOG_ERROR(BSL_LS_BCM_PORT,
   4281                          (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1")));
   4282             }
   4283 
   4284             if ((rval != 0) || (rval_1 != 0) || (egress_drain_timeout != 0) || (port_drain_timeout != 0)
   4285                     || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) {
   4286                 rv = _bcm_tr3_mmu_recovery(ibod_ctrl);
   4287                 ibod_ctrl->drain_timeout_flag = 0;
   4288                 _soc_egress_drain_timeout_flag_set(unit, 0);
   4289                 if (port_drain_timeout) {
   4290                     ibod_ctrl->drain_timeout_flag = 0;
   4291                     ibod_ctrl->drain_timeout_count++;
   4292                 }
   4293                 if (egress_drain_timeout) {
   4294                     _soc_egress_drain_timeout_flag_set(unit, 0);
   4295                     ibod_ctrl->egress_drain_timeout_count++;
   4296                 }
   4297                 if (port_recovery_failed_flag) {
   4298                     ibod_ctrl->port_recovery_failed_flag = 0;
   4299                     ibod_ctrl->port_recovery_failed_count++;
   4300                 }
   4301                 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) {
   4302                     _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER);
   4303                 }
   4304                 if (SOC_FAILURE(rv)) {
   4305                     LOG_ERROR(BSL_LS_BCM_PORT,
   4306                             (BSL_META_U(unit, "\n Error in MMU recovery ")));
   4307                 }
   4308             }
   4309         }
   4310         (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4311     }
   4312     ibod_ctrl->running = 0;
   4313 }
   4314 
   4315 int _bcm_esw_ibod_syn_port_down (int unit, int port)
   4316 {
   4317     _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit];
   4318     int rv;
   4319     uint64 rrpkt, rrbyt,rval64;
   4320     uint64 rrpkt_diff, rrbyt_diff;
   4321     int runt_threshold;
   4322     uint32 port_mode, rval;
   4323 
   4324     if (!SOC_IS_TRIUMPH3(unit) || !ibod_ctrl) {
   4325         return BCM_E_NONE;
   4326     }
   4327 
   4328     if (SOC_IS_HELIX4(unit)) {
   4329         if (!IS_XE_PORT(unit, port) && !IS_HG_PORT(unit, port)) {
   4330             return SOC_E_NONE;
   4331         }
   4332     } else {
   4333         if (!IS_HG_PORT(unit, port)) {
   4334             return SOC_E_NONE;
   4335         }
   4336     }
   4337 
   4338      if (SOC_INFO(unit).port_speed_max[port] >= 100000 ||
   4339         !(SOC_CONTROL(unit)->soc_flags & SOC_F_INITED)) {
   4340          return SOC_E_NONE;
   4341      }
   4342 
   4343      BCM_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
   4344      port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   4345                                  rval, XPORT0_CORE_PORT_MODEf);
   4346 
   4347      /* Port mode must be Dual or Qual */
   4348      if ((port_mode != 1) && (port_mode != 2)) {
   4349          return SOC_E_NONE;
   4350      }
   4351 
   4352      /* Check if any new runt packet logged in RRPKT */
   4353      rv = READ_RRPKTr(unit, port, &rrpkt);
   4354      if (SOC_FAILURE(rv)) {
   4355          return SOC_E_NONE;
   4356      }
   4357      if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   4358          return SOC_E_NONE;
   4359      }
   4360      /* Check total runt byte count */
   4361      rv = READ_RRBYTr(unit, port, &rrbyt);
   4362      if (SOC_FAILURE(rv)) {
   4363          return SOC_E_NONE;
   4364      }
   4365 
   4366      /* It's very unlikely both packet and byte counters wrap around
   4367      * and stop at 0, the code assume this is from clear counter */
   4368      if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   4369          ibod_ctrl->rrpkt[port] = rrpkt;
   4370          ibod_ctrl->rrbyt[port] = rrbyt;
   4371          return SOC_E_NONE;
   4372      }
   4373 
   4374      rrpkt_diff = rrpkt;
   4375      rrbyt_diff = rrbyt;
   4376      COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   4377      COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   4378      ibod_ctrl->rrpkt[port] = rrpkt;
   4379      ibod_ctrl->rrbyt[port] = rrbyt;
   4380 
   4381      rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   4382      if (SOC_FAILURE(rv)) {
   4383          return SOC_E_NONE;
   4384      }
   4385      runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   4386 
   4387      /* Recovery is needed only for packet size between 33 and 76 */
   4388      if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   4389          COMPILER_64_LO(rrpkt_diff) == 1) {
   4390          if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   4391              return SOC_E_NONE;
   4392          }
   4393      }
   4394      if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   4395          COMPILER_64_LO(rrbyt_diff) <= 32) {
   4396          return SOC_E_NONE;
   4397      }
   4398 
   4399      ibod_ctrl->start_time = sal_time_usecs();
   4400      if (SOC_IS_HELIX4(unit)) {
   4401          int port_group_iter, port_iter, flex_port=0;
   4402          bcm_pbmp_t pbmp;
   4403 
   4404          port_group_iter=-1;
   4405          PBMP_ITER(PBMP_XW_ALL(unit), port_iter) {
   4406              /* coverity[overrun-call : FALSE] */
   4407              if (!(_bcm_tr3_port_is_control_port(unit, port_iter))) {
   4408                  continue;
   4409              }
   4410              flex_port = port_iter;
   4411              port_group_iter++;
   4412              BCM_IF_ERROR_RETURN(bcm_esw_port_subsidiary_ports_get(unit, flex_port, &pbmp));
   4413              if (SOC_PBMP_MEMBER(pbmp, port)) {
   4414                  break;
   4415              }
   4416          }
   4417          /* coverity[overrun-call : FALSE] */
   4418          rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4419          if (SOC_FAILURE(rv)) {
   4420             PORT_UNLOCK(unit);
   4421             /* Release the ibod recovery port group lock */
   4422             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4423             _bcm_esw_lc_unlock(unit);
   4424          }
   4425      } else {
   4426          rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 1, port);
   4427      }
   4428 
   4429      if (SOC_FAILURE(rv)) {
   4430          LOG_ERROR(BSL_LS_BCM_PORT,
   4431                   (BSL_META_U(unit, "\n Error in RRPKT WAR %s"), SOC_PORT_NAME(unit, port)));
   4432      }
   4433      return SOC_E_NONE;
   4434 
   4435 }
   4436 
   4437 int
   4438 _bcm_esw_ibod_sync_recovery_start(int unit, sal_usecs_t interval)
   4439 {
   4440     int cnt;
   4441     bcm_pkt_t *pkt;
   4442     uint8 *buf;
   4443     int buf_size = 72;
   4444     uint32 rval;
   4445     int rv = BCM_E_NONE;
   4446     _port_ibod_ctrl_t *ibod_ctrl;
   4447 
   4448     if (!SOC_IS_TRIUMPH3(unit)) {
   4449         return BCM_E_NONE;
   4450     }
   4451 
   4452     ibod_ctrl = _port_ibod_ctrl[unit];
   4453     if (ibod_ctrl == NULL) {
   4454         ibod_ctrl = sal_alloc(sizeof(_port_ibod_ctrl_t), "_port_ibod_ctrl_t");
   4455         if (ibod_ctrl == NULL) {
   4456             return BCM_E_MEMORY;
   4457         }
   4458         sal_memset(ibod_ctrl, 0, sizeof(_port_ibod_ctrl_t));
   4459         _port_ibod_ctrl[unit] = ibod_ctrl;
   4460     }
   4461 
   4462     ibod_ctrl->interval = interval;
   4463 
   4464     if (ibod_ctrl->interval < IBOD_SYNC_INTERVAL_MIN) {
   4465         ibod_ctrl->interval = IBOD_SYNC_INTERVAL_MIN;
   4466     }
   4467 
   4468     if (ibod_ctrl->running) {
   4469         return BCM_E_NONE;
   4470     }
   4471 
   4472     ibod_ctrl->unit = unit;
   4473 
   4474     /* Setup packet field */
   4475     pkt = &ibod_ctrl->pkt;
   4476     buf = soc_cm_salloc(unit, buf_size, "pkt alloc data");
   4477     if (buf == NULL) {
   4478         return BCM_E_MEMORY;
   4479     }
   4480     BCM_PKT_ONE_BUF_SETUP(pkt, buf, buf_size);
   4481     pkt->unit = unit;
   4482     pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD |
   4483                  BCM_TX_LINKDOWN_TRANSMIT;
   4484     pkt->opcode = BCM_PKT_OPCODE_UC; /* do not to CPU */
   4485 
   4486     if (ibod_ctrl->sema == NULL) {
   4487         ibod_ctrl->sema = sal_sem_create("ibod recovery", sal_sem_BINARY, 0);
   4488         if (ibod_ctrl->sema == NULL) {
   4489             return BCM_E_MEMORY;
   4490         }
   4491     }
   4492 
   4493     sal_snprintf(ibod_ctrl->taskname, sizeof (ibod_ctrl->taskname),
   4494                  "bcmIbodSync.%d", unit);
   4495     ibod_ctrl->stop = 0;
   4496     SOC_IF_ERROR_RETURN(_bcm_esw_ibod_recovery_lock_init(unit));
   4497     rv = soc_tr3_mmu_store_alloc(unit);
   4498     if(BCM_FAILURE(rv)) {
   4499         return rv;
   4500     }
   4501     soc_ibod_recovery_in_progress_set(unit, 0);
   4502     _soc_egress_drain_timeout_flag_set(unit, 0);
   4503     sal_memset(txerr_trigger_flag, 0, sizeof(txerr_trigger_flag));
   4504     if (SOC_IS_HELIX4(unit)) {
   4505         SOC_IF_ERROR_RETURN(READ_IBOD_INTR_MASKr(unit, &rval));
   4506         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4507         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4508         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4509         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4510         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4511         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4512         SOC_IF_ERROR_RETURN(WRITE_IBOD_INTR_MASKr(unit, rval));
   4513         if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ,
   4514                               soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50),
   4515                               _bcm_hx4_ibod_sync_recovery_thread,
   4516                               ibod_ctrl) == SAL_THREAD_ERROR) {
   4517             return BCM_E_MEMORY;
   4518         }
   4519     } else {
   4520         if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ,
   4521                               soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50),
   4522                               _bcm_tr3_ibod_sync_recovery_thread,
   4523                               ibod_ctrl) == SAL_THREAD_ERROR) {
   4524             return BCM_E_MEMORY;
   4525         }
   4526     }
   4527     cnt = 10;
   4528     while (!ibod_ctrl->running && cnt--) {
   4529         sal_usleep(100000);
   4530     }
   4531     if (!ibod_ctrl->running) {
   4532         LOG_ERROR(BSL_LS_BCM_PORT,
   4533                   (BSL_META_U(unit,
   4534                               "%s: Thread did not start\n"), ibod_ctrl->taskname));
   4535         return BCM_E_TIMEOUT;
   4536     }
   4537     return BCM_E_NONE;
   4538 }
   4539 
   4540 int
   4541 _bcm_esw_ibod_sync_recovery_stop(int unit)
   4542 {
   4543     int cnt;
   4544     bcm_pkt_t *pkt;
   4545     _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit];
   4546 
   4547     if (ibod_ctrl == NULL) {
   4548         return BCM_E_NONE;
   4549     }
   4550 
   4551     ibod_ctrl->stop = 1;
   4552     if (ibod_ctrl->sema != NULL) {
   4553         sal_sem_give(ibod_ctrl->sema);
   4554     }
   4555     cnt = 10;
   4556     while (ibod_ctrl->running && cnt--) {
   4557         sal_usleep(100000);
   4558     }
   4559     if (ibod_ctrl->running) {
   4560         LOG_ERROR(BSL_LS_BCM_PORT,
   4561                   (BSL_META_U(unit,
   4562                               "%s: Thread did not start\n"), ibod_ctrl->taskname));
   4563         return BCM_E_TIMEOUT;
   4564     }
   4565     pkt = &ibod_ctrl->pkt;
   4566     if (pkt->_pkt_data.data != NULL) {
   4567         soc_cm_sfree(unit, pkt->_pkt_data.data);
   4568         pkt->_pkt_data.data = NULL;
   4569         pkt->_pkt_data.len = 0;
   4570     }
   4571     if (ibod_ctrl->sema != NULL) {
   4572         sal_sem_destroy(ibod_ctrl->sema);
   4573     }
   4574 
   4575     sal_free(ibod_ctrl);
   4576     _port_ibod_ctrl[unit] = NULL;
   4577 
   4578     _bcm_esw_ibod_recovery_lock_deinit(unit);
   4579 
   4580     soc_tr3_mmu_store_free(unit);
   4581     return BCM_E_NONE;
   4582 }
   4583 
   4584 int _bcm_esw_ibod_sync_recovery_running(int unit, _port_ibod_ctrl_t *ibod_ctrl)
   4585 {
   4586     if (_port_ibod_ctrl[unit] == NULL) {
   4587         return BCM_E_FAIL;
   4588     }
   4589     if(ibod_ctrl != NULL) {
   4590         sal_memcpy(ibod_ctrl, _port_ibod_ctrl[unit], sizeof(_port_ibod_ctrl_t));
   4591     }
   4592     return BCM_E_NONE;
   4593 }
   4594 
   4595 STATIC int _bcm_tr3_xmac_fifo_check(int unit, bcm_port_t port, uint8 lu_tpo)
   4596 {
   4597     int rv_xmac_fifo = BCM_E_NONE;
   4598     int rv = BCM_E_NONE;
   4599     bcm_pkt_t *pkt = NULL;
   4600     uint8 *payload;
   4601     uint32 req_cnt = 0, cell_cnt = 0;
   4602     uint64 rval64;
   4603     int rx_enable_org = 0,speed_mode=0,port_enable;
   4604     pbmp_t act_tx_pbmp, tx_pbmp;
   4605 
   4606     COMPILER_64_ZERO(rval64);
   4607     SOC_PBMP_CLEAR(act_tx_pbmp);
   4608     SOC_PBMP_CLEAR(tx_pbmp);
   4609 
   4610     /* Create test packet */
   4611     pkt = soc_cm_salloc(unit, sizeof(bcm_pkt_t), "pkt buffer");
   4612     if (pkt == NULL) {
   4613         return BCM_E_FAIL;
   4614     }
   4615 
   4616     sal_memset(pkt, 0, sizeof(bcm_pkt_t));
   4617     payload = soc_cm_salloc(unit, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ,
   4618                             "pkt alloc data");
   4619     if (payload == NULL) {
   4620         soc_cm_sfree(unit, pkt);
   4621         return BCM_E_FAIL;
   4622     }
   4623     sal_memset(payload, 0, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4624     BCM_PKT_ONE_BUF_SETUP(pkt, payload, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4625     pkt->unit = unit;
   4626     pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD |
   4627                 BCM_TX_LINKDOWN_TRANSMIT;
   4628     pkt->call_back = NULL;
   4629 
   4630 #ifdef BCM_PORT_DEFAULT_DISABLE
   4631     port_enable = FALSE;
   4632 #else
   4633     port_enable = TRUE;
   4634 #endif  /* BCM_PORT_DEFAULT_DISABLE */
   4635 
   4636     if (BCM_E_NONE !=
   4637         (rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &port_enable))) {
   4638         goto cleanup;
   4639     }
   4640     /* Put the port in MAC loopback and enable it for transmit */
   4641     if (BCM_E_NONE !=
   4642         (rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4643         goto cleanup;
   4644     }
   4645     if (BCM_E_NONE !=
   4646         (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4647         goto cleanup;
   4648     }
   4649     /* Ensure that we are in MAC line-side loopback */
   4650     if (SOC_E_NONE != (rv = READ_XMAC_CTRLr(unit, port, &rval64))) {
   4651         goto cleanup;
   4652     }
   4653 
   4654     rx_enable_org = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf);
   4655     /* RX Disable */
   4656     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   4657     /* Line local LB  */
   4658     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1);
   4659     /* Core local LB */
   4660     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, CORE_LOCAL_LPBKf, 0);
   4661     if (SOC_E_NONE != (rv = WRITE_XMAC_CTRLr(unit, port, rval64))) {
   4662         goto cleanup;
   4663     }
   4664     /* Ensure that we are back in same MAC MODE*/
   4665     if (SOC_E_NONE != (rv = READ_XMAC_MODEr(unit, port, &rval64))) {
   4666         goto cleanup;
   4667     }
   4668     speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, SPEED_MODEf);
   4669 
   4670     /* Stall the XMAC's transmit FIFO */
   4671     if (SOC_E_NONE !=
   4672         (rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 4))) {
   4673         goto cleanup;
   4674     }
   4675 
   4676     if (SOC_E_NONE !=
   4677         (rv = soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port,
   4678                                      MACSEC_TX_LAUNCH_ENf, 1))) {
   4679         goto cleanup;
   4680     }
   4681 
   4682     /* EPC_LINK */
   4683     soc_link_mask2_get(unit, &act_tx_pbmp);
   4684     SOC_PBMP_PORT_ADD(tx_pbmp, port);
   4685     if (!lu_tpo) {
   4686         /* Use original state and add new ports as well */
   4687         SOC_PBMP_OR(tx_pbmp, act_tx_pbmp);
   4688     }
   4689     if (SOC_E_NONE != (rv = soc_link_mask2_set(unit, tx_pbmp))) {
   4690         goto cleanup;
   4691     }
   4692     /* Transmit the test packet */
   4693     BCM_PKT_TX_LEN_SET(pkt, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4694     BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   4695     rv = bcm_esw_tx(unit, pkt, NULL);
   4696     if (BCM_FAILURE(rv)) {
   4697         rv = BCM_E_FAIL;
   4698         goto cleanup;
   4699     }
   4700 
   4701     /* Wait for a short period of time to allow
   4702        the packet to reach the end of the EP */
   4703     sal_udelay(1000);
   4704 
   4705     /* Read the request count value */
   4706     if (SOC_E_NONE !=
   4707         (rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(unit, port, &req_cnt))) {
   4708         goto cleanup;
   4709     }
   4710     /* Read the cell count value */
   4711     if (SOC_E_NONE !=
   4712         (rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &cell_cnt))) {
   4713         goto cleanup;
   4714     }
   4715     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4716                 (BSL_META_U(unit,
   4717                             "Check: cell_req_cnt: %d cell_cnt: %d\n"),
   4718                  req_cnt, cell_cnt));
   4719     /* Check to make sure that the request count is exactly zero */
   4720     if (req_cnt != 0) {
   4721         rv_xmac_fifo = BCM_E_INTERNAL;
   4722         goto cleanup;
   4723     }
   4724 
   4725 cleanup:
   4726     /* free packet memory */
   4727     if (payload != NULL) {
   4728         soc_cm_sfree(unit, payload);
   4729     }
   4730     if (pkt != NULL) {
   4731         soc_cm_sfree(unit, pkt);
   4732     }
   4733     /* Clear the MAC loopback (flushes the test packet) */
   4734     if (SOC_E_NONE != MAC_LOOPBACK_SET(PORT(unit, port).p_mac,
   4735                                             unit, port, FALSE)) {
   4736         rv = BCM_E_FAIL;
   4737     }
   4738     /* Clear the MAC Enable Set */
   4739     if (SOC_E_NONE != MAC_ENABLE_SET(PORT(unit, port).p_mac,
   4740                                           unit, port, FALSE)) {
   4741         rv = BCM_E_FAIL;
   4742     }
   4743     /* Restoring the MAC Enable Set */
   4744     if (port_enable) {
   4745         if (SOC_E_NONE !=
   4746             (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4747              rv = BCM_E_FAIL;
   4748         }
   4749     }
   4750     /* Remove the MAC FIFO stall */
   4751     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MODEr, port,
   4752                                              SPEED_MODEf, speed_mode)) {
   4753         rv = BCM_E_FAIL;
   4754     }
   4755     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port,
   4756                                              MACSEC_TX_LAUNCH_ENf, 0)) {
   4757         rv = BCM_E_FAIL;
   4758     }
   4759     /* revert rx_enable */
   4760     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_CTRLr, port, RX_ENf,
   4761                                              rx_enable_org)) {
   4762         rv = BCM_E_FAIL;
   4763     }
   4764     /* EPC_LINK restore */
   4765     if (SOC_E_NONE != soc_link_mask2_set(unit, act_tx_pbmp)) {
   4766         rv = BCM_E_FAIL;
   4767     }
   4768     /* Clear the counters from tx port*/
   4769     SOC_PBMP_PORT_SET(tx_pbmp, port);
   4770     if (SOC_E_NONE != soc_counter_set32_by_port(unit, tx_pbmp, 0))  {
   4771         rv = BCM_E_FAIL;
   4772     }
   4773     if (BCM_E_NONE != rv) {
   4774         return rv;
   4775     } else {
   4776         return rv_xmac_fifo;
   4777     }
   4778 }
   4779 
   4780 #define _BCM_TR3_PORT_UR_RETRY_MAX 15
   4781 int _bcm_tr3_port_ur_chk(int unit, int num_ports, bcm_port_t port)
   4782 {
   4783     uint8 lu_tpo = 0; /* link up test port only */
   4784     int retry = _BCM_TR3_PORT_UR_RETRY_MAX;
   4785     int fifo_underrun = FALSE, issue_overcome = TRUE;
   4786     soc_info_t *si = &SOC_INFO(unit);
   4787     int rv = BCM_E_NONE;
   4788     int okay = 0;
   4789     uint32 expected_cell_req_cnt, cell_req_cnt, cell_cnt;
   4790     soc_block_type_t pbt;
   4791     int _num_ports = (num_ports == -1) ? 4 : num_ports;
   4792     int phy_port = SOC_IS_HELIX4(unit) ?
   4793                    _SOC_HX4_MGMT_PHY_PORT : _SOC_TR3_MGMT_PHY_PORT;
   4794 
   4795 #ifdef BCM_TRIUMPH3_SUPPORT
   4796     if (!(SOC_IS_HELIX4(unit))) {
   4797         /* Skipping in for Disabled Ports */
   4798         SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   4799         if (!okay) {
   4800             return BCM_E_NONE;
   4801         }
   4802     }
   4803 #endif
   4804 #ifdef BCM_HELIX4_SUPPORT
   4805      if ( SOC_IS_HELIX4(unit) &&
   4806      ((_tr3_port_config_id[unit] == 463)||
   4807         (_tr3_port_config_id[unit] == 413)) &&
   4808         (57 == si->port_l2p_mapping[port] || 61 == si->port_l2p_mapping[port]))
   4809      {
   4810         switch (_num_ports) {
   4811           case 1: expected_cell_req_cnt = 8; break;
   4812           case 2: expected_cell_req_cnt = 4; break;
   4813           case 4: expected_cell_req_cnt = 4; break;
   4814           default: expected_cell_req_cnt = 4;
   4815         }
   4816      }else
   4817 #endif
   4818     {
   4819         switch (_num_ports) {
   4820          case 1: expected_cell_req_cnt = 16; break;
   4821          case 2: expected_cell_req_cnt = 8; break;
   4822          case 4: expected_cell_req_cnt = 4; break;
   4823          default: expected_cell_req_cnt = 4;
   4824        }
   4825     }
   4826     if (-1 == port) {
   4827         lu_tpo = 1;
   4828         port = si->port_p2l_mapping[phy_port];
   4829     } else {
   4830         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4831     }
   4832     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4833                 (BSL_META_U(unit,
   4834                             "UR test: %s\n"), SOC_PORT_NAME(unit, port)));
   4835 
   4836     /* nothing to do if port is not a valid port */
   4837     if (!SOC_PORT_VALID(unit, port)) {
   4838         LOG_VERBOSE(BSL_LS_BCM_PORT, (BSL_META_U(unit,
   4839                     "Port %s is not valid - skipping WAR\n"),
   4840                     SOC_PORT_NAME(unit, port)));
   4841         return BCM_E_NONE;
   4842     }
   4843 
   4844     pbt = SOC_BLOCK_TYPE(unit, SOC_PORT_BLOCK(unit, phy_port));
   4845     while (retry--) {
   4846         rv = _bcm_tr3_xmac_fifo_check(unit, port, lu_tpo);
   4847         if (BCM_E_INTERNAL == rv) {
   4848             if (num_ports != -1 && (_num_ports > 1)) {
   4849                 /* This is a case of flex port transform to dual or quad lane
   4850                    mode and one of the newly created ports is failing */
   4851                 return BCM_E_PORT;
   4852             }
   4853             fifo_underrun = TRUE;
   4854             issue_overcome = FALSE;
   4855 
   4856             if (SOC_E_NONE != (rv = _soc_tr3_ur_port_reset(unit, _num_ports, port, pbt))) {
   4857                 rv = BCM_E_INTERNAL;
   4858                 goto cleanup;
   4859             }
   4860             if ((rv = _bcm_port_mac_init(unit, port, &okay)) != BCM_E_NONE) {
   4861                 goto cleanup;
   4862             }
   4863             /* Read cell req count value to see if reset cleared it */
   4864             if ((rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(
   4865                           unit, port, &cell_req_cnt)) != SOC_E_NONE) {
   4866                 goto cleanup;
   4867             }
   4868             /* Read cell count value again to see if reset cleared it */
   4869             if ((rv = READ_PORT_TXFIFO_CELL_CNTr(
   4870                           unit, port, &cell_cnt))!= SOC_E_NONE) {
   4871                 goto cleanup;
   4872             }
   4873             LOG_VERBOSE(BSL_LS_BCM_PORT,
   4874                         (BSL_META_U(unit,
   4875                                     "After reset: cell_req_cnt: "
   4876                                     "%d cell_cnt: %d\n"), cell_req_cnt, cell_cnt));
   4877             /* Check to make sure that the request count is exactly zero */
   4878             if ((cell_req_cnt != expected_cell_req_cnt) || (cell_cnt != 0)) {
   4879                 rv = BCM_E_INTERNAL;
   4880                 goto cleanup;
   4881             }
   4882         } else {
   4883             if (BCM_E_NONE != rv) {
   4884                 goto cleanup;
   4885             }
   4886             if (TRUE == fifo_underrun) {
   4887                 issue_overcome = TRUE;
   4888             }
   4889             /* either underrun didn't occur or war fixed it */
   4890             break;
   4891         }
   4892     }/* while */
   4893 
   4894     if (fifo_underrun) {
   4895         rv = BCM_E_INTERNAL;
   4896         if (issue_overcome) {
   4897             rv = BCM_E_NONE;
   4898             LOG_VERBOSE(BSL_LS_BCM_PORT,
   4899                         (BSL_META_U(unit,
   4900                                     "Port %s recovered from XMAC FIFO underrun\n"),
   4901                          SOC_PORT_NAME(unit, port)));
   4902         } else {
   4903             LOG_ERROR(BSL_LS_BCM_PORT,
   4904                       (BSL_META_U(unit,
   4905                                   "Port %s did not recover from XMAC FIFO underrun\n"),
   4906                        SOC_PORT_NAME(unit, port)));
   4907         }
   4908     }
   4909 
   4910 cleanup:
   4911     if (BCM_E_NONE != rv) {
   4912         LOG_ERROR(BSL_LS_BCM_PORT,
   4913                   (BSL_META_U(unit,
   4914                               "Port %s, failed while checking/recovering "
   4915                               "XL port underrun\n"),
   4916                    SOC_PORT_NAME(unit, port)));
   4917     }
   4918 
   4919     return rv;
   4920 }
   4921 #endif /* BCM_TRIUMPH3_SUPPORT */
   4922 
   4923 
   4924 /*
   4925  * Function:
   4926  *      _bcm_esw_port_gport_validate
   4927  * Description:
   4928  *      Helper funtion to validate port/gport parameter
   4929  * Parameters:
   4930  *      unit  - (IN) BCM device number
   4931  *      port_in  - (IN) Port / Gport to validate
   4932  *      port_out - (OUT) Port number if valid.
   4933  * Return Value:
   4934  *      BCM_E_NONE - Port OK
   4935  *      BCM_E_INIT - Not initialized
   4936  *      BCM_E_PORT - Port Invalid
   4937  */
   4938 int
   4939 _bcm_esw_port_gport_validate(int unit, bcm_port_t port_in, bcm_port_t *port_out)
   4940 {
   4941     if (bcm_port_info[unit] == NULL) {
   4942         return BCM_E_INIT;
   4943     }
   4944 
   4945 #if defined (BCM_HGPROXY_COE_SUPPORT)
   4946     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   4947         soc_feature(unit, soc_feature_channelized_switching)) &&
   4948         BCM_GPORT_IS_SUBPORT_PORT(port_in)) {
   4949         return _bcm_xgs5_subport_gport_validate(unit,
   4950                                                 port_in,
   4951                                                 port_out);
   4952     } else
   4953 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
   4954 
   4955 #ifdef BCM_KATANA2_SUPPORT
   4956     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   4957         soc_feature(unit, soc_feature_subtag_coe)) {
   4958         return _bcm_kt2_port_gport_validate(unit, port_in, port_out);
   4959     }
   4960 #endif
   4961 
   4962     if (BCM_GPORT_IS_SET(port_in)) {
   4963         BCM_IF_ERROR_RETURN(
   4964             bcm_esw_port_local_get(unit, port_in, port_out));
   4965     } else if (SOC_PORT_VALID(unit, port_in)) {
   4966         *port_out = port_in;
   4967     } else {
   4968         return BCM_E_PORT;
   4969     }
   4970 
   4971     return BCM_E_NONE;
   4972 }
   4973 
   4974 /*
   4975  * Function:
   4976  *      _bcm_port_link_delay_update
   4977  * Description:
   4978  *      Helper funtion: Update link delay based on configured values
   4979  * Parameters:
   4980  *      unit  - (IN) BCM device number
   4981  *      port  - (IN) Port number
   4982  *      speed - (IN) New speed
   4983  * Return Value:
   4984  *      BCM_E_XXX
   4985  */
   4986 int
   4987 _bcm_esw_port_link_delay_update(int unit, bcm_port_t port, int speed)
   4988 {
   4989     int32 link_delay;
   4990     int mac_rx_latency = 0;
   4991     _bcm_port_info_t *port_info;
   4992     int rv;
   4993 
   4994     _bcm_port_info_access(unit, port, &port_info);
   4995     rv = MAC_CONTROL_GET(port_info->p_mac, unit, port,
   4996                          SOC_MAC_CONTROL_EXPECTED_RX_LATENCY,
   4997                          &mac_rx_latency);
   4998     if (rv != BCM_E_NONE) {
   4999         LOG_INFO(BSL_LS_BCM_PORT, (BSL_META(
   5000            "Port updating LINK_DELAY, but MAC doesn't have a default value\n")
   5001         ));
   5002     }
   5003 
   5004     link_delay = (int32)soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency);
   5005     /* use bcmPortControl1588P2PDelay control field as an offset from this value */
   5006     link_delay += PORT(unit, port).link_delay_offset;
   5007 
   5008     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   5009         BCM_IF_ERROR_RETURN(
   5010             soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr,
   5011                 port, LINK_DELAYf, (uint32)link_delay));
   5012     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   5013         BCM_IF_ERROR_RETURN(
   5014             soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r,
   5015                 port, 0, LINK_DELAYf, (uint32)link_delay));
   5016     } else {
   5017         /* No LINK_DELAY register, so no-op */
   5018     }
   5019 
   5020     return BCM_E_NONE;
   5021 }
   5022 
   5023 STATIC int
   5024 _bcm_esw_port_link_delay_recover(int unit, bcm_port_t port, int speed)
   5025 {
   5026     uint32 link_delay = 0;
   5027     uint32 mac_rx_latency = 0;
   5028 
   5029     mac_rx_latency = soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency);
   5030 
   5031     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   5032         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGR_1588_LINK_DELAYr, port, LINK_DELAYf, &link_delay));
   5033     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   5034         SOC_IF_ERROR_RETURN(soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r,
   5035                                                           port, 0, LINK_DELAYf, &link_delay));
   5036     }
   5037 
   5038     PORT(unit, port).link_delay_offset = link_delay - mac_rx_latency;
   5039 
   5040     return BCM_E_NONE;
   5041 }
   5042 
   5043 /*
   5044  * Function:
   5045  *      _bcm_port_info_get
   5046  * Description:
   5047  *      Helper funtion
   5048  * Parameters:
   5049  *      unit  - (IN) BCM device number
   5050  *      port  - (IN) Port number
   5051  *      pinfo - (OUT) Port info.
   5052  * Return Value:
   5053  *      BCM_E_XXX
   5054  */
   5055 int
   5056 _bcm_port_info_get(int unit, bcm_port_t port, _bcm_port_info_t **pinfo)
   5057 {
   5058     /* Input parameters check. */
   5059     if (NULL == pinfo) {
   5060         return (BCM_E_PARAM);
   5061     }
   5062 
   5063     PORT_INIT(unit);
   5064 
   5065     *pinfo = &PORT(unit, port);
   5066     return (BCM_E_NONE);
   5067 }
   5068 
   5069 /*
   5070  * Function:
   5071  *      _bcm_esw_iport_tab_set
   5072  * Description:
   5073  *      Set field in either IPORT_TABLE or the special CPU Higig entry in
   5074  *      the PORT_TAB.
   5075  * Parameters:
   5076  *      unit  - Device number
   5077  *      port  - Port number
   5078  *      field - Field name within PORT_TAB table entry
   5079  *      value - new field value
   5080  * Return Value:
   5081  *      BCM_E_NONE
   5082  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   5083  */
   5084 int
   5085 _bcm_esw_iport_tab_set(int unit, bcm_port_t port,
   5086                        soc_field_t field, int value)
   5087 
   5088 {
   5089     port_tab_entry_t pent;
   5090     soc_mem_t mem;
   5091     int rv, index, cpu_hg_index, cur_val;
   5092 
   5093     cpu_hg_index = SOC_IS_KATANA2(unit) ?
   5094                    SOC_INFO(unit).cpu_hg_pp_port_index :
   5095                    SOC_INFO(unit).cpu_hg_index;
   5096 
   5097     if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   5098         mem = IPORT_TABLEm;
   5099         index = SOC_PORT_MOD_OFFSET(unit, port);
   5100     } else if (IS_CPU_PORT(unit, port) && cpu_hg_index != -1) {
   5101         mem = PORT_TABm;
   5102         index = cpu_hg_index;
   5103     } else {
   5104         return BCM_E_NONE;
   5105     }
   5106 
   5107     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   5108         return (BCM_E_UNAVAIL);
   5109     }
   5110 
   5111     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent);
   5112     if (BCM_SUCCESS(rv)) {
   5113         cur_val = soc_mem_field32_get(unit, mem, &pent, field);
   5114         if (value != cur_val) {
   5115             soc_mem_field32_set(unit, mem, &pent, field, value);
   5116             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pent);
   5117         }
   5118     }
   5119     return rv;
   5120 }
   5121 
   5122 /*
   5123  * Function:
   5124  *      _bcm_phy_cb_xlate_port
   5125  * Description:
   5126  *      Provides port translation for API call-backs
   5127  * Parameter:
   5128  *      unit -- unit number
   5129  *      port -- port number to be translated
   5130  * Returns:
   5131  *      SOC_E_xxx
   5132  */
   5133 STATIC int
   5134 _bcm_phy_cb_xlate_port(int unit, int *port)
   5135 {
   5136     BCM_API_XLATE_PORT_P2A(unit, port);
   5137 
   5138     return BCM_E_NONE;
   5139 }
   5140 
   5141 /*
   5142  * Function:
   5143  *      _bcm_port_autoneg_advert_remote_get
   5144  * Purpose:
   5145  *      Main part of bcm_port_advert_get_remote
   5146  */
   5147 
   5148 STATIC int
   5149 _bcm_port_autoneg_advert_remote_get(int unit, bcm_port_t port,
   5150                             bcm_port_ability_t *ability_mask)
   5151 {
   5152     int                 an, an_done;
   5153 
   5154     if(bcm_common_oamp_port_enable_get(unit, port)) {
   5155         LOG_ERROR(BSL_LS_BCM_PORT,
   5156                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   5157                    port));
   5158         return BCM_E_PARAM;
   5159     }
   5160 
   5161     SOC_IF_ERROR_RETURN
   5162         (soc_phyctrl_auto_negotiate_get(unit,  port,
   5163                                 &an, &an_done));
   5164 
   5165     if (an && an_done) {
   5166         SOC_IF_ERROR_RETURN
   5167             (soc_phyctrl_ability_remote_get(unit, port, ability_mask));
   5168     }
   5169 
   5170     return BCM_E_NONE;
   5171 }
   5172 
   5173 /*
   5174  * Function:
   5175  *      _bcm_port_ability_local_get
   5176  * Purpose:
   5177  *      Main part of bcm_port_ability_local_get
   5178  */
   5179 
   5180 STATIC int
   5181 _bcm_port_ability_local_get(int unit, bcm_port_t port,
   5182                            bcm_port_ability_t *ability_mask)
   5183 {
   5184     soc_port_ability_t             mac_ability, phy_ability;
   5185     soc_pa_encap_t                 encap_ability;
   5186 #ifdef BCM_TRIUMPH3_SUPPORT
   5187     int lanes;
   5188 #endif
   5189 #ifdef INCLUDE_MACSEC
   5190     phy_ctrl_t         *ext_pc;
   5191     ext_pc = EXT_PHY_SW_STATE(unit, port);
   5192 #endif /* INCLUDE_MACSEC */
   5193     sal_memset(&phy_ability, 0, sizeof(soc_port_ability_t));
   5194     sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t));
   5195 
   5196     if(bcm_common_oamp_port_enable_get(unit, port)) {
   5197         LOG_ERROR(BSL_LS_BCM_PORT,
   5198                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   5199                    port));
   5200         return BCM_E_PARAM;
   5201     }
   5202 
   5203     SOC_IF_ERROR_RETURN
   5204         (soc_phyctrl_ability_local_get(unit, port, &phy_ability));
   5205 
   5206     if (!(IS_TDM_PORT(unit, port))) {
   5207         SOC_IF_ERROR_RETURN
   5208             (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,
   5209                                    port, &mac_ability));
   5210     }
   5211 
   5212     /* Combine MAC and PHY abilities */
   5213 
   5214 #ifdef INCLUDE_MACSEC
   5215     /*
   5216 	   MACSEC phys have their own MAC. If macsec is enabled,
   5217        phy's MAC is used for MAC operation on the line side.
   5218        Check added to use half duplex ability of phy/MAC.
   5219     */
   5220     if((NULL != ext_pc) && ext_pc->macsec_enable) {
   5221         ability_mask->speed_half_duplex = phy_ability.speed_half_duplex;
   5222     } else
   5223 #endif /* INCLUDE_MACSEC */
   5224     {
   5225         ability_mask->speed_half_duplex =
   5226             mac_ability.speed_half_duplex & phy_ability.speed_half_duplex;
   5227     }
   5228     ability_mask->speed_full_duplex =
   5229         mac_ability.speed_full_duplex & phy_ability.speed_full_duplex;
   5230     ability_mask->pause     = mac_ability.pause & phy_ability.pause;
   5231     if (phy_ability.interface == 0) {
   5232         ability_mask->interface = mac_ability.interface;
   5233     } else {
   5234         ability_mask->interface = phy_ability.interface;
   5235     }
   5236     ability_mask->medium    = phy_ability.medium;
   5237     ability_mask->channel   = phy_ability.channel;
   5238     ability_mask->fec       = phy_ability.fec;
   5239     /* mac_ability.eee without phy_ability.eee makes no sense */
   5240     ability_mask->eee    = phy_ability.eee;
   5241     ability_mask->loopback  = mac_ability.loopback | phy_ability.loopback |
   5242                                BCM_PORT_ABILITY_LB_NONE;
   5243     ability_mask->flags     = mac_ability.flags | phy_ability.flags;
   5244 
   5245     /* Get port encapsulation ability */
   5246     encap_ability = mac_ability.encap;
   5247 
   5248     if ((soc_feature(unit, soc_feature_embedded_higig))
   5249         && IS_E_PORT(unit, port)) {
   5250         encap_ability |= BCM_PA_ENCAP_HIGIG2_L2;
   5251         encap_ability |= BCM_PA_ENCAP_HIGIG2_IP_GRE;
   5252     }
   5253 
   5254 #if defined(BCM_RAPTOR_SUPPORT)
   5255     if ((SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) &&
   5256         IS_S_PORT(unit, port)) {
   5257         encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5258         /* should be HiGig-Lite, not Higig2 */
   5259         encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5260     }
   5261 #endif
   5262 
   5263 #ifdef BCM_TRIUMPH2_SUPPORT
   5264    if (IS_HL_PORT(unit, port) && (SOC_IS_APOLLO(unit) ||
   5265                                   SOC_IS_TRIUMPH2(unit) ||
   5266                                   SOC_IS_VALKYRIE2(unit))) {
   5267        /* HiGig-Lite port */
   5268        encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5269    }
   5270 #endif
   5271 
   5272     if (IS_HL_PORT(unit, port) &&
   5273          (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) ||
   5274           SOC_IS_KATANA2(unit) )) {
   5275         encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5276         /* should be HiGig-Lite, not Higig2 */
   5277         encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5278     }
   5279 
   5280 #ifdef BCM_GREYHOUND_SUPPORT
   5281     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
   5282         SOC_IS_GREYHOUND2(unit)) {
   5283         if (IS_HL_PORT(unit, port)) {
   5284             encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5285             encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5286         } else if (IS_HG_PORT(unit, port)) {
   5287             encap_ability |= BCM_PA_ENCAP_HIGIG;
   5288         }
   5289     }
   5290 #endif /* BCM_GREYHOUND_SUPPORT */
   5291 
   5292 #if defined (BCM_HURRICANE_SUPPORT)
   5293     if (IS_XQ_PORT(unit, port) && SOC_IS_HURRICANEX(unit) && (CMDEV(unit).dev.rev_id == BCM56142_A0_REV_ID) ) {
   5294         ability_mask->speed_half_duplex &= ~(BCM_PORT_ABILITY_100MB);
   5295         ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB);
   5296     }
   5297 #endif
   5298 
   5299 #if defined (BCM_TRIUMPH3_SUPPORT)
   5300    if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
   5301        (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) &&
   5302        (port == 54 || port == 55)) {
   5303         if (IS_XE_PORT(unit, port)) {
   5304             BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &lanes));
   5305             if (lanes == 1) {
   5306                 /* In one lanes mode, only support 100Mbps&1000Mbps */
   5307                 ability_mask->speed_full_duplex =  (BCM_PORT_ABILITY_100MB|BCM_PORT_ABILITY_1000MB);
   5308             } else if (lanes == 4) {
   5309                 /* In four lanes mode, remove the 100Mbps&1000Mbps ability */
   5310                 ability_mask->speed_full_duplex &=  ~(BCM_PORT_ABILITY_100MB|BCM_PORT_ABILITY_1000MB);
   5311             }
   5312         }
   5313     }
   5314 #endif
   5315 
   5316 #ifdef BCM_SABER2_SUPPORT
   5317    if (SOC_IS_SABER2(unit)) {
   5318         if (IS_XE_PORT(unit, port) && IS_MXQ_PORT(unit, port)) {
   5319                 /*  XE port, only support 10Gbps */
   5320                 ability_mask->speed_full_duplex =  (BCM_PORT_ABILITY_10GB);
   5321        }
   5322    }
   5323 #endif
   5324 
   5325     ability_mask->encap = encap_ability;
   5326     return BCM_E_NONE;
   5327 }
   5328 
   5329 int
   5330 bcm_esw_port_lport_prof_src_check(int unit, int port_type, int *src_tbl_is_stm)
   5331 {
   5332     int rv = BCM_E_NONE;
   5333 #if defined(CANCUN_SUPPORT)
   5334     if (soc_feature(unit, soc_feature_cancun)) {
   5335         if (src_tbl_is_stm != NULL) {
   5336             switch (port_type) {
   5337                 case _BCM_ESW_PT_COE:
   5338                 case _BCM_ESW_PT_HGPROXY:
   5339                     *src_tbl_is_stm = 1;
   5340                     break;
   5341                 default:
   5342                     *src_tbl_is_stm = 0;
   5343                     break;
   5344             }
   5345         }
   5346     }
   5347 #endif
   5348     return rv;
   5349 }
   5350 
   5351 #ifdef BCM_TRIUMPH2_SUPPORT
   5352 /*
   5353  * Function:
   5354  *      bcm_esw_port_lport_profile_recover
   5355  * Description:
   5356  *      Recovers the LPORT profile reference count in the
   5357  *      Source Trunk Map Table.
   5358  * Parameters:
   5359  *      unit        - (IN) Device number
   5360  * Return Value:
   5361  *      BCM_E_NONE
   5362  *      BCM_E_XXX
   5363  * Note:
   5364  *     - Called when LPORT profile is supported.
   5365  */
   5366 STATIC int
   5367 bcm_esw_port_lport_profile_recover(int unit)
   5368 {
   5369     int rv = BCM_E_NONE;
   5370 #ifdef BCM_TOMAHAWK3_SUPPORT
   5371     int entries_per_pipe;
   5372 #endif
   5373 #if defined(BCM_TRX_SUPPORT)
   5374     int i, m;
   5375     uint32 lport_index;
   5376     soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm};
   5377     int entry_count;
   5378     int table_sz;
   5379     uint32 *src_table;
   5380     uint32 *src_entry;
   5381     uint32 rtag7_index;
   5382     lport_tab_entry_t lport_entry;
   5383 
   5384     /* Make sure port module is initialized. */
   5385     PORT_INIT(unit);
   5386 
   5387     if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   5388         src_mem[1] = ING_DEVICE_PORTm;
   5389     }
   5390 
   5391     for (m = 0; m < 2; m++) {
   5392         if (src_mem[m] == INVALIDm) {
   5393             continue;
   5394         }
   5395 
   5396         /* Alloc DMA memory */
   5397         entry_count = soc_mem_index_count(unit, src_mem[m]);
   5398         table_sz = SOC_MEM_TABLE_BYTES(unit, src_mem[m]);
   5399         src_table = soc_cm_salloc(unit, table_sz, "LPORT index recover\n");
   5400         if (src_table == NULL) {
   5401             return BCM_E_MEMORY;
   5402         }
   5403         sal_memset(src_table, 0, table_sz);
   5404 
   5405         /* DMA Read */
   5406         rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY,
   5407                                 soc_mem_index_min(unit, src_mem[m]),
   5408                                 soc_mem_index_max(unit, src_mem[m]),
   5409                                 src_table);
   5410         /* Recover LPORT index reference count from Source Trunk Map table */
   5411         if (BCM_SUCCESS(rv)) {
   5412             for (i = 0; i < entry_count; i++) {
   5413                 src_entry =
   5414                     soc_mem_table_idx_to_pointer(unit, src_mem[m], void *,
   5415                                                  src_table, i);
   5416                 lport_index = soc_mem_field32_get(unit, src_mem[m], src_entry,
   5417                                                   LPORT_PROFILE_IDXf);
   5418 
   5419                 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   5420                     rv = _bcm_lport_ind_profile_mem_reference(unit, lport_index, 1);
   5421                     if (BCM_FAILURE(rv)) {
   5422                         break;
   5423                     }
   5424                     rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry);
   5425                     if (BCM_FAILURE(rv)) {
   5426                         break;
   5427                     }
   5428                     rtag7_index = soc_LPORT_TABm_field32_get(
   5429                             unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf);
   5430                     rv = _bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1);
   5431 
   5432                 } else {
   5433 #ifdef BCM_TOMAHAWK3_SUPPORT
   5434                     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5435                         entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm);
   5436                         rv = _bcm_lport_profile_mem_reference_unique(unit, lport_index,
   5437                                                                 1, i/entries_per_pipe);
   5438                     } else
   5439 #endif
   5440                     {
   5441                         rv = _bcm_lport_profile_mem_reference(unit, lport_index, 1);
   5442                     }
   5443                 }
   5444                 if (BCM_FAILURE(rv)) {
   5445                     break;
   5446                 }
   5447             }
   5448         }
   5449 
   5450         soc_cm_sfree(unit, src_table);
   5451         if (BCM_FAILURE(rv)) {
   5452             break;
   5453         }
   5454     }
   5455 
   5456 #endif /* BCM_TRX_SUPPORT */
   5457 
   5458     return rv;
   5459 }
   5460 
   5461 STATIC int
   5462 _bcm_td3_port_egr_lport_profile_recover(int unit)
   5463 {
   5464     int rv = BCM_E_NONE;
   5465     int i, m;
   5466     uint32 egr_lport_index;
   5467     soc_mem_t ep_mem[2] = {EGR_GPP_ATTRIBUTESm, INVALIDm};
   5468     int ega_num_entries;
   5469     int ega_table_size;
   5470     void *ep_tbl;
   5471     void *ep_ent;
   5472 
   5473     /* Make sure port module is initialized. */
   5474     PORT_INIT(unit);
   5475 
   5476     if (SOC_IS_TRIDENT3X(unit)) {
   5477         ep_mem[1] = EGR_PORTm;
   5478     }
   5479 
   5480     /* Alloc DMA memory */
   5481     for (m = 0; m < 2; m++) {
   5482         if (ep_mem[m] == INVALIDm) {
   5483             continue;
   5484         }
   5485         ega_num_entries = soc_mem_index_count(unit, ep_mem[m]);
   5486         ega_table_size = soc_mem_entry_words(unit, ep_mem[m]) * 4 * ega_num_entries;
   5487         ep_tbl = soc_cm_salloc(unit, ega_table_size,
   5488                                   "EGA for EGR LPORT index recover\n");
   5489         if (ep_tbl == NULL) {
   5490             return BCM_E_MEMORY;
   5491         }
   5492         sal_memset(ep_tbl, 0, ega_table_size);
   5493 
   5494         /* DMA Read */
   5495         rv = soc_mem_read_range(unit, ep_mem[m], MEM_BLOCK_ANY,
   5496                                 soc_mem_index_min(unit, ep_mem[m]),
   5497                                 soc_mem_index_max(unit, ep_mem[m]),
   5498                                 ep_tbl);
   5499         /* Recover EGR LPORT index reference count from EGR GPP Attributes table */
   5500         if (SOC_SUCCESS(rv)) {
   5501             for (i = 0; i < ega_num_entries; i++) {
   5502                 ep_ent =
   5503                     soc_mem_table_idx_to_pointer(unit, ep_mem[m],
   5504                                                  void *, ep_tbl, i);
   5505                 egr_lport_index =
   5506                     soc_mem_field32_get(unit, ep_mem[m], ep_ent, EGR_LPORT_PROFILE_IDXf);
   5507                 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1);
   5508                 if (BCM_FAILURE(rv)) {
   5509                     break;
   5510                 }
   5511             }
   5512         }
   5513 
   5514         soc_cm_sfree(unit, ep_tbl);
   5515 
   5516         if (BCM_FAILURE(rv)) {
   5517             break;
   5518         }
   5519     }
   5520 
   5521     return rv;
   5522 }
   5523 
   5524 /*
   5525  * Function:
   5526  *      bcm_esw_port_egr_lport_profile_recover
   5527  * Description:
   5528  *      Recovers the EGR LPORT profile reference count in the
   5529  *      EGR GPP Attributes Table.
   5530  * Parameters:
   5531  *      unit        - (IN) Device number
   5532  * Return Value:
   5533  *      BCM_E_NONE
   5534  *      BCM_E_XXX
   5535  * Note:
   5536  *     - Called when EGR LPORT profile is supported.
   5537  */
   5538 STATIC int
   5539 bcm_esw_port_egr_lport_profile_recover(int unit)
   5540 {
   5541     int rv = BCM_E_NONE;
   5542     int i;
   5543     uint32 egr_lport_index;
   5544     soc_mem_t ega_mem;
   5545     int ega_num_entries;
   5546     int ega_table_size;
   5547     egr_gpp_attributes_entry_t *ega_table;
   5548     egr_gpp_attributes_entry_t *ega_entry;
   5549 
   5550     /* Make sure port module is initialized. */
   5551     PORT_INIT(unit);
   5552 
   5553     if (SOC_IS_TRIDENT3X(unit)) {
   5554         return _bcm_td3_port_egr_lport_profile_recover(unit);
   5555     }
   5556 
   5557     /* Alloc DMA memory */
   5558     ega_mem = EGR_GPP_ATTRIBUTESm;
   5559     ega_num_entries = soc_mem_index_count(unit, ega_mem);
   5560     ega_table_size = sizeof(egr_gpp_attributes_entry_t ) * ega_num_entries;
   5561     ega_table = soc_cm_salloc(unit, ega_table_size,
   5562                               "EGA for EGR LPORT index recover\n");
   5563     if (ega_table == NULL) {
   5564         return BCM_E_MEMORY;
   5565     }
   5566     sal_memset(ega_table, 0, ega_table_size);
   5567 
   5568     /* DMA Read */
   5569     rv = soc_mem_read_range(unit, ega_mem, MEM_BLOCK_ANY,
   5570                             soc_mem_index_min(unit, ega_mem),
   5571                             soc_mem_index_max(unit, ega_mem),
   5572                             ega_table);
   5573 
   5574     /* Recover EGR LPORT index reference count from EGR GPP Attributes table */
   5575     if (SOC_SUCCESS(rv)) {
   5576         for (i = 0; i < ega_num_entries; i++) {
   5577             ega_entry =
   5578                 soc_mem_table_idx_to_pointer(unit, ega_mem,
   5579                                              egr_gpp_attributes_entry_t *,
   5580                                              ega_table, i);
   5581             egr_lport_index =
   5582                 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, ega_entry,
   5583                                                         EGR_LPORT_PROFILE_IDXf);
   5584             rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1);
   5585             if (BCM_FAILURE(rv)) {
   5586                 break;
   5587             }
   5588         }
   5589     }
   5590 
   5591     soc_cm_sfree(unit, ega_table);
   5592 
   5593     return rv;
   5594 }
   5595 #endif /* BCM_TRIUMPH2_SUPPORT */
   5596 
   5597 int
   5598 bcm_esw_port_egr_lport_prof_src_get(int unit,
   5599     bcm_module_t modid, bcm_port_t port, int *src_tbl_is_gpp)
   5600 {
   5601     int rv = BCM_E_NONE;
   5602 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   5603     bcm_xflow_macsec_port_info_t port_info;
   5604     port_info.enable = 0;
   5605 #endif
   5606 
   5607 #if defined(CANCUN_SUPPORT)
   5608     bcm_gport_t gport;
   5609 
   5610     if (soc_feature(unit, soc_feature_cancun)) {
   5611         soc_mem_t pfs_mem = EGR_PKT_FLOW_SELECT_TCAMm;
   5612 
   5613         gport = _bcm_esw_port_gport_get_from_modport(unit, modid, port);
   5614         /* COE flows use the port attrs from the EGR_GPP_ATTRIBUTES
   5615            table, rest all flows use the EGR_PORT table */
   5616         if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   5617             *src_tbl_is_gpp = 1;
   5618 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   5619         } else if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) &&
   5620        (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) &&
   5621        (port_info.enable == 1)) {
   5622             *src_tbl_is_gpp = 1;
   5623 #endif
   5624         } else if (SOC_MEM_IS_VALID(unit, pfs_mem)) {
   5625             *src_tbl_is_gpp = 0;
   5626         }
   5627     }
   5628 #endif
   5629 
   5630     return rv;
   5631 }
   5632 
   5633 #if defined(BCM_TRX_SUPPORT)
   5634 /*
   5635  * Function:
   5636  *      bcm_esw_port_separate_lport_rtag7_profile_fields_set
   5637  * Description:
   5638  *      Sets the fields in the LPORT Profile Table and updates
   5639  *      the corresponding reference index in the Source Trunk Map Table.
   5640  * Parameters:
   5641  *      unit        - (IN) Device number
   5642  *      modid       - (IN) Module number for port
   5643  *      port        - (IN) Port number (NON gport)
   5644  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   5645  *      field_count - (IN) Number of fields to modify
   5646  *      fields      - (IN) Array of fields to modify
   5647  *      values      - (IN) Array of new field values
   5648  * Return Value:
   5649  *      BCM_E_NONE
   5650  *      BCM_E_XXX
   5651  * Note:
   5652  *     - Assumes: lock,
   5653  *                valid bcm module id and port number,
   5654  *                valid table id,
   5655  *                valid HW fields.
   5656  *     - Called when LPORT profile is supported.
   5657  *     - Helper routine for bcm_esw_port_lport_fields_set();
   5658  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   5659  */
   5660 STATIC int
   5661 bcm_esw_port_separate_lport_rtag7_profile_fields_set(int unit, int port_type,
   5662                                       bcm_module_t modid, bcm_port_t port,
   5663                                       int table_id, int field_count,
   5664                                       soc_field_t *fields, uint32 *values)
   5665 {
   5666     int i, rv;
   5667     int src_index;
   5668     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   5669     lport_tab_entry_t lport_entry;
   5670     rtag7_port_based_hash_entry_t  rtag7_entry;
   5671     uint32 lport_index, rtag7_index, old_lport_index, old_rtag7_index = 0;
   5672     soc_mem_t mem;
   5673     void *entries[2], *entry;
   5674 
   5675     int src_tbl_is_stm = 1;
   5676     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   5677 
   5678     /* Make sure port module is initialized. */
   5679     PORT_INIT(unit);
   5680 
   5681     BCM_IF_ERROR_RETURN
   5682         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   5683     if (!src_tbl_is_stm) {
   5684         src_mem = ING_DEVICE_PORTm;
   5685     }
   5686 
   5687     soc_mem_lock(unit, src_mem);
   5688 
   5689     if (src_tbl_is_stm) {
   5690         rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   5691                                                    &src_index);
   5692         if (BCM_FAILURE(rv)) {
   5693             soc_mem_unlock(unit, src_mem);
   5694             return rv;
   5695         }
   5696     } else {
   5697         src_index = port;
   5698     }
   5699 
   5700     rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent);
   5701     if (BCM_FAILURE(rv)) {
   5702         soc_mem_unlock(unit, src_mem);
   5703         return rv;
   5704     }
   5705 
   5706     old_lport_index =
   5707         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   5708 
   5709     if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5710 
   5711         /* Get the associated LPORT entry */
   5712         rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index,
   5713                              &lport_entry);
   5714         if(BCM_FAILURE(rv)) {
   5715             soc_mem_unlock(unit, src_mem);
   5716             return rv;
   5717         }
   5718 
   5719         /* Get the current RTAG7 index from there */
   5720         old_rtag7_index =
   5721             soc_LPORT_TABm_field32_get(unit, &lport_entry,
   5722                                                     RTAG7_PORT_PROFILE_INDEXf);
   5723     }
   5724 
   5725     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5726         entries[0] = &lport_entry;
   5727         rv = _bcm_lport_ind_profile_entry_get(unit, old_lport_index,
   5728                                               1, entries);
   5729     } else {
   5730         entries[0] = &rtag7_entry;
   5731         rv = _bcm_rtag7_ind_profile_entry_get(unit, old_rtag7_index,
   5732                                               1, entries);
   5733     }
   5734 
   5735     if(BCM_FAILURE(rv)) {
   5736         soc_mem_unlock(unit, src_mem);
   5737         return rv;
   5738     }
   5739 
   5740     /* Update fields */
   5741     entry = entries[0];
   5742     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5743         mem = LPORT_TABm;
   5744     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5745         mem = RTAG7_PORT_BASED_HASHm;
   5746     } else {
   5747         soc_mem_unlock(unit, src_mem);
   5748         return BCM_E_INTERNAL;
   5749     }
   5750 
   5751     for (i = 0; i < field_count; i++) {
   5752         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   5753     }
   5754 
   5755     /* Note that when 'soc_feature_separate_ing_lport_rtag7_profiling' is in
   5756        effect, the LPORT and RTAG7 tables are profiled separately, due to which
   5757        we will be making separate calls and not a generic single call like
   5758        earlier */
   5759     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5760 
   5761 #ifdef BCM_MONTEREY_SUPPORT
   5762         if (SOC_IS_MONTEREY(unit)) {
   5763             soc_mem_field32_set(unit, mem, entry, MISC_PORT_PROFILE_INDEXf, port);
   5764         }
   5765 #endif
   5766 
   5767         rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index);
   5768 
   5769     } else {
   5770         rv = _bcm_rtag7_ind_profile_entry_add(unit, entries, 1, &rtag7_index);
   5771     }
   5772 
   5773     if(BCM_FAILURE(rv)) {
   5774         soc_mem_unlock(unit, src_mem);
   5775         return rv;
   5776     }
   5777 
   5778     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5779         /* Update Source Table LPORT profile index  */
   5780         soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf,
   5781                             lport_index);
   5782         rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, src_index, src_ent);
   5783     } else {
   5784         /* Write to the LPORT table here */
   5785         soc_LPORT_TABm_field32_set(unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf,
   5786                                          rtag7_index);
   5787         if (SOC_IS_TRIDENT3X(unit)) {
   5788             entries[0] = &lport_entry;
   5789             rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index);
   5790 
   5791             if(BCM_FAILURE(rv)) {
   5792                soc_mem_unlock(unit, src_mem);
   5793                return rv;
   5794             }
   5795             /* Update Source Table LPORT profile index  */
   5796             soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf,
   5797                                 lport_index);
   5798             rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL,
   5799                                src_index, src_ent);
   5800         } else {
   5801             rv = WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, &lport_entry);
   5802         }
   5803     }
   5804 
   5805     soc_mem_unlock(unit, src_mem);
   5806     if(BCM_FAILURE(rv)) {
   5807         return rv;
   5808     }
   5809 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   5810     if (SOC_IS_HURRICANE4(unit) &&
   5811         (port_type == _BCM_ESW_PT_MACSEC_PORT)) {
   5812         /* Also update STM LPORT profile index  */
   5813         src_mem = SOURCE_TRUNK_MAP_TABLEm;
   5814         soc_mem_lock(unit, src_mem);
   5815         rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index);
   5816         if (BCM_FAILURE(rv)) {
   5817             soc_mem_unlock(unit, src_mem);
   5818             return rv;
   5819         }
   5820         rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent);
   5821         if (BCM_FAILURE(rv)) {
   5822             soc_mem_unlock(unit, src_mem);
   5823             return rv;
   5824         }
   5825         if (old_lport_index != lport_index) {
   5826             soc_mem_field32_set(unit, src_mem, src_ent,
   5827                                 LPORT_PROFILE_IDXf, lport_index);
   5828             rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL,
   5829                                src_index, src_ent);
   5830         }
   5831         soc_mem_unlock(unit, src_mem);
   5832         if (BCM_FAILURE(rv)) {
   5833             return rv;
   5834         }
   5835     }
   5836 #endif
   5837 
   5838     /*
   5839      * Entry must be 'deleted' because the mem profile 'add' routine
   5840      * always increments count even though the same entry is used.
   5841      */
   5842     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5843         BCM_IF_ERROR_RETURN
   5844             (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index));
   5845 
   5846     } else {
   5847         if (SOC_IS_TRIDENT3X(unit)) {
   5848             BCM_IF_ERROR_RETURN
   5849                   (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index));
   5850         }
   5851         BCM_IF_ERROR_RETURN
   5852             (_bcm_rtag7_ind_profile_entry_delete(unit, old_rtag7_index));
   5853     }
   5854 
   5855     return BCM_E_NONE;
   5856 }
   5857 #endif /* BCM_TRX_SUPPORT */
   5858 
   5859 /*
   5860  * Function:
   5861  *      bcm_esw_port_lport_profile_fields_set
   5862  * Description:
   5863  *      Sets the fields in the LPORT Profile Table and updates
   5864  *      the corresponding reference index in the Source Trunk Map Table.
   5865  * Parameters:
   5866  *      unit        - (IN) Device number
   5867  *      modid       - (IN) Module number for port
   5868  *      port        - (IN) Port number (NON gport)
   5869  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   5870  *      field_count - (IN) Number of fields to modify
   5871  *      fields      - (IN) Array of fields to modify
   5872  *      values      - (IN) Array of new field values
   5873  * Return Value:
   5874  *      BCM_E_NONE
   5875  *      BCM_E_XXX
   5876  * Note:
   5877  *     - Assumes: lock,
   5878  *                valid bcm module id and port number,
   5879  *                valid table id,
   5880  *                valid HW fields.
   5881  *     - Called when LPORT profile is supported.
   5882  *     - Helper routine for bcm_esw_port_lport_fields_set();
   5883  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   5884  */
   5885 STATIC int
   5886 bcm_esw_port_lport_profile_fields_set(int unit, int port_type,
   5887                                       bcm_module_t modid, bcm_port_t port,
   5888                                       int table_id, int field_count,
   5889                                       soc_field_t *fields, uint32 *values)
   5890 {
   5891 #if defined(BCM_TRX_SUPPORT)
   5892     int i;
   5893     int src_index;
   5894     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   5895     int src_tbl_is_stm = 1;
   5896     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   5897     lport_tab_entry_t lport_entry;
   5898     rtag7_port_based_hash_entry_t  rtag7_entry;
   5899     uint32 lport_index, old_lport_index;
   5900     void *entries[2];
   5901     soc_mem_t mem;
   5902     void *entry;
   5903     int rv;
   5904     int pipe = 0;
   5905     int num_entries_per_pipe = 0;
   5906 
   5907     if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   5908         return bcm_esw_port_separate_lport_rtag7_profile_fields_set(unit,
   5909                     port_type, modid, port, table_id, field_count,
   5910                     fields, values);
   5911     }
   5912 
   5913     /* Make sure port module is initialized. */
   5914     PORT_INIT(unit);
   5915 
   5916     BCM_IF_ERROR_RETURN
   5917         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   5918 #if defined(CANCUN_SUPPORT)
   5919     if (soc_feature(unit, soc_feature_cancun) && src_tbl_is_stm == 0) {
   5920         src_mem = ING_DEVICE_PORTm;
   5921     }
   5922 #endif
   5923 
   5924     soc_mem_lock(unit, src_mem);
   5925 
   5926     /* Get LPORT profile index Source table */
   5927     if (src_tbl_is_stm) {
   5928         rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index);
   5929         if (BCM_FAILURE(rv)) {
   5930             soc_mem_unlock(unit, src_mem);
   5931             return rv;
   5932         }
   5933     } else {
   5934         src_index = port;
   5935     }
   5936 
   5937     rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent);
   5938     if (BCM_FAILURE(rv)) {
   5939         soc_mem_unlock(unit, src_mem);
   5940         return rv;
   5941     }
   5942 
   5943     old_lport_index =
   5944         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   5945 
   5946     /* Get LPORT profile entry */
   5947     entries[0] = &lport_entry;
   5948     entries[1] = &rtag7_entry;
   5949 
   5950     /* Tomahawk 3 split this memory into a per pipe unique access,
   5951      * so it is indexed in SOURCE_TRUNK_MAP on a per pipe basis */
   5952     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5953         pipe = SOC_INFO(unit).port_pipe[src_index];
   5954         mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe];
   5955         num_entries_per_pipe = SOC_MEM_SIZE(unit, mem);
   5956 
   5957         /* the profile cache is stored in one large logical table (all the pipes
   5958          * put together), so we need to index into the pipe being used so that
   5959          * we can access the index of that one big logical table */
   5960         old_lport_index += pipe*num_entries_per_pipe;
   5961     }
   5962 
   5963     rv = _bcm_lport_profile_entry_get(unit, old_lport_index, 1, entries);
   5964     if (BCM_FAILURE(rv)) {
   5965         soc_mem_unlock(unit, src_mem);
   5966         return rv;
   5967     }
   5968 
   5969     /* Update fields */
   5970     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5971         mem = LPORT_TABm;
   5972         entry = entries[0];
   5973     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5974         mem = RTAG7_PORT_BASED_HASHm;
   5975         entry = entries[1];
   5976     } else {
   5977         soc_mem_unlock(unit, src_mem);
   5978         return BCM_E_INTERNAL;
   5979     }
   5980 
   5981     for (i = 0; i < field_count; i++) {
   5982         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   5983     }
   5984 
   5985     /* Tomahawk 3 split this memory into a per pipe unique access,
   5986      * so it must be handled differently */
   5987     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5988         /* Restore the old_lport_index to its per pipe index because the call
   5989          * below to entry_add_unique will get its lport_index based on a per
   5990          * pipe index and they will be compared. */
   5991         old_lport_index -= pipe*num_entries_per_pipe;
   5992 
   5993         rv = _bcm_lport_profile_entry_add_unique(unit, entries, 1, pipe, &lport_index);
   5994     } else {
   5995         rv = _bcm_lport_profile_entry_add(unit, entries, 1, &lport_index);
   5996     }
   5997     if(BCM_FAILURE(rv)) {
   5998         soc_mem_unlock(unit, src_mem);
   5999         return rv;
   6000     }
   6001 
   6002     /* Update STM LPORT profile index  */
   6003     if (old_lport_index != lport_index) {
   6004         soc_mem_field32_set(unit, src_mem, src_ent,
   6005                             LPORT_PROFILE_IDXf, lport_index);
   6006         rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL,
   6007                            src_index, src_ent);
   6008     }
   6009 
   6010     soc_mem_unlock(unit, src_mem);
   6011     if (BCM_FAILURE(rv)) {
   6012         return rv;
   6013     }
   6014     /*
   6015      * Entry must be 'deleted' because the mem profile 'add' routine
   6016      * always increments count even though the same entry is used.
   6017      */
   6018     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   6019         BCM_IF_ERROR_RETURN
   6020             (_bcm_lport_profile_entry_delete_unique(unit, old_lport_index, pipe));
   6021     } else {
   6022         BCM_IF_ERROR_RETURN
   6023             (_bcm_lport_profile_entry_delete(unit, old_lport_index));
   6024     }
   6025 
   6026     return BCM_E_NONE;
   6027 #else
   6028     return BCM_E_UNAVAIL;
   6029 #endif /* BCM_TRX_SUPPORT */
   6030 }
   6031 
   6032 /*
   6033  * Function:
   6034  *      bcm_esw_port_egr_lport_profile_fields_set
   6035  * Description:
   6036  *      Sets the fields in the EGR_LPORT Profile Table and updates
   6037  *      the corresponding reference index in the Source Trunk Map Table.
   6038  * Parameters:
   6039  *      unit        - (IN) Device number
   6040  *      modid       - (IN) Module number for port
   6041  *      port        - (IN) Port number (NON gport)
   6042  *      mem         - (IN) Table to modify
   6043  *      field_count - (IN) Number of fields to modify
   6044  *      fields      - (IN) Array of fields to modify
   6045  *      values      - (IN) Array of new field values
   6046  * Return Value:
   6047  *      BCM_E_NONE
   6048  *      BCM_E_XXX
   6049  * Note:
   6050  *     - Assumes: lock,
   6051  *                valid bcm module id and port number,
   6052  *                valid table id,
   6053  *                valid HW fields.
   6054  *     - Called when EGR_LPORT profile is supported.
   6055  *     - Helper routine for bcm_esw_port_egr_lport_fields_set();
   6056  *       callers should be calling bcm_esw_port_egr_lport_fields_set() instead.
   6057  */
   6058 STATIC int
   6059 bcm_esw_port_egr_lport_profile_fields_set(int unit,
   6060                                       bcm_module_t modid, bcm_port_t port,
   6061                                       soc_mem_t mem, int field_count,
   6062                                       soc_field_t *fields, uint32 *values)
   6063 {
   6064 #if defined(BCM_TRX_SUPPORT)
   6065     int i, index;
   6066     int egr_gpp_index = 0;
   6067     egr_gpp_attributes_entry_t egr_gpp_entry;
   6068     egr_lport_profile_entry_t egr_lport_entry;
   6069     egr_vlan_control_1_entry_t egr_vlan_control_1;
   6070     egr_vlan_control_2_entry_t egr_vlan_control_2;
   6071     egr_vlan_control_3_entry_t egr_vlan_control_3;
   6072     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   6073     egr_mtu_entry_t egr_mtu;
   6074     egr_port_1_entry_t egr_port_1;
   6075     egr_counter_control_entry_t egr_counter_control;
   6076     egr_shaping_control_entry_t egr_shaping_control;
   6077     egr_port_entry_t egr_port;
   6078     uint32 egr_lport_index, old_egr_lport_index;
   6079     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   6080     void *entry;
   6081     int use_gpp_index = 1;
   6082 
   6083     /* Make sure port module is initialized. */
   6084     PORT_INIT(unit);
   6085 
   6086     if (mem == EGR_GPP_ATTRIBUTESm) {
   6087         BCM_IF_ERROR_RETURN
   6088             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6089                                                    &egr_gpp_index));
   6090         BCM_IF_ERROR_RETURN
   6091             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6092                                       egr_gpp_index, &egr_gpp_entry));
   6093         for (i = 0; i < field_count; i++) {
   6094             soc_mem_field32_set(unit, EGR_GPP_ATTRIBUTESm,
   6095                                 &egr_gpp_entry, fields[i], values[i]);
   6096         }
   6097         BCM_IF_ERROR_RETURN
   6098             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL,
   6099                                        egr_gpp_index, &egr_gpp_entry));
   6100 
   6101         return BCM_E_NONE;
   6102     }
   6103 
   6104     BCM_IF_ERROR_RETURN(
   6105         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6106 
   6107     if (use_gpp_index) {
   6108         /* Get LPORT profile index Source Trunk Map table */
   6109         BCM_IF_ERROR_RETURN
   6110             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6111                                                    &egr_gpp_index));
   6112         BCM_IF_ERROR_RETURN
   6113             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6114                                       egr_gpp_index, &egr_gpp_entry));
   6115         old_egr_lport_index =
   6116             soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6117                                                 EGR_LPORT_PROFILE_IDXf);
   6118     } else {
   6119         BCM_IF_ERROR_RETURN
   6120             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port));
   6121         old_egr_lport_index =
   6122             soc_mem_field32_get(unit, EGR_PORTm, &egr_port,
   6123                                 EGR_LPORT_PROFILE_IDXf);
   6124     }
   6125 
   6126     /* Get LPORT profile entry */
   6127     index = 0;
   6128     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6129         entries[index++] = &egr_lport_entry;
   6130     }
   6131     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6132         entries[index++] = &egr_vlan_control_1;
   6133     }
   6134     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6135         entries[index++] = &egr_vlan_control_2;
   6136     }
   6137     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6138         entries[index++] = &egr_vlan_control_3;
   6139     }
   6140     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6141         entries[index++] = &egr_ipmc_cfg2;
   6142     }
   6143     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6144         entries[index++] = &egr_mtu;
   6145     }
   6146     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6147         entries[index++] = &egr_port_1;
   6148     }
   6149     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6150         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6151             entries[index++] = &egr_counter_control;
   6152         }
   6153         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6154             entries[index++] = &egr_shaping_control;
   6155         }
   6156     }
   6157 
   6158     BCM_IF_ERROR_RETURN
   6159         (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries));
   6160 
   6161     BCM_IF_ERROR_RETURN
   6162         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6163     entry = entries[index];
   6164     /* Update fields */
   6165     for (i = 0; i < field_count; i++) {
   6166         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   6167     }
   6168 
   6169     BCM_IF_ERROR_RETURN
   6170         (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index));
   6171 
   6172     /* Update STM LPORT profile index  */
   6173     if (use_gpp_index) {
   6174         soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry,
   6175                                             EGR_LPORT_PROFILE_IDXf,
   6176                                             egr_lport_index);
   6177         BCM_IF_ERROR_RETURN
   6178             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6179                                        egr_gpp_index, &egr_gpp_entry));
   6180     } else {
   6181         soc_mem_field32_set(unit, EGR_PORTm, &egr_port,
   6182                             EGR_LPORT_PROFILE_IDXf, egr_lport_index);
   6183         BCM_IF_ERROR_RETURN
   6184             (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port));
   6185     }
   6186     /*
   6187      * Entry must be 'deleted' because the mem profile 'add' routine
   6188      * always increments count even though the same entry is used.
   6189      */
   6190     if (old_egr_lport_index != 0) {
   6191         BCM_IF_ERROR_RETURN
   6192             (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index));
   6193     }
   6194 
   6195     return BCM_E_NONE;
   6196 #else
   6197     return BCM_E_UNAVAIL;
   6198 #endif /* BCM_TRX_SUPPORT */
   6199 }
   6200 
   6201 /*
   6202  * Function:
   6203  *      bcm_esw_port_egr_lport_profile_clear
   6204  * Description:
   6205  *      Similar function as bcm_esw_port_egr_lport_profile_fields_set,
   6206  *      for clear purpose only.
   6207  */
   6208 STATIC int
   6209 bcm_esw_port_egr_lport_profile_clear(int unit,
   6210                                      bcm_module_t modid, bcm_port_t port,
   6211                                      soc_mem_t mem)
   6212 {
   6213 #if defined(BCM_TRX_SUPPORT)
   6214     int index;
   6215     int egr_gpp_index = 0;
   6216     egr_gpp_attributes_entry_t egr_gpp_entry;
   6217     egr_lport_profile_entry_t egr_lport_entry;
   6218     egr_vlan_control_1_entry_t egr_vlan_control_1;
   6219     egr_vlan_control_2_entry_t egr_vlan_control_2;
   6220     egr_vlan_control_3_entry_t egr_vlan_control_3;
   6221     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   6222     egr_mtu_entry_t egr_mtu;
   6223     egr_port_1_entry_t egr_port_1;
   6224     egr_counter_control_entry_t egr_counter_control;
   6225     egr_shaping_control_entry_t egr_shaping_control;
   6226     egr_port_entry_t egr_port;
   6227     uint32 egr_lport_index, old_egr_lport_index;
   6228     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   6229     void *entry;
   6230     int ent_size[_BCM_EGR_LPROF_MEM_COUNT] = {0};
   6231     int use_gpp_index = 1;
   6232 
   6233     /* Make sure port module is initialized. */
   6234     PORT_INIT(unit);
   6235 
   6236     if (mem == EGR_GPP_ATTRIBUTESm) {
   6237         BCM_IF_ERROR_RETURN
   6238             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6239                                                    &egr_gpp_index));
   6240         BCM_IF_ERROR_RETURN
   6241             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6242                                       egr_gpp_index, &egr_gpp_entry));
   6243         sal_memset(&egr_gpp_entry, 0, sizeof(egr_gpp_entry));
   6244         BCM_IF_ERROR_RETURN
   6245             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL,
   6246                                        egr_gpp_index, &egr_gpp_entry));
   6247 
   6248         return BCM_E_NONE;
   6249     }
   6250 
   6251     BCM_IF_ERROR_RETURN(
   6252         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6253 
   6254     if (use_gpp_index) {
   6255         /* Get LPORT profile index Source Trunk Map table */
   6256         BCM_IF_ERROR_RETURN
   6257             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6258                                                    &egr_gpp_index));
   6259         BCM_IF_ERROR_RETURN
   6260             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6261                                       egr_gpp_index, &egr_gpp_entry));
   6262         old_egr_lport_index =
   6263             soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6264                                                 EGR_LPORT_PROFILE_IDXf);
   6265     } else {
   6266         BCM_IF_ERROR_RETURN
   6267             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port));
   6268         old_egr_lport_index =
   6269             soc_mem_field32_get(unit, EGR_PORTm, &egr_port,
   6270                                 EGR_LPORT_PROFILE_IDXf);
   6271     }
   6272 
   6273     /* Get LPORT profile entry */
   6274     index = 0;
   6275     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6276         ent_size[index] = sizeof(egr_lport_entry);
   6277         entries[index++] = &egr_lport_entry;
   6278     }
   6279     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6280         ent_size[index] = sizeof(egr_vlan_control_1);
   6281         entries[index++] = &egr_vlan_control_1;
   6282     }
   6283     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6284         ent_size[index] = sizeof(egr_vlan_control_2);
   6285         entries[index++] = &egr_vlan_control_2;
   6286     }
   6287     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6288         ent_size[index] = sizeof(egr_vlan_control_3);
   6289         entries[index++] = &egr_vlan_control_3;
   6290     }
   6291     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6292         ent_size[index] = sizeof(egr_ipmc_cfg2);
   6293         entries[index++] = &egr_ipmc_cfg2;
   6294     }
   6295     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6296         ent_size[index] = sizeof(egr_mtu);
   6297         entries[index++] = &egr_mtu;
   6298     }
   6299     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6300         ent_size[index] = sizeof(egr_port_1);
   6301         entries[index++] = &egr_port_1;
   6302     }
   6303     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6304         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6305             ent_size[index] = sizeof(egr_counter_control);
   6306             entries[index++] = &egr_counter_control;
   6307         }
   6308         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6309             ent_size[index] = sizeof(egr_shaping_control);
   6310             entries[index++] = &egr_shaping_control;
   6311         }
   6312     }
   6313 
   6314     BCM_IF_ERROR_RETURN
   6315         (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries));
   6316 
   6317     BCM_IF_ERROR_RETURN
   6318         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6319     entry = entries[index];
   6320     /* Clear fields */
   6321     sal_memset(entry, 0, ent_size[index]);
   6322 
   6323     BCM_IF_ERROR_RETURN
   6324         (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index));
   6325 
   6326     /* Update STM LPORT profile index  */
   6327     if (use_gpp_index) {
   6328         soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry,
   6329                                             EGR_LPORT_PROFILE_IDXf,
   6330                                             egr_lport_index);
   6331         BCM_IF_ERROR_RETURN
   6332             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6333                                        egr_gpp_index, &egr_gpp_entry));
   6334     } else {
   6335         soc_mem_field32_set(unit, EGR_PORTm, &egr_port,
   6336                             EGR_LPORT_PROFILE_IDXf, egr_lport_index);
   6337         BCM_IF_ERROR_RETURN
   6338             (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port));
   6339     }
   6340     /*
   6341      * Entry must be 'deleted' because the mem profile 'add' routine
   6342      * always increments count even though the same entry is used.
   6343      */
   6344     if (old_egr_lport_index != 0) {
   6345         BCM_IF_ERROR_RETURN
   6346             (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index));
   6347     }
   6348 
   6349     return BCM_E_NONE;
   6350 #else
   6351     return BCM_E_UNAVAIL;
   6352 #endif /* BCM_TRX_SUPPORT */
   6353 }
   6354 
   6355 /*
   6356  * Function:
   6357  *      _bcm_esw_egr_port_tab_multi_set
   6358  * Description:
   6359  *      Function to set multiple fields in EGR port tables
   6360  * Parameters:
   6361  *      unit        - Device number
   6362  *      port        - Port number
   6363  *      field_count - Number of fields to modify
   6364  *      fields      - Array of fields to modify
   6365  *      values      - Array of new field values
   6366  * Return Value:
   6367  *      BCM_E_NONE
   6368  *      BCM_E_XXX - an error occurred accessing EGR_PORT table.
   6369  */
   6370 int
   6371 _bcm_esw_egr_port_tab_multi_set(int unit, bcm_port_t port, int field_count,
   6372         soc_field_t *fields, uint32 *values)
   6373 
   6374 {
   6375     soc_mem_t mem = EGR_PORTm;
   6376     int rv = BCM_E_NONE, i, index;
   6377 
   6378     soc_field_t egr_port_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   6379     uint32 egr_port_tab_values[SOC_MAX_MEM_FIELD_NUM];
   6380     int egr_port_tab_field_count = 0;
   6381     soc_field_t egr_lport_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   6382     uint32 egr_lport_tab_values[SOC_MAX_MEM_FIELD_NUM];
   6383     int egr_lport_tab_field_count = 0;
   6384     soc_field_t egr_gpp_fields[SOC_MAX_MEM_FIELD_NUM];
   6385     uint32 egr_gpp_values[SOC_MAX_MEM_FIELD_NUM];
   6386     int egr_gpp_field_count = 0;
   6387 #if defined BCM_HGPROXY_COE_SUPPORT
   6388     int is_lport_cfg = 0;
   6389 #endif
   6390 
   6391 
   6392     if ((fields == NULL) || (values == NULL) ) {
   6393         return BCM_E_PARAM;
   6394     }
   6395     if (field_count <= 0) {
   6396         return BCM_E_NONE;
   6397     }
   6398 
   6399 #if defined BCM_HGPROXY_COE_SUPPORT
   6400     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   6401         (soc_feature(unit, soc_feature_channelized_switching))) &&
   6402         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6403         is_lport_cfg = 1;
   6404     }
   6405 
   6406     if (is_lport_cfg == 1) {
   6407         mem = EGR_LPORT_PROFILEm;
   6408     } else
   6409 #endif
   6410     if (BCM_GPORT_IS_SET(port)) {
   6411         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   6412     }
   6413 
   6414     for(i = 0; i < field_count; i++) {
   6415 #if defined(CANCUN_SUPPORT)
   6416         if (SOC_IS_TRIDENT3X(unit)) {
   6417             if (soc_cancun_cmh_check(unit, mem, fields[i]) == SOC_E_NONE) {
   6418                 rv = soc_cancun_cmh_mem_set(unit, mem, port, fields[i],
   6419                                             values[i]);
   6420             }
   6421             _bcm_td3_egr_port_tab_conv(unit, &fields[i], &mem);
   6422         }
   6423 #endif
   6424         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   6425             return (SOC_E_UNAVAIL);
   6426         }
   6427 
   6428         switch (mem) {
   6429             case EGR_GPP_ATTRIBUTESm:
   6430                 soc_mem_set_field_value_array(egr_gpp_fields, fields[i],
   6431                                               egr_gpp_values, values[i],
   6432                                               egr_gpp_field_count);
   6433                 break;
   6434             case EGR_PORTm:
   6435                 soc_mem_set_field_value_array(egr_port_tab_fields, fields[i],
   6436                                               egr_port_tab_values, values[i],
   6437                                               egr_port_tab_field_count);
   6438                 break;
   6439             case EGR_LPORT_PROFILEm:
   6440                 soc_mem_set_field_value_array(egr_lport_tab_fields, fields[i],
   6441                                               egr_lport_tab_values, values[i],
   6442                                               egr_lport_tab_field_count);
   6443                 break;
   6444             default:
   6445                 BCM_IF_ERROR_RETURN
   6446                     (soc_mem_field32_modify(unit, mem, port, fields[i],
   6447                                             values[i]));
   6448                 break;
   6449         }
   6450     }
   6451 
   6452 #if defined BCM_HGPROXY_COE_SUPPORT
   6453     if (is_lport_cfg == 1) { /* remote port */
   6454         return bcm_esw_port_egr_lport_fields_set(unit, port,
   6455                                                  EGR_LPORT_PROFILEm,
   6456                                                  egr_lport_tab_field_count,
   6457                                                  egr_lport_tab_fields,
   6458                                                  egr_lport_tab_values);
   6459     }
   6460 #endif
   6461 
   6462     index = SOC_PORT_MOD_OFFSET(unit, port);
   6463 
   6464     if (egr_port_tab_field_count) {
   6465         rv = soc_mem_fields32_modify(unit, EGR_PORTm, index,
   6466                                      egr_port_tab_field_count,
   6467                                      egr_port_tab_fields, egr_port_tab_values);
   6468     }
   6469 
   6470     if (egr_lport_tab_field_count && BCM_SUCCESS(rv)) {
   6471         rv = bcm_esw_port_egr_lport_fields_set(unit, index,
   6472                 EGR_LPORT_PROFILEm, egr_lport_tab_field_count,
   6473                 egr_lport_tab_fields, egr_lport_tab_values);
   6474     }
   6475 
   6476     if (egr_gpp_field_count && BCM_SUCCESS(rv)) {
   6477         rv = bcm_esw_port_egr_lport_fields_set(unit, index,
   6478                 EGR_GPP_ATTRIBUTESm, egr_gpp_field_count,
   6479                 egr_gpp_fields, egr_gpp_values);
   6480     }
   6481 
   6482     return rv;
   6483 }
   6484 
   6485 /*
   6486  * Function:
   6487  *      _bcm_esw_egr_port_tab_set
   6488  * Description:
   6489  *      Helper funtion for bcm_esw_port_control_set.
   6490  * Parameters:
   6491  *      unit  - Device number
   6492  *      port  - Port number
   6493  *      field - Field name within EGR_PORT table entry
   6494  *      value - new field value
   6495  * Return Value:
   6496  *      BCM_E_NONE
   6497  *      BCM_E_XXX - an error occurred accessing EGR_PORT table.
   6498  */
   6499 int
   6500 _bcm_esw_egr_port_tab_set(int unit, bcm_port_t port,
   6501         soc_field_t field, uint32 value)
   6502 
   6503 {
   6504     return (_bcm_esw_egr_port_tab_multi_set(unit, port, 1, &field, &value));
   6505 }
   6506 
   6507 /*
   6508  * Function:
   6509  *      _bcm_esw_egr_port_tab_get
   6510  * Description:
   6511  *      Helper funtion for bcm_esw_port_control_get.
   6512  * Parameters:
   6513  *      unit  - Device number
   6514  *      port  - Port number
   6515  *      field - Field name within PORT_TAB table entry
   6516  *      value - (OUT) field value
   6517  * Return Value:
   6518  *      BCM_E_NONE
   6519  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   6520  * Notes:
   6521  *      Due to the large number of callers for this routine,
   6522  *      function is expanded to take a GPORT PROXY, which
   6523  *      get the property from the LPORT profile table.
   6524  *
   6525  *      Current valid port types are:
   6526  *          GPORT SUBPORT
   6527  *          BCM port (non-gport), assumes a valid local physical port
   6528  */
   6529 
   6530 int
   6531 _bcm_esw_egr_port_tab_get(int unit, bcm_port_t port,
   6532                           soc_field_t field, int *value)
   6533 {
   6534     int rv = BCM_E_UNAVAIL;
   6535     egr_port_entry_t pent;
   6536     soc_mem_t mem;
   6537     int index, is_lport_cfg = 0, is_gpp_attr = 0;
   6538     uint32 value32;
   6539 
   6540     mem = EGR_PORTm;
   6541 #if defined(BCM_TRIDENT3_SUPPORT)
   6542     if (SOC_IS_TRIDENT3X(unit)) {
   6543         BCM_IF_ERROR_RETURN(_bcm_td3_egr_port_tab_conv(unit, &field, &mem));
   6544         if (mem == EGR_GPP_ATTRIBUTESm) {
   6545             is_gpp_attr = 1;
   6546         } else if (mem != EGR_PORTm) {
   6547             is_lport_cfg = 1;
   6548         }
   6549     }
   6550 #endif
   6551 
   6552     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   6553         return (BCM_E_UNAVAIL);
   6554     }
   6555 
   6556 #if defined BCM_HGPROXY_COE_SUPPORT
   6557     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   6558         soc_feature(unit, soc_feature_channelized_switching)) &&
   6559         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6560         is_lport_cfg = 1;
   6561     } else
   6562 #endif
   6563     if (BCM_GPORT_IS_PROXY(port)) {
   6564         is_lport_cfg = 1;
   6565     }
   6566 
   6567     /* If LPORT, then get property from LPORT table */
   6568     if (is_lport_cfg) {
   6569         rv = bcm_esw_port_egr_lport_field_get(unit, port,
   6570                                               EGR_LPORT_PROFILEm,
   6571                                               field, &value32);
   6572         *value = value32;
   6573         return rv;
   6574     } else if (is_gpp_attr) {
   6575         rv = bcm_esw_port_egr_lport_field_get(unit, port,
   6576                                               EGR_GPP_ATTRIBUTESm,
   6577                                               field, &value32);
   6578         *value = value32;
   6579         return rv;
   6580     }
   6581 
   6582     /* At this point, 'port' needs to be a BCM port (non-gport) */
   6583     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   6584 
   6585     index = SOC_PORT_MOD_OFFSET(unit, port);
   6586     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent);
   6587 
   6588     if (BCM_SUCCESS(rv)) {
   6589         *value = soc_mem_field32_get(unit, mem, &pent, field);
   6590     }
   6591 
   6592     return rv;
   6593 }
   6594 
   6595 
   6596 #if defined(BCM_TRX_SUPPORT)
   6597 /*
   6598  * Function:
   6599  *      bcm_esw_port_separate_lport_rtag7_profile_fields_get
   6600  * Description:
   6601  *      Gets the fields from the LPORT Profile Table.
   6602  * Parameters:
   6603  *      unit        - (IN) Device number
   6604  *      modid       - (IN) Module number for port
   6605  *      port        - (IN) Port number (NON gport)
   6606  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   6607  *      field_count - (IN) Number of fields to read
   6608  *      fields      - (IN) Array of fields to return
   6609  *      values      - (OUT) Array of return values
   6610  * Return Value:
   6611  *      BCM_E_NONE
   6612  *      BCM_E_XXX
   6613  * Note:
   6614  *     - Assumes: lock,
   6615  *                valid bcm module id and port number,
   6616  *                valid table id,
   6617  *                valid HW fields.
   6618  *     - Called when LPORT profile is supported.
   6619  *     - Helper routine for bcm_esw_port_lport_fields_get();
   6620  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   6621  */
   6622 STATIC int
   6623 bcm_esw_port_separate_lport_rtag7_profile_fields_get(int unit, int port_type,
   6624                                       bcm_module_t modid, bcm_port_t port,
   6625                                       int table_id, int field_count,
   6626                                       soc_field_t *fields, uint32 *values)
   6627 {
   6628     int i;
   6629     int src_index;
   6630     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   6631     int src_tbl_is_stm = 1;
   6632     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   6633     lport_tab_entry_t lport_entry;
   6634     rtag7_port_based_hash_entry_t  rtag7_entry;
   6635     uint32 lport_index = 0, rtag7_index = 0;
   6636     void *entries[1];
   6637     soc_mem_t mem;
   6638     void *entry;
   6639 
   6640     BCM_IF_ERROR_RETURN
   6641         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   6642 
   6643     /* Get LPORT profile index Source table */
   6644     if (src_tbl_is_stm) {
   6645         BCM_IF_ERROR_RETURN
   6646             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index));
   6647     } else {
   6648         src_mem = ING_DEVICE_PORTm;
   6649         src_index = port;
   6650     }
   6651 
   6652     BCM_IF_ERROR_RETURN
   6653         (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY,
   6654                       src_index, src_ent));
   6655 
   6656     lport_index =
   6657         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   6658 
   6659     /* If this is a RTAG7 table, extract the RTAG7 index from the LPORT table */
   6660     if(table_id == LPORT_PROFILE_RTAG7_TAB) {
   6661 
   6662         /* Get the associated LPORT entry */
   6663         BCM_IF_ERROR_RETURN
   6664             (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry));
   6665 
   6666         rtag7_index =
   6667             soc_LPORT_TABm_field32_get(unit, &lport_entry,
   6668                                                     RTAG7_PORT_PROFILE_INDEXf);
   6669     }
   6670 
   6671     /* Read the appropriate profile table entry */
   6672     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   6673         mem = LPORT_TABm;
   6674         entries[0] = &lport_entry;
   6675         entry = entries[0];
   6676         BCM_IF_ERROR_RETURN
   6677             (_bcm_lport_ind_profile_entry_get(unit, lport_index,
   6678                                             1, entries));
   6679     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   6680         mem = RTAG7_PORT_BASED_HASHm;
   6681         entries[0] = &rtag7_entry;
   6682         entry = entries[0];
   6683         BCM_IF_ERROR_RETURN
   6684             (_bcm_rtag7_ind_profile_entry_get(unit, rtag7_index,
   6685                                             1, entries));
   6686     } else {
   6687         return BCM_E_INTERNAL;
   6688     }
   6689 
   6690     for (i = 0; i < field_count; i++) {
   6691         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6692     }
   6693 
   6694     return BCM_E_NONE;
   6695 }
   6696 #endif /* BCM_TRX_SUPPORT */
   6697 
   6698 
   6699 /*
   6700  * Function:
   6701  *      bcm_esw_port_egr_lport_profile_fields_get
   6702  * Description:
   6703  *      Gets the fields from the LPORT Profile Table.
   6704  * Parameters:
   6705  *      unit        - (IN) Device number
   6706  *      modid       - (IN) Module number for port
   6707  *      port        - (IN) Port number (NON gport)
   6708  *      mem         - (IN) Table to modify
   6709  *      field_count - (IN) Number of fields to read
   6710  *      fields      - (IN) Array of fields to return
   6711  *      values      - (OUT) Array of return values
   6712  * Return Value:
   6713  *      BCM_E_NONE
   6714  *      BCM_E_XXX
   6715  * Note:
   6716  *     - Assumes: lock,
   6717  *                valid bcm module id and port number,
   6718  *                valid table id,
   6719  *                valid HW fields.
   6720  *     - Called when LPORT profile is supported.
   6721  *     - Helper routine for bcm_esw_port_egr_lport_fields_get();
   6722  *       callers should be calling bcm_esw_port_egr_lport_fields_get() instead.
   6723  */
   6724 STATIC int
   6725 bcm_esw_port_egr_lport_profile_fields_get(int unit,
   6726                                       bcm_module_t modid, bcm_port_t port,
   6727                                       soc_mem_t mem, int field_count,
   6728                                       soc_field_t *fields, uint32 *values)
   6729 {
   6730 #if defined(BCM_TRX_SUPPORT)
   6731     int i, index;
   6732     int egr_gpp_index = 0;
   6733     egr_gpp_attributes_entry_t egr_gpp_entry;
   6734     egr_lport_profile_entry_t egr_lport_entry;
   6735     egr_vlan_control_1_entry_t egr_vlan_control_1;
   6736     egr_vlan_control_2_entry_t egr_vlan_control_2;
   6737     egr_vlan_control_3_entry_t egr_vlan_control_3;
   6738     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   6739     egr_mtu_entry_t egr_mtu;
   6740     egr_port_1_entry_t egr_port_1;
   6741     egr_counter_control_entry_t egr_counter_control;
   6742     egr_shaping_control_entry_t egr_shaping_control;
   6743     uint32 egr_lport_index;
   6744     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   6745     void *entry = NULL;
   6746     int use_gpp_index = 1;
   6747 
   6748     if (mem == EGR_GPP_ATTRIBUTESm) {
   6749         BCM_IF_ERROR_RETURN
   6750             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6751                                                    &egr_gpp_index));
   6752         BCM_IF_ERROR_RETURN
   6753             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6754                                       egr_gpp_index, &egr_gpp_entry));
   6755         for (i = 0; i < field_count; i++) {
   6756             values[i] = soc_mem_field32_get(unit, EGR_GPP_ATTRIBUTESm,
   6757                                             &egr_gpp_entry, fields[i]);
   6758         }
   6759         return BCM_E_NONE;
   6760     }
   6761 
   6762     BCM_IF_ERROR_RETURN(
   6763         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6764 
   6765     if (use_gpp_index) {
   6766         /* Get LPORT profile index Source Trunk Map table */
   6767         BCM_IF_ERROR_RETURN
   6768             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6769                                                    &egr_gpp_index));
   6770         BCM_IF_ERROR_RETURN
   6771             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6772                                       egr_gpp_index, &egr_gpp_entry));
   6773         egr_lport_index =
   6774             soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6775                                                 EGR_LPORT_PROFILE_IDXf);
   6776     } else {
   6777         egr_port_entry_t entry2;
   6778         BCM_IF_ERROR_RETURN
   6779             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry2));
   6780         egr_lport_index =
   6781             soc_mem_field32_get(unit, EGR_PORTm, &entry2,
   6782                                 EGR_LPORT_PROFILE_IDXf);
   6783     }
   6784 
   6785     /* Get EGR_LPORT profile entry */
   6786     index = 0;
   6787     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6788         entries[index++] = &egr_lport_entry;
   6789     }
   6790     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6791         entries[index++] = &egr_vlan_control_1;
   6792     }
   6793     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6794         entries[index++] = &egr_vlan_control_2;
   6795     }
   6796     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6797         entries[index++] = &egr_vlan_control_3;
   6798     }
   6799     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6800         entries[index++] = &egr_ipmc_cfg2;
   6801     }
   6802     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6803         entries[index++] = &egr_mtu;
   6804     }
   6805     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6806         entries[index++] = &egr_port_1;
   6807     }
   6808     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6809         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6810             entries[index++] = &egr_counter_control;
   6811         }
   6812         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6813             entries[index++] = &egr_shaping_control;
   6814         }
   6815     }
   6816 
   6817     BCM_IF_ERROR_RETURN
   6818             (_bcm_egr_lport_profile_entry_get(unit, egr_lport_index, 1, entries));
   6819 
   6820     BCM_IF_ERROR_RETURN
   6821         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6822     entry = entries[index];
   6823     /* Get fields */
   6824 
   6825     for (i = 0; i < field_count; i++) {
   6826         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6827     }
   6828 
   6829     return BCM_E_NONE;
   6830 #else
   6831     return BCM_E_UNAVAIL;
   6832 #endif /* BCM_TRX_SUPPORT */
   6833 }
   6834 
   6835 /*
   6836  * Function:
   6837  *      bcm_esw_port_lport_profile_fields_get
   6838  * Description:
   6839  *      Gets the fields from the LPORT Profile Table.
   6840  * Parameters:
   6841  *      unit        - (IN) Device number
   6842  *      modid       - (IN) Module number for port
   6843  *      port        - (IN) Port number (NON gport)
   6844  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   6845  *      field_count - (IN) Number of fields to read
   6846  *      fields      - (IN) Array of fields to return
   6847  *      values      - (OUT) Array of return values
   6848  * Return Value:
   6849  *      BCM_E_NONE
   6850  *      BCM_E_XXX
   6851  * Note:
   6852  *     - Assumes: lock,
   6853  *                valid bcm module id and port number,
   6854  *                valid table id,
   6855  *                valid HW fields.
   6856  *     - Called when LPORT profile is supported.
   6857  *     - Helper routine for bcm_esw_port_lport_fields_get();
   6858  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   6859  */
   6860 STATIC int
   6861 bcm_esw_port_lport_profile_fields_get(int unit, int port_type,
   6862                                       bcm_module_t modid, bcm_port_t port,
   6863                                       int table_id, int field_count,
   6864                                       soc_field_t *fields, uint32 *values)
   6865 {
   6866 #if defined(BCM_TRX_SUPPORT)
   6867     int i;
   6868     int src_index;
   6869     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   6870     int src_tbl_is_stm = 1;
   6871     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   6872     lport_tab_entry_t lport_entry;
   6873     rtag7_port_based_hash_entry_t  rtag7_entry;
   6874     uint32 lport_index;
   6875     void *entries[2];
   6876     soc_mem_t mem;
   6877     void *entry;
   6878     int pipe;
   6879 
   6880     if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   6881         return bcm_esw_port_separate_lport_rtag7_profile_fields_get(unit,
   6882                 port_type, modid, port, table_id, field_count, fields, values);
   6883     }
   6884 
   6885     BCM_IF_ERROR_RETURN
   6886         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   6887 
   6888     /* Get LPORT profile index Source table */
   6889     if (src_tbl_is_stm) {
   6890         BCM_IF_ERROR_RETURN
   6891             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index));
   6892     } else {
   6893         src_mem = ING_DEVICE_PORTm;
   6894         src_index = port;
   6895     }
   6896 
   6897     BCM_IF_ERROR_RETURN
   6898         (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent));
   6899 
   6900     lport_index =
   6901         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   6902 
   6903     /* Get LPORT profile entry */
   6904     entries[0] = &lport_entry;
   6905     entries[1] = &rtag7_entry;
   6906     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   6907         pipe = SOC_INFO(unit).port_pipe[src_index];
   6908         mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe];
   6909         /* Need to index into the proper entry of the profile table,
   6910          * which is stored as one logical table while LPORT_PROFILE_IDX
   6911          * is from 0-19 of each pipe */
   6912         lport_index += pipe*SOC_MEM_SIZE(unit, mem);
   6913     }
   6914 
   6915     BCM_IF_ERROR_RETURN
   6916             (_bcm_lport_profile_entry_get(unit, lport_index, 1, entries));
   6917 
   6918     /* Get fields */
   6919     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   6920         mem = LPORT_TABm;
   6921         if (SOC_MEM_UNIQUE_ACC(unit, mem)) {
   6922             int pipe = SOC_INFO(unit).port_pipe[src_index];
   6923             mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe];
   6924         }
   6925         entry = entries[0];
   6926     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   6927         mem = RTAG7_PORT_BASED_HASHm;
   6928         entry = entries[1];
   6929     } else {
   6930         return BCM_E_INTERNAL;
   6931     }
   6932 
   6933     for (i = 0; i < field_count; i++) {
   6934         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6935     }
   6936 
   6937     return BCM_E_NONE;
   6938 #else
   6939     return BCM_E_UNAVAIL;
   6940 #endif /* BCM_TRX_SUPPORT */
   6941 }
   6942 
   6943 /*
   6944  * Function:
   6945  *      bcm_esw_port_lport_non_profile_fields_set
   6946  * Description:
   6947  *      Sets the fields only in the LPORT Table for local HG ports.
   6948  *      There is no reference update to the SOURCE TRUNK MAP table.
   6949  * Parameters:
   6950  *      unit        - (IN) Device number
   6951  *      port        - (IN) Local Port number (NON gport)
   6952  *      field_count - (IN) Number of fields to modify
   6953  *      fields      - (IN) Array of fields to modify
   6954  *      values      - (IN) Array of new field values
   6955  * Return Value:
   6956  *      BCM_E_NONE
   6957  *      BCM_E_XXX
   6958  * Note:
   6959  *     Assumes: lock,
   6960  *              valid bcm port number,
   6961  *              valid HW fields.
   6962  *     - Maintained for backwards compatibility with old code.  This only
   6963  *       updates local HG ports.
   6964  *     - Called when LPORT profile is NOT supported.
   6965  *     - Helper routine for bcm_esw_port_lport_fields_set();
   6966  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   6967  */
   6968 STATIC int
   6969 bcm_esw_port_lport_non_profile_fields_set(int unit, bcm_port_t port,
   6970                                           int field_count,
   6971                                           soc_field_t *fields, uint32 *values)
   6972 {
   6973     bcm_port_config_t port_config;
   6974     soc_mem_t mem = LPORT_TABm;
   6975     int lport_index;
   6976 
   6977     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config));
   6978 
   6979     if (PBMP_MEMBER(port_config.hg, port) == 0) {
   6980         return BCM_E_NONE;
   6981     }
   6982 
   6983     lport_index = SOC_PORT_MOD_OFFSET(unit, port);
   6984 
   6985     return soc_mem_fields32_modify(unit, mem, lport_index,
   6986                                    field_count, fields, values);
   6987 }
   6988 
   6989 /*
   6990  * Function:
   6991  *      bcm_esw_port_lport_non_profile_fields_get
   6992  * Description:
   6993  *      Gets the fields from the LPORT Table for local HG ports.
   6994  * Parameters:
   6995  *      unit        - (IN) Device number
   6996  *      port        - (IN) Local Port number (NON gport)
   6997  *      field_count - (IN) Number of fields to read
   6998  *      fields      - (IN) Array of fields to return
   6999  *      values      - (OUT) Array of return values
   7000  * Return Value:
   7001  *      BCM_E_NONE
   7002  *      BCM_E_XXX
   7003  * Note:
   7004  *     Assumes: lock,
   7005  *              valid bcm port number,
   7006  *              valid HW fields.
   7007  *     - Maintained for backwards compatibility with old code.  This only
   7008  *       updates local HG ports.
   7009  *     - Called when LPORT profile is NOT supported.
   7010  *     - Helper routine for bcm_esw_port_lport_fields_get();
   7011  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   7012  */
   7013 STATIC int
   7014 bcm_esw_port_lport_non_profile_fields_get(int unit, bcm_port_t port,
   7015                                           int field_count,
   7016                                           soc_field_t *fields, uint32 *values)
   7017 {
   7018     lport_tab_entry_t lport_entry;
   7019     int lport_index;
   7020     int i;
   7021 
   7022     if (!IS_HG_PORT(unit,port)) {
   7023         return BCM_E_NONE;
   7024     }
   7025 
   7026     lport_index = SOC_PORT_MOD_OFFSET(unit, port);
   7027 
   7028     BCM_IF_ERROR_RETURN
   7029         (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry));
   7030 
   7031     for (i = 0; i < field_count; i++) {
   7032         values[i] = soc_LPORT_TABm_field32_get(unit, &lport_entry, fields[i]);
   7033     }
   7034 
   7035     return BCM_E_NONE;
   7036 }
   7037 
   7038 /*
   7039  * Function:
   7040  *      bcm_esw_port_lport_resolve
   7041  * Description:
   7042  *      Resolves given port to use in the LPORT table as follows.
   7043  *      Current valid "port" for LPORT are:
   7044  *        GPORT_PROXY  - Resolve to module ID and port
   7045  *        GPORT_xxx    - Should result in a valid local physical port
   7046  *        Not GPORT    - Should be a valid local port number
   7047  * Parameters:
   7048  *      unit        - (IN) Device number
   7049  *      port        - (IN) Port number or GPORT
   7050  *      modid_out   - (OUT) Module ID
   7051  *      port_out    - (OUT) Port number
   7052  * Return Value:
   7053  *      BCM_E_XXX
   7054  * Notes:
   7055  *      If port is GPORT_PROXY, then module-id is derived from GPORT.
   7056  *      Else, module-is is the id of the local device.
   7057  */
   7058 STATIC int
   7059 bcm_esw_port_lport_resolve(int unit, bcm_port_t port,
   7060                            bcm_module_t *modid_out, bcm_port_t *port_out)
   7061 {
   7062     bcm_trunk_t trunk;
   7063     int id, rv;
   7064 
   7065     /* Make sure port module is initialized. */
   7066     PORT_INIT(unit);
   7067 
   7068     /* Resolve port */
   7069     if (BCM_GPORT_IS_PROXY(port)) {
   7070         if (!soc_feature(unit, soc_feature_proxy_port_property)) {
   7071             return BCM_E_PORT;
   7072         }
   7073         BCM_IF_ERROR_RETURN
   7074             (_bcm_esw_gport_resolve(unit, port,
   7075                                     modid_out, port_out,
   7076                                     &trunk, &id));
   7077     } else {
   7078 
   7079 #if defined BCM_HGPROXY_COE_SUPPORT
   7080         if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   7081             soc_feature(unit, soc_feature_channelized_switching)) &&
   7082              _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7083                 BCM_IF_ERROR_RETURN
   7084                     (_bcm_esw_gport_resolve(unit, port,
   7085                                         modid_out, port_out,
   7086                                         &trunk, &id));
   7087         } else
   7088 #endif
   7089 
   7090 #if defined(BCM_KATANA2_SUPPORT)
   7091         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port) &&
   7092                 (soc_feature(unit, soc_feature_subtag_coe) ||
   7093                  soc_feature(unit, soc_feature_linkphy_coe))) {
   7094             BCM_IF_ERROR_RETURN
   7095                 (_bcm_esw_gport_resolve(unit, port,
   7096                                     modid_out, port_out,
   7097                                     &trunk, &id));
   7098         } else
   7099 #endif
   7100 
   7101         {
   7102             /* Gport should resolve to a local valid port */
   7103             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out));
   7104             rv = _bcm_esw_port_gport_validate(unit, port, port_out);
   7105 
   7106             if (rv == BCM_E_PORT &&
   7107                 SOC_IS_TRIDENT3X(unit) &&
   7108                 SOC_INFO(unit).cpu_hg_index == port) {
   7109                 *port_out = port;
   7110                 rv = BCM_E_NONE;
   7111             }
   7112             BCM_IF_ERROR_RETURN(rv);
   7113         }
   7114     }
   7115 
   7116     return BCM_E_NONE;
   7117 }
   7118 
   7119 /*
   7120  * Function:
   7121  *      bcm_esw_port_egr_lport_resolve
   7122  * Description:
   7123  *      Resolves given port to use in the EGR_LPORT table as follows.
   7124  *      Current valid "port" for EGR_LPORT are:
   7125  *        GPORT_SUBPORT - Resolve to module ID and port
   7126  * Parameters:
   7127  *      unit        - (IN) Device number
   7128  *      port        - (IN) Port number or GPORT
   7129  *      modid_out   - (OUT) Module ID
   7130  *      port_out    - (OUT) Port number
   7131  * Return Value:
   7132  *      BCM_E_XXX
   7133  * Notes:
   7134  *      If port is GPORT_PROXY, then module-id is derived from GPORT.
   7135  *      Else, module-is is the id of the local device.
   7136  */
   7137 STATIC int
   7138 bcm_esw_port_egr_lport_resolve(int unit, bcm_port_t port,
   7139                            bcm_module_t *modid_out, bcm_port_t *port_out)
   7140 {
   7141 #if defined BCM_HGPROXY_COE_SUPPORT
   7142     bcm_trunk_t trunk;
   7143     int         id;
   7144 #endif
   7145 
   7146     /* Make sure port module is initialized. */
   7147     PORT_INIT(unit);
   7148 
   7149     /* Resolve port */
   7150 #if defined BCM_HGPROXY_COE_SUPPORT
   7151     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   7152         (soc_feature(unit, soc_feature_channelized_switching))) &&
   7153          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7154             BCM_IF_ERROR_RETURN
   7155                 (_bcm_esw_gport_resolve(unit, port,
   7156                                     modid_out, port_out,
   7157                                     &trunk, &id));
   7158     } else
   7159 #endif
   7160     {
   7161         /* Gport should resolve to a local valid port */
   7162         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out));
   7163         BCM_IF_ERROR_RETURN
   7164             (_bcm_esw_port_gport_validate(unit, port, port_out));
   7165     }
   7166 
   7167     return BCM_E_NONE;
   7168 }
   7169 
   7170 
   7171 /*
   7172  * Function:
   7173  *      bcm_esw_port_lport_fields_set
   7174  * Description:
   7175  *      Sets the fields in the LPORT Table as follows:
   7176  *      - If LPORT profile is available, update fields in the
   7177  *        LPORT Profile Table and corresponding index in the
   7178  *        Source Trunk Map table.
   7179  *      - Else, update fields in the LPORT table only (old logic).
   7180  * Parameters:
   7181  *      unit        - (IN) Device number
   7182  *      port        - (IN) Port number or GPORT (see Notes)
   7183  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7184  *      field_count - (IN) Number of fields to modify
   7185  *      fields      - (IN) Array of fields to modify
   7186  *      values      - (IN) Array of new field values
   7187  * Return Value:
   7188  *      BCM_E_XXX
   7189  * Notes:
   7190  *      Current valid port/gport types:
   7191  *        GPORT_PROXY
   7192  *        GPORT_xxx    - should result in a valid local physical port
   7193  *        Not GPORT    - assumes a valid local port number
   7194  */
   7195 int
   7196 bcm_esw_port_lport_fields_set(int unit, bcm_port_t port,
   7197                               int table_id, int field_count,
   7198                               soc_field_t *fields, uint32 *values)
   7199 {
   7200     int rv = BCM_E_NONE;
   7201     int i;
   7202     soc_mem_t mem;
   7203     bcm_module_t lmodid;
   7204     bcm_port_t lport;
   7205     int ptype = _BCM_ESW_PT_PORT;
   7206 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   7207     bcm_xflow_macsec_port_info_t port_info;
   7208     port_info.enable =0;
   7209 #endif
   7210 
   7211     /* Make sure port module is initialized. */
   7212     PORT_INIT(unit);
   7213 
   7214 #if defined BCM_HGPROXY_COE_SUPPORT
   7215     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   7216         (soc_feature(unit, soc_feature_channelized_switching))) &&
   7217          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7218         ptype = _BCM_ESW_PT_COE;
   7219     } else
   7220 #endif
   7221 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   7222     if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) &&
   7223         (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) &&
   7224         (port_info.enable == 1)) {
   7225         ptype = _BCM_ESW_PT_MACSEC_PORT;
   7226     } else
   7227 #endif
   7228     if (BCM_GPORT_IS_PROXY(port)) {
   7229         ptype = _BCM_ESW_PT_HGPROXY;
   7230     }
   7231 
   7232     /* Check table */
   7233     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   7234         mem = LPORT_TABm;
   7235     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   7236         if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   7237             return BCM_E_UNAVAIL;
   7238         }
   7239         mem = RTAG7_PORT_BASED_HASHm;
   7240     } else {
   7241         return BCM_E_INTERNAL;
   7242     }
   7243 
   7244     /* Check all fields are valid */
   7245     for (i = 0; i < field_count; i++) {
   7246         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7247             return BCM_E_UNAVAIL;
   7248         }
   7249     }
   7250 
   7251     /* Resolve port */
   7252     BCM_IF_ERROR_RETURN
   7253         (bcm_esw_port_lport_resolve(unit, port,
   7254                                     &lmodid, &lport));
   7255 
   7256     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   7257         rv = bcm_esw_port_lport_profile_fields_set(unit, ptype,
   7258                 lmodid, lport, table_id, field_count, fields, values);
   7259     } else {
   7260         rv = bcm_esw_port_lport_non_profile_fields_set(unit,
   7261                 lport, field_count, fields, values);
   7262     }
   7263 
   7264     return rv;
   7265 }
   7266 
   7267 /*
   7268  * Function:
   7269  *      bcm_esw_port_egr_lport_fields_set
   7270  * Description:
   7271  *      Sets the fields in the LPORT Table as follows:
   7272  *      - If LPORT profile is available, update fields in the
   7273  *        LPORT Profile Table and corresponding index in the
   7274  *        Source Trunk Map table.
   7275  *      - Else, update fields in the LPORT table only (old logic).
   7276  * Parameters:
   7277  *      unit        - (IN) Device number
   7278  *      port        - (IN) Port number or GPORT (see Notes)
   7279  *      mem         - (IN) Table to modify
   7280  *      field_count - (IN) Number of fields to modify
   7281  *      fields      - (IN) Array of fields to modify
   7282  *      values      - (IN) Array of new field values
   7283  * Return Value:
   7284  *      BCM_E_XXX
   7285  * Notes:
   7286  *      Current valid port/gport types:
   7287  *        GPORT_PROXY
   7288  *        GPORT_xxx    - should result in a valid local physical port
   7289  *        Not GPORT    - assumes a valid local port number
   7290  */
   7291 int
   7292 bcm_esw_port_egr_lport_fields_set(int unit, bcm_port_t port,
   7293                               soc_mem_t mem, int field_count,
   7294                               soc_field_t *fields, uint32 *values)
   7295 {
   7296     int rv = BCM_E_NONE;
   7297     int i;
   7298     bcm_module_t lmodid;
   7299     bcm_port_t lport;
   7300 
   7301     /* Make sure port module is initialized. */
   7302     PORT_INIT(unit);
   7303 
   7304     /* Check all fields are valid */
   7305     for (i = 0; i < field_count; i++) {
   7306         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7307             return BCM_E_UNAVAIL;
   7308         }
   7309     }
   7310 
   7311     /* Resolve port */
   7312     BCM_IF_ERROR_RETURN
   7313         (bcm_esw_port_egr_lport_resolve(unit, port,
   7314                                     &lmodid, &lport));
   7315 
   7316     PORT_LOCK(unit);
   7317     if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
   7318         rv = bcm_esw_port_egr_lport_profile_fields_set(unit, lmodid, lport,
   7319                                                    mem, field_count,
   7320                                                    fields, values);
   7321     }
   7322 
   7323     PORT_UNLOCK(unit);
   7324 
   7325     return rv;
   7326 }
   7327 
   7328 /*
   7329  * Function:
   7330  *      bcm_esw_port_egr_lport_fields_clear
   7331  * Description:
   7332  *      Similar function as bcm_esw_port_egr_lport_fields_set.
   7333  *      For clear purpose only.
   7334  * Parameters:
   7335  *      unit        - (IN) Device number
   7336  *      port        - (IN) Port number or GPORT (see Notes)
   7337  *      mem         - (IN) Table to modify
   7338  * Return Value:
   7339  *      BCM_E_XXX
   7340  * Notes:
   7341  *      Current valid port/gport types:
   7342  *        GPORT_PROXY
   7343  *        GPORT_xxx    - should result in a valid local physical port
   7344  *        Not GPORT    - assumes a valid local port number
   7345  */
   7346 int
   7347 bcm_esw_port_egr_lport_fields_clear(int unit, bcm_port_t port,
   7348                                     soc_mem_t mem)
   7349 {
   7350     int rv = BCM_E_NONE;
   7351     bcm_module_t lmodid;
   7352     bcm_port_t lport;
   7353 
   7354     /* Make sure port module is initialized. */
   7355     PORT_INIT(unit);
   7356 
   7357     /* Resolve port */
   7358     BCM_IF_ERROR_RETURN
   7359         (bcm_esw_port_egr_lport_resolve(unit, port,
   7360                                     &lmodid, &lport));
   7361 
   7362     PORT_LOCK(unit);
   7363     if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
   7364         rv = bcm_esw_port_egr_lport_profile_clear(unit, lmodid, lport, mem);
   7365     }
   7366 
   7367     PORT_UNLOCK(unit);
   7368 
   7369     return rv;
   7370 }
   7371 
   7372 /*
   7373  * Function:
   7374  *      bcm_esw_port_lport_fields_get
   7375  * Description:
   7376  *      Gets the values from the LPORT Table fields as follows:
   7377  *      - If LPORT profile is available, gets fields from the
   7378  *        LPORT Profile Table and corresponding index in the
   7379  *        Source Trunk Map table.
   7380  *      - Else, get fields from the LPORT table only (old logic).
   7381  * Parameters:
   7382  *      unit        - (IN) Device number
   7383  *      port        - (IN) Port number or GPORT (see Notes)
   7384  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7385  *      field_count - (IN) Number of fields to get
   7386  *      fields      - (IN) Array of fields values to get
   7387  *      values      - (OUT) Array of returned values
   7388  * Return Value:
   7389  *      BCM_E_XXX
   7390  * Notes:
   7391  *      Current valid port/gport types:
   7392  *        GPORT_PROXY
   7393  *        GPORT_xxx    - should result in a valid local physical port
   7394  *        Not GPORT    - assumes a valid local port number
   7395  */
   7396 int
   7397 bcm_esw_port_lport_fields_get(int unit, bcm_port_t port,
   7398                               int table_id, int field_count,
   7399                               soc_field_t *fields, uint32 *values)
   7400 {
   7401     int rv = BCM_E_NONE;
   7402     int i;
   7403     soc_mem_t mem;
   7404     bcm_module_t lmodid;
   7405     bcm_port_t lport;
   7406     int ptype = _BCM_ESW_PT_PORT;
   7407 
   7408     /* Make sure port module is initialized. */
   7409     PORT_INIT(unit);
   7410 
   7411 #if defined BCM_HGPROXY_COE_SUPPORT
   7412     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   7413         (soc_feature(unit, soc_feature_channelized_switching))) &&
   7414          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7415         ptype = _BCM_ESW_PT_COE;
   7416     } else
   7417 #endif
   7418     if (BCM_GPORT_IS_PROXY(port)) {
   7419         ptype = _BCM_ESW_PT_HGPROXY;
   7420     }
   7421 
   7422     /* Check table */
   7423     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   7424         mem = LPORT_TABm;
   7425     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   7426         if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   7427             return BCM_E_UNAVAIL;
   7428         }
   7429         mem = RTAG7_PORT_BASED_HASHm;
   7430     } else {
   7431         return BCM_E_INTERNAL;
   7432     }
   7433 
   7434     /* Check all fields are valid */
   7435     for (i = 0; i < field_count; i++) {
   7436         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7437             return BCM_E_UNAVAIL;
   7438         }
   7439     }
   7440 
   7441     /* Resolve port */
   7442     BCM_IF_ERROR_RETURN
   7443         (bcm_esw_port_lport_resolve(unit, port,
   7444                                     &lmodid, &lport));
   7445 
   7446     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   7447         rv = bcm_esw_port_lport_profile_fields_get(unit, ptype,
   7448                 lmodid, lport, table_id, field_count, fields, values);
   7449     } else {
   7450         rv = bcm_esw_port_lport_non_profile_fields_get(unit, lport,
   7451                 field_count, fields, values);
   7452     }
   7453 
   7454     return rv;
   7455 }
   7456 
   7457 /*
   7458  * Function:
   7459  *      bcm_esw_port_egr_lport_fields_get
   7460  * Description:
   7461  *      Gets the values from the LPORT Table fields as follows:
   7462  *      - If LPORT profile is available, gets fields from the
   7463  *        LPORT Profile Table and corresponding index in the
   7464  *        Source Trunk Map table.
   7465  *      - Else, get fields from the LPORT table only (old logic).
   7466  * Parameters:
   7467  *      unit        - (IN) Device number
   7468  *      port        - (IN) Port number or GPORT (see Notes)
   7469  *      mem         - (IN) Table to modify
   7470  *      field_count - (IN) Number of fields to get
   7471  *      fields      - (IN) Array of fields values to get
   7472  *      values      - (OUT) Array of returned values
   7473  * Return Value:
   7474  *      BCM_E_XXX
   7475  * Notes:
   7476  *      Current valid port/gport types:
   7477  *        GPORT_PROXY
   7478  *        GPORT_xxx    - should result in a valid local physical port
   7479  *        Not GPORT    - assumes a valid local port number
   7480  */
   7481 int
   7482 bcm_esw_port_egr_lport_fields_get(int unit, bcm_port_t port,
   7483                               soc_mem_t mem, int field_count,
   7484                               soc_field_t *fields, uint32 *values)
   7485 {
   7486     int rv = BCM_E_NONE;
   7487     int i;
   7488     bcm_module_t lmodid;
   7489     bcm_port_t lport;
   7490 
   7491     /* Sanity check */
   7492     if ((fields == NULL) || (values == NULL)) {
   7493         return BCM_E_PARAM;
   7494     }
   7495 
   7496     /* Make sure port module is initialized. */
   7497     PORT_INIT(unit);
   7498 
   7499     /* Check all fields are valid */
   7500     for (i = 0; i < field_count; i++) {
   7501         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7502             return BCM_E_UNAVAIL;
   7503         }
   7504     }
   7505 
   7506     /* Resolve port */
   7507     BCM_IF_ERROR_RETURN
   7508         (bcm_esw_port_egr_lport_resolve(unit, port,
   7509                                     &lmodid, &lport));
   7510 
   7511     PORT_LOCK(unit);
   7512     rv = bcm_esw_port_egr_lport_profile_fields_get(unit, lmodid, lport,
   7513                                                mem, field_count,
   7514                                                fields, values);
   7515     PORT_UNLOCK(unit);
   7516 
   7517     return rv;
   7518 }
   7519 
   7520 /*
   7521  * Function:
   7522  *      bcm_esw_port_lport_field_set
   7523  * Description:
   7524  *      Sets given field in the LPORT Table as follows:
   7525  *      - If LPORT profile is available, update field in the
   7526  *        LPORT Profile Table and corresponding index in the
   7527  *        Source Trunk Map table.
   7528  *      - Else, update field in the LPORT table only (old logic).
   7529  * Parameters:
   7530  *      unit        - (IN) Device number
   7531  *      port        - (IN) Port number or GPORT (see Notes)
   7532  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7533  *      field       - (IN) Field to modify
   7534  *      value       - (IN) New field value
   7535  * Return Value:
   7536  *      BCM_E_XXX
   7537  * Notes:
   7538  *      See bcm_esw_port_lport_fields_set().
   7539  */
   7540 int
   7541 bcm_esw_port_lport_field_set(int unit, bcm_port_t port,
   7542                              int table_id, soc_field_t field, uint32 value)
   7543 {
   7544     /* Make sure port module is initialized. */
   7545     PORT_INIT(unit);
   7546 
   7547     return bcm_esw_port_lport_fields_set(unit, port,
   7548                                          table_id, 1, &field, &value);
   7549 }
   7550 
   7551 /*
   7552  * Function:
   7553  *      bcm_esw_port_egr_lport_field_set
   7554  * Description:
   7555  *      Sets given field in the LPORT Table as follows:
   7556  *      - If LPORT profile is available, update field in the
   7557  *        LPORT Profile Table and corresponding index in the
   7558  *        Source Trunk Map table.
   7559  *      - Else, update field in the LPORT table only (old logic).
   7560  * Parameters:
   7561  *      unit        - (IN) Device number
   7562  *      port        - (IN) Port number or GPORT (see Notes)
   7563  *      mem         - (IN) Table to modify
   7564  *      field       - (IN) Field to modify
   7565  *      value       - (IN) New field value
   7566  * Return Value:
   7567  *      BCM_E_XXX
   7568  * Notes:
   7569  *      See bcm_esw_port_egr_lport_fields_set().
   7570  */
   7571 int
   7572 bcm_esw_port_egr_lport_field_set(int unit, bcm_port_t port, soc_mem_t mem,
   7573                                  soc_field_t field, uint32 value)
   7574 {
   7575     /* Make sure port module is initialized. */
   7576     PORT_INIT(unit);
   7577 
   7578     return bcm_esw_port_egr_lport_fields_set(unit, port, mem, 1, &field, &value);
   7579 }
   7580 
   7581 
   7582 /*
   7583  * Function:
   7584  *      bcm_esw_port_lport_field_get
   7585  * Description:
   7586  *      Gets given field from the LPORT Table as follows:
   7587  *      - If LPORT profile is available, gets fields from the
   7588  *        LPORT Profile Table and corresponding index in the
   7589  *        Source Trunk Map table.
   7590  *      - Else, get fields from the LPORT table only (old logic).
   7591  * Parameters:
   7592  *      unit        - (IN) Device number
   7593  *      port        - (IN) Port number or GPORT (see Notes)
   7594  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7595  *      field       - (IN) Field value to get
   7596  *      value       - (OUT) Returned value
   7597  * Return Value:
   7598  *      BCM_E_XXX
   7599  * Notes:
   7600  *      See bcm_esw_port_lport_fields_get().
   7601  */
   7602 int
   7603 bcm_esw_port_lport_field_get(int unit, bcm_port_t port,
   7604                              int table_id, soc_field_t field, uint32 *value)
   7605 {
   7606     /* Make sure port module is initialized. */
   7607     PORT_INIT(unit);
   7608 
   7609     return bcm_esw_port_lport_fields_get(unit, port,
   7610                                          table_id, 1, &field, value);
   7611 }
   7612 
   7613 
   7614 /*
   7615  * Function:
   7616  *      bcm_esw_port_egr_lport_field_get
   7617  * Description:
   7618  *      Gets given field from the LPORT Table as follows:
   7619  *      - If LPORT profile is available, gets fields from the
   7620  *        LPORT Profile Table and corresponding index in the
   7621  *        Source Trunk Map table.
   7622  *      - Else, get fields from the LPORT table only (old logic).
   7623  * Parameters:
   7624  *      unit        - (IN) Device number
   7625  *      port        - (IN) Port number or GPORT (see Notes)
   7626  *      mem         - (IN) Table to modify
   7627  *      field       - (IN) Field value to get
   7628  *      value       - (OUT) Returned value
   7629  * Return Value:
   7630  *      BCM_E_XXX
   7631  * Notes:
   7632  *      See bcm_esw_port_egr_lport_fields_get().
   7633  */
   7634 int
   7635 bcm_esw_port_egr_lport_field_get(int unit, bcm_port_t port, soc_mem_t mem,
   7636                                  soc_field_t field, uint32 *value)
   7637 {
   7638     /* Make sure port module is initialized. */
   7639     PORT_INIT(unit);
   7640 
   7641     return bcm_esw_port_egr_lport_fields_get(unit, port, mem, 1, &field, value);
   7642 }
   7643 
   7644 /*
   7645  * Function:
   7646  *      _bcm_esw_port_tab_multi_set
   7647  * Description:
   7648  *      Sets multiple port property fields in the HW table.
   7649  *      Helper funtion for bcm_esw_port_control_set.
   7650  * Parameters:
   7651  *      unit        - Device number
   7652  *      port        - Port number (see Notes for valid port formats)
   7653  *      cpu_tabs - If CPU port, which ingress tables should be written?
   7654  *      field_count - Number of fields to modify
   7655  *      fields      - Array of fields to modify
   7656  *      values      - Array of new field values
   7657  * Return Value:
   7658  *      BCM_E_NONE
   7659  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   7660  * Notes:
   7661  *      Due to the large number of callers for this routine,
   7662  *      function is expanded to take a GPORT PROXY, which
   7663  *      sets the property in the LPORT profile table (similar
   7664  *      to what was done for the GPORT_WLAN_PORT).
   7665  *
   7666  *      Current valid port types are:
   7667  *          GPORT WLAN
   7668  *          GPORT PROXY
   7669  *          GPORT SUBPORT
   7670  *          BCM port (non-gport), assumes a valid local physical port
   7671  *
   7672  *     For GPORT PROXY port, this routine only accesses the properties
   7673  *     in the LPORT table (not the RTAG7).
   7674  */
   7675 int
   7676 _bcm_esw_port_tab_multi_set(int unit, bcm_port_t port, int cpu_tabs,
   7677                             int field_count, soc_field_t *fields,
   7678                             uint32 *values)
   7679 {
   7680     soc_mem_t port_tab_mem = PORT_TABm;
   7681     int rv = BCM_E_NONE, i, cpu_hg_index = -1;
   7682     int is_lport_cfg=0, is_wlan_cfg = 0, is_in_warm_boot = 0;
   7683     int index = 0, is_local_port = 0;
   7684     int ptype = _BCM_ESW_PT_PORT;
   7685 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7686      && defined(INCLUDE_L3))
   7687     bcm_port_t wport = 0;
   7688 #endif
   7689     port_tab_entry_t pent;
   7690 
   7691     soc_field_t port_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   7692     uint32 port_tab_values[SOC_MAX_MEM_FIELD_NUM];
   7693     int port_tab_field_count = 0;
   7694     soc_field_t lport_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   7695     uint32 lport_tab_values[SOC_MAX_MEM_FIELD_NUM];
   7696     int lport_tab_field_count = 0;
   7697     soc_field_t ing_dev_port_fields[SOC_MAX_MEM_FIELD_NUM];
   7698     uint32 ing_dev_port_values[SOC_MAX_MEM_FIELD_NUM];
   7699     int ing_dev_port_field_count = 0;
   7700 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   7701     bcm_xflow_macsec_port_info_t port_info;
   7702     port_info.enable =0;
   7703 #endif
   7704 
   7705     if ((fields == NULL) || (values == NULL) ) {
   7706         return BCM_E_PARAM;
   7707     }
   7708     if (field_count <= 0) {
   7709         return BCM_E_NONE;
   7710     }
   7711 
   7712 #if defined BCM_HGPROXY_COE_SUPPORT
   7713     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   7714         (soc_feature(unit, soc_feature_channelized_switching))) &&
   7715          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7716         is_lport_cfg = 1;
   7717         ptype = _BCM_ESW_PT_COE;
   7718     } else
   7719 #endif
   7720 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT)
   7721     if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) &&
   7722         (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) &&
   7723         (port_info.enable == 1)) {
   7724         ptype = _BCM_ESW_PT_MACSEC_PORT;
   7725     } else
   7726 #endif
   7727     if (BCM_GPORT_IS_PROXY(port)) {
   7728         is_lport_cfg = 1;
   7729         ptype = _BCM_ESW_PT_HGPROXY;
   7730         if(bcm_esw_port_local_get(unit, port, &port) == BCM_E_NONE) {
   7731             is_local_port = 1;
   7732             index = SOC_PORT_MOD_OFFSET(unit, port);
   7733         }
   7734     }
   7735 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7736      && defined(INCLUDE_L3))
   7737     else if (BCM_GPORT_IS_WLAN_PORT(port)) {
   7738         is_wlan_cfg = 1;
   7739         wport = port;
   7740     }
   7741 #endif
   7742 
   7743     if (is_lport_cfg) {
   7744         port_tab_mem = LPORT_TABm;
   7745     } else if (!is_wlan_cfg) {
   7746         /*
   7747          * At this point, 'port' needs to be a BCM port (non-gport)
   7748          * convert the gport to local port
   7749          */
   7750         if (BCM_GPORT_IS_SET(port)) {
   7751             BCM_IF_ERROR_RETURN(
   7752                 _bcm_esw_port_gport_validate(unit, port, &port));
   7753         }
   7754         index = SOC_PORT_MOD_OFFSET(unit, port);
   7755         port_tab_mem = SOC_PORT_MEM_TAB(unit, port);
   7756     }
   7757 
   7758     if (!is_wlan_cfg && port_tab_mem == PORT_TABm &&
   7759         (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7760         sal_memset(&pent, 0, sizeof(pent));
   7761         if (port_tab_mem == PORT_TABm &&
   7762             SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   7763             port_tab_mem = ING_DEVICE_PORTm;
   7764         }
   7765         BCM_IF_ERROR_RETURN(
   7766             soc_mem_read(unit, port_tab_mem, MEM_BLOCK_ANY, index, &pent));
   7767     }
   7768 
   7769     /* Loop to set field values into corresponding memory */
   7770     for (i = 0; i < field_count; i++) {
   7771         /* If LPORT, then set property in LPORT table */
   7772         if (is_lport_cfg) {
   7773 #if defined(CANCUN_SUPPORT)
   7774             if(SOC_IS_TRIDENT3X(unit)) {
   7775                 if(soc_cancun_cmh_check(unit, port_tab_mem, fields[i])
   7776                        == SOC_E_NONE) {
   7777                     rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port,
   7778                              fields[i], values[i]);
   7779                 }
   7780                 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem);
   7781             }
   7782 #endif
   7783             soc_mem_set_field_value_array(lport_tab_fields, fields[i],
   7784                                           lport_tab_values, values[i],
   7785                                           lport_tab_field_count);
   7786 
   7787             /* Synchronize PORT and LPORT profile tables if port is local*/
   7788             if(is_local_port) {
   7789                 if(SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) {
   7790                     soc_mem_set_field_value_array(port_tab_fields, fields[i],
   7791                                                   port_tab_values, values[i],
   7792                                                   port_tab_field_count);
   7793                 }
   7794             }
   7795 
   7796             continue;
   7797         }
   7798 
   7799         /* GPORT WLAN */
   7800 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7801      && defined(INCLUDE_L3))
   7802         
   7803         if (is_wlan_cfg) {
   7804 #if defined(BCM_TRIUMPH3_SUPPORT)
   7805             if (soc_feature(unit, soc_feature_axp)) {
   7806                 rv = _bcm_tr3_wlan_port_set(unit, wport, fields[i], values[i]);
   7807             } else
   7808 #endif /* BCM_TRIUMPH3_SUPPORT */
   7809             if (soc_feature(unit, soc_feature_wlan)) {
   7810                 rv = _bcm_tr2_wlan_port_set(unit, wport, fields[i], values[i]);
   7811             }
   7812             if (rv != BCM_E_NONE) {
   7813                 return rv;
   7814             }
   7815             continue;
   7816         }
   7817 #endif
   7818 
   7819         /*  BCM port (non-gport)  */
   7820 #if defined(CANCUN_SUPPORT)
   7821         if (SOC_IS_TRIDENT3X(unit)) {
   7822             port_tab_mem = PORT_TABm;
   7823             if (soc_cancun_cmh_check(unit, port_tab_mem, fields[i])
   7824                    == SOC_E_NONE) {
   7825                 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port,
   7826                          fields[i], values[i]);
   7827                 continue;
   7828             }
   7829             _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem);
   7830         }
   7831 #endif
   7832         if (!SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) {
   7833             LOG_INFO(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
   7834                 "%s.%s is INVALID\n"),
   7835                     SOC_MEM_NAME(unit, port_tab_mem),
   7836                     SOC_FIELD_NAME(unit, fields[i])));
   7837             return (BCM_E_UNAVAIL);
   7838         }
   7839 
   7840         if ((!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER)) ||
   7841             (IS_CPU_PORT(unit, port) &&
   7842              (cpu_tabs & _BCM_CPU_TABS_HIGIG) &&
   7843              (port_tab_mem == PORT_TABm))) {
   7844             switch (port_tab_mem) {
   7845 #ifdef  BCM_TUCANA_SUPPORT
   7846                 case PORT_TAB1m:
   7847 #endif
   7848                 case PORT_TABm:
   7849                     if ((soc_mem_field32_get(unit, port_tab_mem,
   7850                                              &pent, fields[i]) != values[i]) ||
   7851                         (fields[i] == TRILL_ENABLEf) ||
   7852                         (fields[i] == ALLOW_TRILL_FRAMESf) ||
   7853                         (fields[i] == ALLOW_NON_TRILL_FRAMESf) ||
   7854                         (fields[i] == COPY_CORE_IS_IS_TO_CPUf) ||
   7855                         (fields[i] == RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) {
   7856                         soc_mem_field32_set(unit, port_tab_mem,
   7857                                             &pent, fields[i], values[i]);
   7858                         soc_mem_set_field_value_array(port_tab_fields,
   7859                             fields[i], port_tab_values, values[i],
   7860                             port_tab_field_count);
   7861                         if ((SOC_MEM_IS_VALID(unit, LPORT_TABm)) &&
   7862                             (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) ||
   7863                              SOC_IS_APACHE(unit) ||
   7864                              soc_feature(unit,
   7865                                          soc_feature_sync_port_lport_tab))) {
   7866                             soc_mem_set_field_value_array(lport_tab_fields,
   7867                                 fields[i], lport_tab_values, values[i],
   7868                                 lport_tab_field_count);
   7869                         }
   7870                     }
   7871                     break;
   7872                 case LPORT_TABm:
   7873                     soc_mem_set_field_value_array(lport_tab_fields, fields[i],
   7874                                                   lport_tab_values, values[i],
   7875                                                   lport_tab_field_count);
   7876                     break;
   7877                 case ING_DEVICE_PORTm:
   7878                     soc_mem_set_field_value_array(ing_dev_port_fields,
   7879                                                   fields[i],
   7880                                                   ing_dev_port_values,
   7881                                                   values[i],
   7882                                                   ing_dev_port_field_count);
   7883                     break;
   7884                 default:
   7885                     soc_mem_field32_modify(unit, port_tab_mem, port,
   7886                                                 fields[i], values[i]);
   7887                     continue;
   7888             }
   7889         }
   7890     }
   7891 
   7892     /* wlan_cfg is handled outside of this function */
   7893     if (is_wlan_cfg == 1) {
   7894         return BCM_E_NONE;
   7895     }
   7896 
   7897     is_in_warm_boot = (inside_bcm_shutdown[unit] == TRUE) ||
   7898                       SOC_WARM_BOOT(unit);
   7899 
   7900     /* Apply the changes to tables their field_count is not 0 */
   7901     if (port_tab_field_count != 0) {
   7902         if (port_tab_mem == PORT_TABm &&
   7903             (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7904             BCM_IF_ERROR_RETURN
   7905                 (soc_mem_write(unit, port_tab_mem, MEM_BLOCK_ALL, index, &pent));
   7906         } else {
   7907             if ((!IS_CPU_PORT(unit, port)) ||
   7908                 (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7909             BCM_IF_ERROR_RETURN
   7910                 (soc_mem_fields32_modify(unit, port_tab_mem, index,
   7911                                          port_tab_field_count, port_tab_fields,
   7912                                          port_tab_values));
   7913         }
   7914     }
   7915     }
   7916 
   7917     if (ing_dev_port_field_count != 0) {
   7918         if(is_in_warm_boot) {
   7919             SOC_WARM_BOOT_DONE(unit);
   7920         }
   7921 
   7922         BCM_IF_ERROR_RETURN
   7923             (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, index,
   7924                                      ing_dev_port_field_count,
   7925                                      ing_dev_port_fields,
   7926                                      ing_dev_port_values));
   7927         if(is_in_warm_boot) {
   7928             SOC_WARM_BOOT_START(unit);
   7929         }
   7930     }
   7931 
   7932     if (lport_tab_field_count != 0) {
   7933 #if defined(BCM_KATANA2_SUPPORT)
   7934         if (SOC_IS_KATANA2(unit) && (port > KT2_MAX_PHYSICAL_PORTS)) {
   7935             /* Skip programming */;
   7936         } else
   7937 #endif
   7938 #if defined(BCM_SABER2_SUPPORT)
   7939         if (SOC_IS_SABER2(unit) && (port > SB2_MAX_PHYSICAL_PORTS)) {
   7940             /* Skip programming */;
   7941         } else
   7942 #endif
   7943         {
   7944             if (is_in_warm_boot) {
   7945                 SOC_WARM_BOOT_DONE(unit);
   7946             }
   7947 
   7948             if (is_lport_cfg == 1) { /* remote port */
   7949                 rv = bcm_esw_port_lport_fields_set(unit, port,
   7950                                                    LPORT_PROFILE_LPORT_TAB,
   7951                                                    lport_tab_field_count,
   7952                                                    lport_tab_fields,
   7953                                                    lport_tab_values);
   7954 
   7955                 if (is_in_warm_boot) {
   7956                     SOC_WARM_BOOT_START(unit);
   7957                 }
   7958                 return rv;
   7959             }
   7960 
   7961             BCM_IF_ERROR_RETURN
   7962                 (bcm_esw_port_lport_fields_set(unit,
   7963                                                index,
   7964                                                LPORT_PROFILE_LPORT_TAB,
   7965                                                lport_tab_field_count,
   7966                                                lport_tab_fields,
   7967                                                lport_tab_values));
   7968             if (is_in_warm_boot) {
   7969                 SOC_WARM_BOOT_START(unit);
   7970             }
   7971         }
   7972     }
   7973 
   7974     /* Copy to Higig port if needed */
   7975     if (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_HIGIG)) {
   7976         cpu_hg_index = SOC_IS_KATANA2(unit) ?
   7977                        SOC_INFO(unit).cpu_hg_pp_port_index :
   7978                        SOC_INFO(unit).cpu_hg_index;
   7979 
   7980         if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   7981             if (port_tab_field_count != 0) {
   7982                 BCM_IF_ERROR_RETURN
   7983                     (soc_mem_fields32_modify(unit, IPORT_TABLEm, index,
   7984                                              port_tab_field_count,
   7985                                              port_tab_fields, port_tab_values));
   7986             }
   7987         } else if (cpu_hg_index != -1) {
   7988             if (port_tab_field_count != 0) {
   7989                 BCM_IF_ERROR_RETURN
   7990                     (soc_mem_fields32_modify(unit, port_tab_mem, cpu_hg_index,
   7991                                              port_tab_field_count,
   7992                                              port_tab_fields,
   7993                                              port_tab_values));
   7994             }
   7995             if (ing_dev_port_field_count != 0) {
   7996                 BCM_IF_ERROR_RETURN
   7997                     (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm,
   7998                                              cpu_hg_index,
   7999                                              ing_dev_port_field_count,
   8000                                              ing_dev_port_fields,
   8001                                              ing_dev_port_values));
   8002             }
   8003             if (lport_tab_field_count != 0) {
   8004                 if (SOC_IS_TRIDENT3X(unit)) {
   8005                     /* TD3TBD Should use a feature check? */
   8006                     int my_modid = 0;
   8007                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
   8008                     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   8009                         BCM_IF_ERROR_RETURN(
   8010                             bcm_esw_port_lport_profile_fields_set(unit, ptype,
   8011                                 my_modid, cpu_hg_index, LPORT_PROFILE_LPORT_TAB,
   8012                                 lport_tab_field_count, lport_tab_fields,
   8013                                 lport_tab_values));
   8014                     }
   8015                 }
   8016             }
   8017         }
   8018     }
   8019 
   8020     return rv;
   8021 }
   8022 
   8023 int
   8024 _bcm_esw_port_tab_set_without_portlock(int unit, bcm_port_t port, int cpu_tabs,
   8025                                        soc_field_t field, int value)
   8026 {
   8027     return (_bcm_esw_port_tab_multi_set(unit, port, cpu_tabs, 1, &field,
   8028                                 (uint32*) &value));
   8029 }
   8030 
   8031 /*
   8032  * Function:
   8033  *      _bcm_esw_port_tab_set
   8034  * Description:
   8035  *      Sets the port property field in the HW table.
   8036  *      Helper funtion for bcm_esw_port_control_set.
   8037  * Parameters:
   8038  *      unit  - Device number
   8039  *      port  - Port number (see Notes for valid port formats)
   8040  *      cpu_tabs - If CPU port, which ingress tables should be written?
   8041  *      field - Field name within PORT_TAB table entry
   8042  *      value - new field value
   8043  * Return Value:
   8044  *      BCM_E_NONE
   8045  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   8046  * Notes:
   8047  *      Due to the large number of callers for this routine,
   8048  *      function is expanded to take a GPORT PROXY, which
   8049  *      sets the property in the LPORT profile table (similar
   8050  *      to what was done for the GPORT_WLAN_PORT).
   8051  *
   8052  *      Current valid port types are:
   8053  *          GPORT WLAN
   8054  *          GPORT PROXY
   8055  *          GPORT SUBPORT
   8056  *          BCM port (non-gport), assumes a valid local physical port
   8057  *
   8058  *     For GPORT PROXY port, this routine only accesses the properties
   8059  *     in the LPORT table (not the RTAG7).
   8060  */
   8061 int
   8062 _bcm_esw_port_tab_set(int unit, bcm_port_t port, int cpu_tabs,
   8063                       soc_field_t field, int value)
   8064 {
   8065     int rv = BCM_E_UNAVAIL;
   8066 
   8067     PORT_LOCK(unit);
   8068     rv = _bcm_esw_port_tab_set_without_portlock(unit, port, cpu_tabs, field,
   8069                                                 value);
   8070     PORT_UNLOCK(unit);
   8071 
   8072     return rv;
   8073 }
   8074 
   8075 #if defined(BCM_TRX_SUPPORT)
   8076 /*
   8077  * Function:
   8078  *      _bcm_esw_iport_tab_get
   8079  * Description:
   8080  *      Helper funtion for bcm_esw_port_control_get.
   8081  * Parameters:
   8082  *      unit  - Device number
   8083  *      port  - Port number
   8084  *      field - Field name within IPORT_TAB table entry
   8085  *      value - (OUT) field value
   8086  * Return Value:
   8087  *      BCM_E_NONE
   8088  *      BCM_E_XXX - an error occurred accessing IPORT_TAB table.
   8089  */
   8090 STATIC int
   8091 _bcm_esw_iport_tab_get(int unit, bcm_port_t port,
   8092                       soc_field_t field, int *value)
   8093 {
   8094     port_tab_entry_t pent;
   8095     soc_mem_t mem = INVALIDm;
   8096     int rv, index = -1;
   8097 
   8098     if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   8099         mem = IPORT_TABLEm;
   8100         index = SOC_PORT_MOD_OFFSET(unit, port);
   8101     } else if (IS_CPU_PORT(unit, port)) {
   8102         int cpu_hg_index;
   8103 
   8104         cpu_hg_index = SOC_IS_KATANA2(unit) ?
   8105                        SOC_INFO(unit).cpu_hg_pp_port_index :
   8106                        SOC_INFO(unit).cpu_hg_index;
   8107         if (cpu_hg_index != -1){
   8108             mem = PORT_TABm;
   8109             index = cpu_hg_index;
   8110         }
   8111     }
   8112     if (index == -1) {
   8113         return BCM_E_UNAVAIL;
   8114     }
   8115 
   8116     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   8117         return (BCM_E_UNAVAIL);
   8118     }
   8119     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   8120                       index, &pent);
   8121 
   8122     if (BCM_SUCCESS(rv)) {
   8123         *value = soc_mem_field32_get(unit, mem, &pent, field);
   8124     }
   8125 
   8126     return rv;
   8127 }
   8128 #endif /* BCM_TRX_SUPPORT */
   8129 
   8130 /*
   8131  * Function:
   8132  *      _bcm_esw_port_tab_get
   8133  * Description:
   8134  *      Helper funtion for bcm_esw_port_control_get.
   8135  * Parameters:
   8136  *      unit  - Device number
   8137  *      port  - Port number
   8138  *      field - Field name within PORT_TAB table entry
   8139  *      value - (OUT) field value
   8140  * Return Value:
   8141  *      BCM_E_NONE
   8142  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   8143  * Notes:
   8144  *      Due to the large number of callers for this routine,
   8145  *      function is expanded to take a GPORT PROXY, which
   8146  *      get the property from the LPORT profile table (similar
   8147  *      to what was done for the GPORT_WLAN_PORT).
   8148  *
   8149  *      Current valid port types are:
   8150  *          GPORT WLAN
   8151  *          GPORT PROXY
   8152  *          GPORT SUBPORT
   8153  *          BCM port (non-gport), assumes a valid local physical port
   8154  *          GPORT Local
   8155  *
   8156  *     For GPORT PROXY port, this routine only accesses the properties
   8157  *     in the LPORT table (not the RTAG7).
   8158  */
   8159 int
   8160 _bcm_esw_port_tab_get(int unit, bcm_port_t port,
   8161                       soc_field_t field, int *value)
   8162 {
   8163     int rv = BCM_E_UNAVAIL;
   8164     port_tab_entry_t pent;
   8165     soc_mem_t mem;
   8166     int index, is_lport_cfg = 0;
   8167     uint32 value32;
   8168 
   8169     mem = SOC_PORT_MEM_TAB(unit, port);
   8170 #if defined(BCM_TRIDENT3_SUPPORT)
   8171     if (SOC_IS_TRIDENT3X(unit)) {
   8172         _bcm_td3_port_tab_conv(unit, &field, &mem);
   8173         if (mem == LPORT_TABm) {
   8174             is_lport_cfg = 1;
   8175         }
   8176     }
   8177 #endif
   8178 
   8179 #if defined BCM_HGPROXY_COE_SUPPORT
   8180     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   8181         (soc_feature(unit, soc_feature_channelized_switching))) &&
   8182          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8183             is_lport_cfg = 1;
   8184     } else
   8185 #endif
   8186     if (BCM_GPORT_IS_PROXY(port)) {
   8187         is_lport_cfg = 1;
   8188     }
   8189 
   8190     /* If LPORT, then get property from LPORT table */
   8191     if (is_lport_cfg) {
   8192         rv = bcm_esw_port_lport_field_get(unit, port,
   8193                                           LPORT_PROFILE_LPORT_TAB,
   8194                                           field, &value32);
   8195         *value = value32;
   8196         return rv;
   8197     }
   8198 
   8199     /* GPORT WLAN */
   8200 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8201      && defined(INCLUDE_L3))
   8202     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8203 #if defined(BCM_TRIUMPH3_SUPPORT)
   8204         if (soc_feature(unit, soc_feature_axp)) {
   8205             rv = bcm_tr3_wlan_lport_field_get(unit, port, field, value);
   8206         } else
   8207 #endif /* BCM_TRIUMPH3_SUPPORT */
   8208         if (soc_feature(unit, soc_feature_wlan)) {
   8209             rv = bcm_tr2_wlan_lport_field_get(unit, port, field, value);
   8210         }
   8211         return rv;
   8212     }
   8213 #endif
   8214 
   8215     /* At this point, 'port' needs to be a BCM port (non-gport).
   8216      * convert the gport to local port.
   8217      */
   8218     if (BCM_GPORT_IS_SET(port)) {
   8219         BCM_IF_ERROR_RETURN(
   8220             _bcm_esw_port_gport_validate(unit, port, &port));
   8221     }
   8222 
   8223 #if defined(CANCUN_SUPPORT)
   8224     if (soc_feature(unit, soc_feature_cancun)) {
   8225         if (soc_cancun_cmh_check(unit, mem, field) == SOC_E_NONE) {
   8226             rv = soc_cancun_cmh_mem_get(unit, mem, port,
   8227                      field, (void *)value);
   8228             if (!BCM_SUCCESS(rv)) {
   8229                 return rv;
   8230             }
   8231         }
   8232     }
   8233 #endif
   8234 
   8235     index = SOC_PORT_MOD_OFFSET(unit, port);
   8236     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   8237         return (BCM_E_UNAVAIL);
   8238     }
   8239 
   8240     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   8241                       index, &pent);
   8242 
   8243     if (BCM_SUCCESS(rv)) {
   8244         *value = soc_mem_field32_get(unit, mem, &pent, field);
   8245     }
   8246 
   8247     return rv;
   8248 }
   8249 
   8250 /*
   8251  * Function:
   8252  *      bcm_port_untagged_vlan_get
   8253  * Purpose:
   8254  *      Retrieve the default VLAN ID for the port.
   8255  *      This is the VLAN ID assigned to received untagged packets.
   8256  * Parameters:
   8257  *      unit - StrataSwitch unit number.
   8258  *      port - StrataSwitch port number of port to get info for
   8259  *      vid_ptr - (OUT) Pointer to VLAN ID for return
   8260  * Returns:
   8261  *      BCM_E_NONE
   8262  *      BCM_E_INTERNAL if table read failed.
   8263  */
   8264 
   8265 int
   8266 bcm_esw_port_untagged_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vid_ptr)
   8267 {
   8268     bcm_port_cfg_t              pcfg;
   8269     int                         vid;
   8270     int                         rv;
   8271 
   8272     /* Make sure port module is initialized. */
   8273     PORT_INIT(unit);
   8274 
   8275     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8276         LOG_ERROR(BSL_LS_BCM_PORT,
   8277                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   8278                    port));
   8279         return BCM_E_PARAM;
   8280     }
   8281 
   8282 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8283      && defined(INCLUDE_L3))
   8284     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8285 #if defined(BCM_TRIUMPH3_SUPPORT)
   8286         if (SOC_IS_TRIUMPH3(unit)) {
   8287             return bcm_tr3_wlan_port_untagged_vlan_get(unit, port, vid_ptr);
   8288         } else
   8289 #endif /* BCM_TRIUMPH3_SUPPORT */
   8290         {
   8291             return bcm_tr2_wlan_port_untagged_vlan_get(unit, port, vid_ptr);
   8292         }
   8293     }
   8294 #endif
   8295 
   8296 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8297     if (BCM_GPORT_IS_NIV_PORT(port)) {
   8298         return bcm_trident_niv_port_untagged_vlan_get(unit, port, vid_ptr);
   8299     }
   8300 #endif
   8301 
   8302 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   8303     if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   8304         return bcm_tr3_extender_port_untagged_vlan_get(unit, port, vid_ptr);
   8305     }
   8306 #endif
   8307 
   8308 #ifdef BCM_HGPROXY_COE_SUPPORT
   8309     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   8310         (soc_feature(unit, soc_feature_channelized_switching))) &&
   8311          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8312         rv = _bcm_esw_port_tab_get(unit, port, PORT_VIDf, &vid);
   8313     } else
   8314 #endif
   8315     {
   8316         BCM_IF_ERROR_RETURN(
   8317             _bcm_esw_port_gport_validate(unit, port, &port));
   8318 
   8319         PORT_LOCK(unit);
   8320         rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
   8321         PORT_UNLOCK(unit);
   8322         vid = pcfg.pc_vlan;
   8323     }
   8324 
   8325     if (BCM_SUCCESS(rv)) {
   8326         *vid_ptr = vid;
   8327     } else {
   8328         *vid_ptr = BCM_VLAN_INVALID;
   8329     }
   8330 
   8331     LOG_INFO(BSL_LS_BCM_PORT,
   8332              (BSL_META_U(unit,
   8333                          "bcm_port_untagged_vlan_get: u=%d p=%d vid=%d rv=%d\n"),
   8334               unit, port, *vid_ptr, rv));
   8335 
   8336     return rv;
   8337 }
   8338 
   8339 
   8340 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   8341 /*
   8342  * Function:
   8343  *      _bcm_port_mmu_update
   8344  * Purpose:
   8345  *      Adjust MMU settings depending on port status.
   8346  * Parameters:
   8347  *      unit - StrataSwitch Unit #.
   8348  *      port - StrataSwitch port #.
   8349  *      link -  True if link is active, false if link is inactive.
   8350  * Returns:
   8351  *      BCM_E_NONE
   8352  *      BCM_E_XXX
   8353  */
   8354 
   8355 STATIC int
   8356 _bcm_port_mmu_update(int unit, bcm_port_t port, int link)
   8357 {
   8358     int pause_tx, pause_rx, q_limit_enable, cos;
   8359     uint32 psl_rval, opc_rval, oqc_rval;
   8360 
   8361     if (!SOC_IS_HBX(unit)) {
   8362         return (BCM_E_UNAVAIL);
   8363     }
   8364 
   8365     if (link < 0) {
   8366         SOC_IF_ERROR_RETURN
   8367             (bcm_esw_port_link_status_get(unit, port, &link));
   8368     }
   8369 
   8370     SOC_IF_ERROR_RETURN
   8371         (MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port,
   8372                        &pause_tx, &pause_rx));
   8373 
   8374     SOC_IF_ERROR_RETURN(READ_PORT_SHARED_LIMITr(unit, port, &psl_rval));
   8375     SOC_IF_ERROR_RETURN(READ_OP_PORT_CONFIGr(unit, port, &opc_rval));
   8376     if (link && pause_tx) {
   8377         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8378                           PORT_SHARED_LIMITf,
   8379                           SOC_IS_SC_CQ(unit) ? 0x5 : 0x3);
   8380         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8381                           PORT_SHARED_DYNAMICf, 1);
   8382         soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval,
   8383                           PORT_LIMIT_ENABLEf, 1);
   8384         q_limit_enable = 0;
   8385     } else {
   8386         /* Turn off */
   8387         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8388                           PORT_SHARED_LIMITf,
   8389                           SOC_IS_SC_CQ(unit) ? 0x3fff : 0x3000);
   8390         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8391                           PORT_SHARED_DYNAMICf, 0);
   8392         soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval,
   8393                           PORT_LIMIT_ENABLEf, 0);
   8394         q_limit_enable = 1;
   8395     }
   8396     SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMITr(unit, port, psl_rval));
   8397     SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIGr(unit, port, opc_rval));
   8398     for (cos = 0; cos < NUM_COS(unit); cos++) {
   8399         SOC_IF_ERROR_RETURN
   8400             (READ_OP_QUEUE_CONFIGr(unit, port, cos, &oqc_rval));
   8401         soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &oqc_rval,
   8402                           Q_LIMIT_ENABLEf, q_limit_enable);
   8403         SOC_IF_ERROR_RETURN
   8404             (WRITE_OP_QUEUE_CONFIGr(unit, port, cos, oqc_rval));
   8405     }
   8406 
   8407     return (BCM_E_NONE);
   8408 }
   8409 #endif /* BCM_BRADLEY_SUPPORT || BCM_SCORPION_SUPPORT */
   8410 
   8411 /*
   8412  * Function:
   8413  *      _bcm_port_untagged_vlan_set
   8414  * Purpose:
   8415  *      Main part of bcm_port_untagged_vlan_set.
   8416  * Notes:
   8417  *      Port does not have to be a member of the VLAN.
   8418  */
   8419 
   8420 STATIC int
   8421 _bcm_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid)
   8422 {
   8423     bcm_port_cfg_t      pcfg;
   8424     int                 ut_prio;
   8425 #if defined(BCM_FIREBOLT_SUPPORT)
   8426     bcm_vlan_t          pdvid;
   8427 #endif /* BCM_FIREBOLT_SUPPORT */
   8428 
   8429 #ifdef BCM_TRX_SUPPORT
   8430     if (soc_feature(unit, soc_feature_vlan_action)) {
   8431         bcm_port_t local_port;
   8432         bcm_vlan_action_set_t action;
   8433 #if defined(BCM_TOMAHAWK_SUPPORT)
   8434         bcm_port_cfg_t pcfg;
   8435 #endif
   8436         BCM_IF_ERROR_RETURN(
   8437             _bcm_esw_port_gport_validate(unit, port, &local_port));
   8438 
   8439 #if defined(BCM_TOMAHAWK3_SUPPORT)
   8440 		if (SOC_IS_TOMAHAWK3(unit)) {
   8441              BCM_IF_ERROR_RETURN
   8442                  (_bcm_th3_vlan_port_default_action_get(unit, port, &action));
   8443 		} else
   8444 #endif
   8445 		{
   8446              BCM_IF_ERROR_RETURN
   8447                  (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
   8448         }
   8449         action.new_outer_vlan = vid;
   8450         action.priority = PORT(unit, local_port).p_ut_prio;
   8451 #if defined(BCM_TOMAHAWK_SUPPORT)
   8452         if (soc_feature(unit, soc_feature_decouple_protocol_vlan)){
   8453             BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, &action));
   8454             BCM_IF_ERROR_RETURN
   8455                 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
   8456             pcfg.pc_vlan = action.new_outer_vlan;
   8457             if (action.priority >= BCM_PRIO_MIN &&
   8458                 action.priority <= BCM_PRIO_MAX) {
   8459                 pcfg.pc_new_opri = action.priority;
   8460             }
   8461             return (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
   8462         }
   8463 #endif /* BCM_TOMAHAWK2_SUPPORT */
   8464 #if defined(BCM_TOMAHAWK3_SUPPORT)
   8465 		if(SOC_IS_TOMAHAWK3(unit)) {
   8466 			return _bcm_th3_vlan_port_default_action_set(unit, port, &action);
   8467 		} else
   8468 #endif
   8469 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   8470         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   8471             return _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action);
   8472         } else
   8473 #endif
   8474         {
   8475             return _bcm_trx_vlan_port_default_action_set(unit, port, &action);
   8476         }
   8477     }
   8478 #endif
   8479 
   8480     BCM_IF_ERROR_RETURN
   8481         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
   8482 
   8483 #if defined(BCM_FIREBOLT_SUPPORT)
   8484     pdvid = pcfg.pc_vlan;
   8485 #endif /* BCM_FIREBOLT_SUPPORT */
   8486     pcfg.pc_vlan = vid;
   8487 
   8488     BCM_IF_ERROR_RETURN
   8489         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
   8490 
   8491 #if defined(BCM_FIREBOLT_SUPPORT)
   8492     if (SOC_IS_FBX(unit)) {
   8493         /*
   8494          * Update default VLAN ID in VLAN_PROTOCOL_DATA
   8495          */
   8496         int rv = _bcm_fb_port_untagged_vlan_data_update(unit, port,
   8497                                                         pdvid, vid);
   8498         if (rv != BCM_E_NONE) {
   8499             LOG_ERROR(BSL_LS_BCM_PORT,
   8500                       (BSL_META_U(unit,
   8501                                   "failed updating default VLAN ID "
   8502                                   "in VLAN_PROTOCOL_DATA: %s\n"), bcm_errmsg(rv)));
   8503         }
   8504     }
   8505 #endif /* BCM_FIREBOLT_SUPPORT */
   8506 
   8507     if (!soc_feature(unit, soc_feature_remap_ut_prio)) {
   8508         /* Reset the untagged port priority filter entry, if any */
   8509 
   8510         BCM_IF_ERROR_RETURN
   8511             (bcm_esw_port_untagged_priority_get(unit, port, &ut_prio));
   8512 
   8513         BCM_IF_ERROR_RETURN
   8514             (bcm_esw_port_untagged_priority_set(unit, port, ut_prio));
   8515     }
   8516 
   8517     return BCM_E_NONE;
   8518 }
   8519 
   8520 /*
   8521  * Function:
   8522  *      bcm_port_untagged_vlan_set
   8523  * Purpose:
   8524  *      Set the default VLAN ID for the port.
   8525  *      This is the VLAN ID assigned to received untagged packets.
   8526  * Parameters:
   8527  *      unit - StrataSwitch unit number.
   8528  *      port - StrataSwitch port number.
   8529  *      vid -  VLAN ID used for packets that ingress the port untagged
   8530  * Returns:
   8531  *      BCM_E_NONE
   8532  *      BCM_E_NOT_FOUND if vid not in VTABLE
   8533  *      BCM_E_INTERNAL if table read failed.
   8534  *      BCM_E_CONFIG - port does not belong to the VLAN
   8535  * Notes:
   8536  *      BCM_LOCK is used because bcm_vlan_port_get is called internally
   8537  *      which also takes it.  BCM_LOCK must be taken before PORT_LOCK.
   8538  */
   8539 
   8540 int
   8541 bcm_esw_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid)
   8542 {
   8543     int rv;
   8544 
   8545     VLAN_CHK_ID(unit, vid);
   8546 
   8547     /* Make sure port module is initialized. */
   8548     PORT_INIT(unit);
   8549 
   8550     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8551         LOG_ERROR(BSL_LS_BCM_PORT,
   8552                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   8553                    port));
   8554         return BCM_E_PARAM;
   8555     }
   8556 
   8557 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8558      && defined(INCLUDE_L3))
   8559     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8560 #if defined(BCM_TRIUMPH3_SUPPORT)
   8561         if (SOC_IS_TRIUMPH3(unit)) {
   8562             return bcm_tr3_wlan_port_untagged_vlan_set(unit, port, vid);
   8563         } else
   8564 #endif /* BCM_TRIUMPH3_SUPPORT */
   8565         {
   8566             return bcm_tr2_wlan_port_untagged_vlan_set(unit, port, vid);
   8567         }
   8568     }
   8569 #endif
   8570 
   8571 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8572     if (BCM_GPORT_IS_NIV_PORT(port)) {
   8573         return bcm_trident_niv_port_untagged_vlan_set(unit, port, vid);
   8574     }
   8575 #endif
   8576 
   8577 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   8578     if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   8579         return bcm_tr3_extender_port_untagged_vlan_set(unit, port, vid);
   8580     }
   8581 #endif
   8582 
   8583 #ifdef BCM_HGPROXY_COE_SUPPORT
   8584     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
   8585         (soc_feature(unit, soc_feature_channelized_switching))) &&
   8586          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8587     } else
   8588 #endif
   8589     {
   8590         BCM_IF_ERROR_RETURN(
   8591             _bcm_esw_port_gport_validate(unit, port, &port));
   8592     }
   8593 
   8594     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) ||
   8595         SOC_IS_TRIDENT3X(unit) ||
   8596         SOC_IS_KATANAX(unit) || SOC_IS_SABER2(unit)) {
   8597         BCM_IF_ERROR_RETURN
   8598         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   8599                                                PORT_VIDf, vid));
   8600     }
   8601 
   8602     PORT_LOCK(unit);
   8603     rv = _bcm_port_untagged_vlan_set(unit, port, vid);
   8604     PORT_UNLOCK(unit);
   8605 
   8606     LOG_INFO(BSL_LS_BCM_PORT,
   8607              (BSL_META_U(unit,
   8608                          "bcm_port_untagged_vlan_set: u=%d p=%d vid=%d rv=%d\n"),
   8609               unit, port, vid, rv));
   8610 
   8611     return rv;
   8612 }
   8613 
   8614 /*
   8615  * Function:
   8616  *      _bcm_esw_port_ingress_dest_enable
   8617  * Purpose:
   8618  *      Enables/disables all forwarding to port in the last stage
   8619  *      of the ingress pipeline, including SOBMH and all
   8620  *      other types of traffic.  Works for all egress ports,
   8621  *      including CPU port.
   8622  * Parameters:
   8623  *      unit   - (IN) Device number.
   8624  *      port   - (IN) Port number.
   8625  *      enable - (IN) TRUE, forward traffic
   8626  *                    FALSE, block traffic
   8627  * Returns:
   8628  *      BCM_E_XXX
   8629  */
   8630 int
   8631 _bcm_esw_port_ingress_dest_enable(int unit, bcm_port_t port, int enable)
   8632 {
   8633 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT)
   8634     ing_dest_port_enable_entry_t dest_e;
   8635     bcm_pbmp_t dest_e_pbmp;
   8636     sal_usecs_t delay;
   8637     int speed;
   8638     int change = FALSE;
   8639 
   8640     SOC_IF_ERROR_RETURN
   8641         (READ_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e));
   8642 
   8643     soc_mem_pbmp_field_get(unit, ING_DEST_PORT_ENABLEm,
   8644                            &dest_e, PORT_BITMAPf, &dest_e_pbmp);
   8645 
   8646     if (enable) {
   8647         if (!SOC_PBMP_MEMBER(dest_e_pbmp, port)) {
   8648             SOC_PBMP_PORT_ADD(dest_e_pbmp, port);
   8649             change = TRUE;
   8650         }
   8651     } else {
   8652         if (SOC_PBMP_MEMBER(dest_e_pbmp, port)) {
   8653             SOC_PBMP_PORT_REMOVE(dest_e_pbmp, port);
   8654             change = TRUE;
   8655         }
   8656     }
   8657 
   8658     if (change) {
   8659         soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm,
   8660                                &dest_e, PORT_BITMAPf, &dest_e_pbmp);
   8661         SOC_IF_ERROR_RETURN
   8662             (WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e));
   8663 
   8664         /*
   8665          * On a disable operation, ensure that no further cells
   8666          * arrive to MMU in order to reconfigure the MMU safely,
   8667          * and the flush mechanism in the MMU to work properly.
   8668          *
   8669          * This requires a delay to ensure packet EOP has arrived at MMU
   8670          * (the is the only method.  The time is based on the largest
   8671          * possible frame at the slowest possible source port speed.
   8672          */
   8673         if (!enable) {
   8674             BCM_IF_ERROR_RETURN
   8675                 (bcm_esw_port_speed_get(unit, port, &speed));
   8676 
   8677             if ((speed == 10) || (speed == 100)) {
   8678                 delay = 8000;  /* 8 msecs */
   8679             } else {
   8680                 /*
   8681                  * This assumes the CPU port can sustain 1GE performance
   8682                  * over the duration of an MTU.
   8683                  */
   8684                 delay = 80;    /* 80 usecs */
   8685             }
   8686             sal_udelay(delay);
   8687         }
   8688     }
   8689 
   8690     return BCM_E_NONE;
   8691 #else  /* BCM_TRIDENT2PLUS_SUPPORT */
   8692     return BCM_E_UNAVAIL;
   8693 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8694 }
   8695 
   8696 /*
   8697  * Function:
   8698  *      _bcmi_esw_port_linkphy_subport_dfc_update
   8699  * Purpose:
   8700  *      Updates the DFC for the stream ids associated with Linkphy gport.
   8701  * Parameters:
   8702  *      unit   - (IN) Device number.
   8703  *      subport_gport - (IN) Linkphy gport.
   8704  *      enable - (IN) Port enable/disable status.
   8705  * Returns:
   8706  *      BCM_E_XXX
   8707  */
   8708 
   8709 #ifdef BCM_KATANA2_SUPPORT
   8710 int
   8711 _bcmi_esw_port_linkphy_subport_dfc_update(int unit, bcm_port_t subport_gport,
   8712                                           int enable)
   8713 {
   8714     bcm_subport_config_t config;
   8715     int stream_id = 0;
   8716 
   8717     BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config));
   8718 
   8719     /* Run through the streams and perform needed actions */
   8720     for (stream_id = 0; stream_id < config.num_streams; stream_id++) {
   8721             BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_dfc_update(unit,
   8722                                    &config,
   8723                                   _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport),
   8724                                    config.stream_id_array[stream_id], enable));
   8725     }
   8726 
   8727     return BCM_E_NONE;
   8728 }
   8729 
   8730 int
   8731 _bcmi_esw_port_linkphy_subport_flush(int unit, bcm_port_t subport_gport)
   8732 {
   8733     bcm_subport_config_t config;
   8734     int stream_id = 0;
   8735 
   8736     BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config));
   8737 
   8738     /* Run through the streams and perform needed actions */
   8739     for (stream_id = 0; stream_id < config.num_streams; stream_id++) {
   8740             BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_flush(unit,
   8741                                    &config,
   8742                                   _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport),
   8743                                    config.stream_id_array[stream_id]));
   8744     }
   8745 
   8746     return BCM_E_NONE;
   8747 }
   8748 #endif
   8749 
   8750 /*
   8751  * Function:
   8752  *      _bcmi_esw_port_subport_enable_set
   8753  * Purpose:
   8754  *      Enable/disable a subport.
   8755  * Parameters:
   8756  *      unit - StrataSwitch unit #.
   8757  *      port - StrataSwitch port #.
   8758  *      is_subtag_port - TRUE if this is subtag port, linkphy otherwise
   8759  *      enable - TRUE, port is enabled, FALSE port is disabled.
   8760  * Returns:
   8761  *      BCM_E_XXX
   8762  */
   8763 int
   8764 _bcmi_esw_port_subport_enable_set(int unit, bcm_port_t port,
   8765                                   int is_subtag_port, int enable)
   8766 {
   8767 
   8768     int rv = BCM_E_NONE;
   8769 
   8770 #ifdef BCM_KATANA2_SUPPORT
   8771     pbmp_t      mask;
   8772     int         subport_gport = port;
   8773 
   8774     BCM_IF_ERROR_RETURN(
   8775         _bcm_esw_port_gport_validate(unit, port, &port));
   8776 
   8777     /* Set/Unset the port in the relevant enabled pbmp */
   8778     if(is_subtag_port) {
   8779 
   8780         /* Check if the setting is already in effect */
   8781         if((enable &&
   8782             BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8783                                   port)) ||
   8784            (!enable &&
   8785             !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8786                                   port)))) {
   8787             /* Already in effect, return OK */
   8788             return  BCM_E_NONE;
   8789         }
   8790 
   8791         if(enable) {
   8792             BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8793                               port);
   8794         } else {
   8795             BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8796                               port);
   8797         }
   8798     } else {
   8799 
   8800         /* Check if the setting is already in effect */
   8801         if((enable &&
   8802             BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8803                                   port)) ||
   8804            (!enable &&
   8805             !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8806                                   port)))) {
   8807             /* Already in effect, return OK */
   8808             return  BCM_E_NONE;
   8809         }
   8810 
   8811         if(enable) {
   8812             BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8813                               port);
   8814         } else {
   8815             BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8816                               port);
   8817         }
   8818     }
   8819 
   8820     /* Get the current mask */
   8821     soc_link_mask2_get(unit, &mask);
   8822     /* Make a call so that the enable/disable we did above take effect,
   8823      * note that 'soc_link_mask2_set' works on the pbmps we updated above,
   8824      * we still pass the existing bpmp since it gets re-assigned
   8825      */
   8826     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
   8827 
   8828     /* Some special processing needed for enable/disable of LinkPhy ports */
   8829     if (!is_subtag_port) {
   8830 
   8831         /* Updates DFC for the streams */
   8832         BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_dfc_update(unit,
   8833                             subport_gport, enable));
   8834         if (!enable) {
   8835         /* Flush the related MMU queues */
   8836         BCM_IF_ERROR_RETURN(bcm_kt2_cosq_port_flush(unit,
   8837                                   port, bcmCosqFlushTypeQueue));
   8838 
   8839         /* Flush the relevant RXLP */
   8840         BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_flush(unit,
   8841                                                  subport_gport));
   8842     }
   8843     }
   8844 
   8845 #endif
   8846 
   8847     return rv;
   8848 }
   8849 
   8850 /*
   8851  * Function:
   8852  *      _bcmi_esw_port_subport_enable_get
   8853  * Purpose:
   8854  *      Get Enable/disable state of a subport.
   8855  * Parameters:
   8856  *      unit - StrataSwitch unit #.
   8857  *      port - StrataSwitch port #.
   8858  *      is_subtag_port - TRUE if this is subtag port, linkphy otherwise
   8859  *      *enable - Return enable value.
   8860  * Returns:
   8861  *      BCM_E_XXX
   8862  */
   8863 int
   8864 _bcmi_esw_port_subport_enable_get(int unit, bcm_port_t port,
   8865                                   int is_subtag_port, int *enable)
   8866 {
   8867     int rv = BCM_E_NONE;
   8868 
   8869 #ifdef BCM_KATANA2_SUPPORT
   8870     /* Start with enabled set to 0 */
   8871     *enable = 0;
   8872 
   8873     BCM_IF_ERROR_RETURN(
   8874         _bcm_esw_port_gport_validate(unit, port, &port));
   8875 
   8876     /* Depending on subtag/linkphy, check if the port is enabled */
   8877     if(is_subtag_port) {
   8878         if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8879                         port)) {
   8880             *enable = 1;
   8881         }
   8882     } else {
   8883         if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8884                         port)) {
   8885             *enable = 1;
   8886         }
   8887     }
   8888     rv = BCM_E_NONE;
   8889 #endif
   8890 
   8891     return rv;
   8892 }
   8893 
   8894 /*
   8895  * Function:
   8896  *      bcm_port_enable_set
   8897  * Purpose:
   8898  *      Physically enable/disable the MAC/PHY on this port.
   8899  * Parameters:
   8900  *      unit - StrataSwitch unit #.
   8901  *      port - StrataSwitch port #.
   8902  *      enable - TRUE, port is enabled, FALSE port is disabled.
   8903  * Returns:
   8904  *      BCM_E_XXX
   8905  * Notes:
   8906  *      If linkscan is running, it also controls the MAC enable state.
   8907  */
   8908 
   8909 int
   8910 bcm_esw_port_enable_set(int unit, bcm_port_t port, int enable)
   8911 {
   8912     int         rv = BCM_E_NONE;
   8913     int         link, loopback = BCM_PORT_LOOPBACK_NONE;
   8914     pbmp_t      mask;
   8915 
   8916 #if defined (BCM_TRIUMPH3_SUPPORT) || defined (BCM_MONTEREY_SUPPPORT)
   8917     int         skip_phy_en = 0;
   8918 #endif /* BCM_TRIUMPH3_SUPPORT */
   8919     soc_persist_t       *sop = SOC_PERSIST(unit);
   8920 
   8921 #if defined(BCM_KATANA2_SUPPORT)
   8922     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
   8923     uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE;
   8924 #endif
   8925     /* Make sure port module is initialized. */
   8926     PORT_INIT(unit);
   8927 
   8928 #ifdef BCM_KATANA2_SUPPORT
   8929     if(BCM_GPORT_IS_SUBPORT_PORT(port)) {
   8930         if (soc_feature(unit, soc_feature_subtag_coe) &&
   8931             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8932            is_subtag_port = TRUE;
   8933        } else if (soc_feature(unit, soc_feature_linkphy_coe) &&
   8934                   _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) {
   8935            is_linkphy_port = TRUE;
   8936        }
   8937        if(is_subtag_port || is_linkphy_port) {
   8938            PORT_LOCK(unit);
   8939            rv = _bcmi_esw_port_subport_enable_set(unit, port,
   8940                                                   is_subtag_port, enable);
   8941            PORT_UNLOCK(unit);
   8942            return rv;
   8943         }
   8944     }
   8945 #endif
   8946 
   8947     /* Call Port Control module */
   8948     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
   8949         return (bcmi_esw_portctrl_enable_set(unit, port, enable));
   8950     }
   8951 
   8952     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8953         LOG_ERROR(BSL_LS_BCM_PORT,
   8954                   (BSL_META("Error: Cannot enable OAMP Port %d.\n"),
   8955                    port));
   8956         return BCM_E_PARAM;
   8957     }
   8958 
   8959 #if defined(BCM_KATANA2_SUPPORT)
   8960 #if defined(BCM_SABER2_SUPPORT)
   8961     if(SOC_IS_SABER2(unit)) {
   8962         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
   8963     }
   8964 #endif
   8965     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
   8966         (!((port >= 1) && (port <= max_phy_port)))) {
   8967          return BCM_E_PORT;
   8968     }
   8969 #endif
   8970 
   8971     if (!BCM_GPORT_IS_SET(port)) {
   8972         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {
   8973             return BCM_E_PORT;
   8974         }
   8975     }
   8976 
   8977     BCM_IF_ERROR_RETURN(
   8978         _bcm_esw_port_gport_validate(unit, port, &port));
   8979 
   8980 #ifdef BCM_RCPU_SUPPORT
   8981     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
   8982         return BCM_E_PORT;
   8983     }
   8984 #endif /* BCM_RCPU_SUPPORT */
   8985 
   8986 #ifdef BCM_TRIUMPH3_SUPPORT
   8987     if (SOC_IS_TRIUMPH3(unit) && !enable) {
   8988         _bcm_esw_ibod_syn_port_down(unit, port);
   8989     }
   8990 #endif /* BCM_TRIUMPH3_SUPPORT */
   8991 
   8992     PORT_LOCK(unit);
   8993 
   8994     bcm_esw_port_loopback_get(unit, port, &loopback);
   8995 
   8996     if (enable) {
   8997         if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   8998             PORT_UNLOCK(unit);
   8999             return BCM_E_NONE;
   9000         }
   9001 
   9002 #ifdef BCM_TRIUMPH3_SUPPORT
   9003         if (!skip_phy_en) {
   9004 #endif /* BCM_TRIUMPH3_SUPPORT */
   9005 #ifdef BCM_TRIDENT2_SUPPORT
   9006             /*
   9007              * When the PHY is TSC and port is configured to MAC loopback,
   9008              * need to unsquelch TX LANE.
   9009              */
   9010             if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit))
   9011                 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))
   9012                 && (loopback == BCM_PORT_LOOPBACK_MAC)) {
   9013                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE);
   9014             }
   9015 #endif /* BCM_TRIDENT2_SUPPORT */
   9016             rv = soc_phyctrl_enable_set(unit, port, TRUE);
   9017 #ifdef BCM_TRIUMPH3_SUPPORT
   9018         }
   9019 #endif /* BCM_TRIUMPH3_SUPPORT */
   9020         if (SOC_SUCCESS(rv)) {
   9021             /* Get link status after PHY state has been set */
   9022             rv = bcm_esw_port_link_status_get(unit, port, &link);
   9023             if (BCM_FAILURE(rv)) {
   9024                 if (rv == BCM_E_INIT) {
   9025                     link = FALSE;
   9026                     rv = BCM_E_NONE;
   9027                 } else {
   9028                     PORT_UNLOCK(unit);
   9029                     return rv;
   9030                 }
   9031             }
   9032 
   9033             if (link || (loopback != BCM_PORT_LOOPBACK_NONE)
   9034                 || SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)
   9035                 || SOC_PBMP_MEMBER(sop->lc_pbm_linkdown_tx, port)) {
   9036                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE);
   9037                 if (loopback == BCM_PORT_LOOPBACK_MAC) {
   9038                     /* Add port to EPC_LINK */
   9039                     soc_link_mask2_get(unit, &mask);
   9040                     SOC_PBMP_PORT_ADD(mask, port);
   9041                     rv = soc_link_mask2_set(unit, mask);
   9042                     if (BCM_FAILURE(rv)) {
   9043                         PORT_UNLOCK(unit);
   9044                         return (rv);
   9045                     }
   9046                 }
   9047             }
   9048         }
   9049 
   9050         if (SOC_SUCCESS(rv)) {
   9051             /* Enable forwarding traffic */
   9052             if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) {
   9053                 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable);
   9054                 if (BCM_FAILURE(rv)) {
   9055                     PORT_UNLOCK(unit);
   9056                     return rv;
   9057                 }
   9058             }
   9059         }
   9060 
   9061     } else {
   9062 
   9063         /* Disable all forwarding traffic */
   9064         if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) {
   9065             rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable);
   9066             if (BCM_FAILURE(rv)) {
   9067                 PORT_UNLOCK(unit);
   9068                 return rv;
   9069             }
   9070         }
   9071 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
   9072     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
   9073         bcm_port_info_t tmp_port_info;
   9074         bcm_port_info_t_init(&tmp_port_info);
   9075         tmp_port_info.linkstatus = BCM_PORT_LINK_STATUS_DOWN;
   9076         SOC_LINKSCAN_MODPORT_MAP_LOCK(unit);
   9077         rv = _bcm_td_stk_modport_map_linkscan_handler(unit, port,
   9078                                                       &tmp_port_info);
   9079         SOC_LINKSCAN_MODPORT_MAP_UNLOCK(unit);
   9080         if (BCM_FAILURE(rv)) {
   9081             PORT_UNLOCK(unit);
   9082             return (rv);
   9083         }
   9084     }
   9085 #endif /* #(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) */
   9086         /* Remove from EPC_LINK to prevent packet queued to this port from TX */
   9087         soc_link_mask2_get(unit, &mask);
   9088         SOC_PBMP_PORT_REMOVE(mask, port);
   9089         rv = soc_link_mask2_set(unit, mask);
   9090         if (BCM_FAILURE(rv)) {
   9091             PORT_UNLOCK(unit);
   9092             return (rv);
   9093         }
   9094 #ifdef BCM_HURRICANE4_SUPPORT
   9095         /* Wait 8ms. For non-MAC LB case its handled in MAC RESET */
   9096         if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port) &&
   9097             (loopback == BCM_PORT_LOOPBACK_MAC)) {
   9098             int wait_us = 8000;
   9099             if (SAL_BOOT_QUICKTURN) {
   9100                 wait_us += 10000;
   9101             }
   9102             sal_usleep(wait_us);
   9103         }
   9104 #endif
   9105         LOG_VERBOSE(BSL_LS_BCM_PORT,
   9106                     (BSL_META_U(unit,
   9107                                 "Disable and isolate port %d..\n"),
   9108                      port));
   9109         if ((!SOC_IS_TD2_TT2(unit) && (loopback != BCM_PORT_LOOPBACK_MAC)) ||
   9110             (SOC_IS_TOMAHAWKX(unit) && (loopback != BCM_PORT_LOOPBACK_MAC))) {
   9111             /* Disable MAC RX to prevent traffic going into this port */
   9112             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9113                             SOC_MAC_CONTROL_RX_SET, FALSE);
   9114             sal_udelay(100); /* Wait for 1 jumbo packet transmission time */
   9115         }
   9116 
   9117 #ifdef BCM_KATANA_SUPPORT
   9118         if (SOC_IS_KATANA(unit)) {
   9119             /*
   9120              * When the port is configured to MAC loopback,
   9121              * can't disabling MAC.
   9122              * But in Saber2, credits are released when MAC goes down.
   9123              */
   9124             if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) {
   9125                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
   9126             }
   9127             if ((SOC_SUCCESS(rv))) {
   9128                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9129                                 SOC_MAC_CONTROL_DISABLE_PHY, TRUE);
   9130                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
   9131                 if (BCM_FAILURE(rv)) {
   9132                     LOG_WARN(BSL_LS_BCM_PORT,
   9133                              (BSL_META_U(unit,
   9134                                          "u=%d p=%d soc_phyctrl_enable_set rv=%d\n"),
   9135                               unit, port, rv));
   9136                 }
   9137                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9138                                 SOC_MAC_CONTROL_DISABLE_PHY, FALSE);
   9139             }
   9140         } else
   9141 #endif /* BCM_KATANA_SUPPORT */
   9142         {
   9143             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9144                             SOC_MAC_CONTROL_DISABLE_PHY, TRUE);
   9145 
   9146 #ifdef BCM_TRIDENT2_SUPPORT
   9147             /*
   9148              * When the PHY is TSC and port is configured to MAC loopback,
   9149              * need to squelch the TX lane instead of disabling PHY.
   9150              */
   9151             if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit))
   9152                 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))
   9153                 && (loopback == BCM_PORT_LOOPBACK_MAC)) {
   9154                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE);
   9155             } else
   9156 #endif /* BCM_TRIDENT2_SUPPORT */
   9157             {
   9158                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
   9159             }
   9160 
   9161             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9162                             SOC_MAC_CONTROL_DISABLE_PHY, FALSE);
   9163             /*
   9164              * When the port is configured to MAC loopback,
   9165              * can't disabling MAC.
   9166              */
   9167             if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) {
   9168                 if (SOC_SUCCESS(rv)) {
   9169                     rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
   9170                 }
   9171             }
   9172         }
   9173     }
   9174 
   9175 #ifdef BCM_SABER2_SUPPORT
   9176     if (SOC_IS_SABER2(unit)) {
   9177         rv = soc_saber2_port_enable_set(unit, port, enable);
   9178         if (BCM_FAILURE(rv)) {
   9179             LOG_WARN(BSL_LS_BCM_PORT,
   9180                      (BSL_META_U(unit,
   9181                                  "u=%d p=%d soc_saber2_port_enable_set rv=%d\n"),
   9182                       unit, port, rv));
   9183         }
   9184     } else
   9185 #endif
   9186 #ifdef BCM_KATANA2_SUPPORT
   9187     if (SOC_IS_KATANA2(unit)) {
   9188         rv = soc_katana2_port_enable_set(unit, port, enable);
   9189         if (BCM_FAILURE(rv)) {
   9190             LOG_WARN(BSL_LS_BCM_PORT,
   9191                      (BSL_META_U(unit,
   9192                                  "u=%d p=%d soc_katana2_port_enable_set rv=%d\n"),
   9193                       unit, port, rv));
   9194         }
   9195     }
   9196 #endif
   9197 #ifdef BCM_TRIDENT2_SUPPORT
   9198     if (SOC_IS_TD2_TT2(unit)) {
   9199         PORT(unit, port).enable = enable;
   9200     }
   9201 #endif /* BCM_TRIDENT2_SUPPORT */
   9202 
   9203 #ifdef SW_AUTONEG_SUPPORT
   9204     rv = _bcm_esw_port_notify_link_down_evt(unit, port);
   9205     if (BCM_FAILURE(rv)) {
   9206         LOG_WARN(BSL_LS_BCM_PORT,
   9207                  (BSL_META_U(unit,
   9208                              "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"),
   9209                   unit, port, rv));
   9210         PORT_UNLOCK(unit);
   9211         return rv;
   9212     }
   9213 #endif
   9214 
   9215     PORT_UNLOCK(unit);
   9216 
   9217     if (loopback != BCM_PORT_LOOPBACK_NONE) {
   9218         if (loopback == BCM_PORT_LOOPBACK_MAC) {
   9219             rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE);
   9220         } else {
   9221             rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, enable);
   9222         }
   9223     }
   9224     LOG_INFO(BSL_LS_BCM_PORT,
   9225              (BSL_META_U(unit,
   9226                          "bcm_port_enable_set: u=%d p=%d enable=%d rv=%d\n"),
   9227               unit, port, enable, rv));
   9228 
   9229 #ifdef BCM_WARM_BOOT_SUPPORT
   9230     SOC_CONTROL_LOCK(unit);
   9231     SOC_CONTROL(unit)->scache_dirty = 1;
   9232     SOC_CONTROL_UNLOCK(unit);
   9233 #endif
   9234 
   9235     return rv;
   9236 }
   9237 
   9238 /*
   9239  * Function:
   9240  *      bcm_port_enable_get
   9241  * Purpose:
   9242  *      Gets the enable state as defined by bcm_port_enable_set()
   9243  * Parameters:
   9244  *      unit - StrataSwitch unit #.
   9245  *      port - StrataSwitch port #.
   9246  *      enable - (OUT) TRUE, port is enabled, FALSE port is disabled.
   9247  * Returns:
   9248  *      BCM_E_XXX
   9249  * Notes:
   9250  *      The PHY enable holds the port enable state set by the user.
   9251  *      The MAC enable transitions up and down automatically via linkscan
   9252  *      even if user port enable is always up.
   9253  */
   9254 
   9255 int
   9256 bcm_esw_port_enable_get(int unit, bcm_port_t port, int *enable)
   9257 {
   9258     int                 rv=BCM_E_NONE;
   9259 #if defined(BCM_KATANA2_SUPPORT)
   9260     uint8       is_subtag_port = FALSE, is_linkphy_port = FALSE;
   9261     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
   9262 #endif
   9263 
   9264     /* Make sure port module is initialized. */
   9265     PORT_INIT(unit);
   9266 
   9267     /* Check for PortMod */
   9268     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
   9269         return bcmi_esw_portctrl_enable_get(unit, port, enable);
   9270     }
   9271 
   9272     if(bcm_common_oamp_port_enable_get(unit, port)) {
   9273         LOG_ERROR(BSL_LS_BCM_PORT,
   9274                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   9275                    port));
   9276         return BCM_E_PARAM;
   9277     }
   9278 
   9279 #if defined(BCM_KATANA2_SUPPORT)
   9280 #if defined(BCM_SABER2_SUPPORT)
   9281     if(SOC_IS_SABER2(unit)) {
   9282         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
   9283     }
   9284 #endif
   9285     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
   9286         (!((port >= 1) && (port <= max_phy_port)))) {
   9287          return BCM_E_PORT;
   9288     }
   9289 #endif
   9290 
   9291 
   9292 #ifdef BCM_KATANA2_SUPPORT
   9293     if(BCM_GPORT_IS_SUBPORT_PORT(port)) {
   9294         if (soc_feature(unit, soc_feature_subtag_coe) &&
   9295            _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   9296            is_subtag_port = TRUE;
   9297        } else if (soc_feature(unit, soc_feature_linkphy_coe) &&
   9298            _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) {
   9299            is_linkphy_port = TRUE;
   9300        }
   9301 
   9302        if (is_subtag_port || is_linkphy_port) {
   9303             return _bcmi_esw_port_subport_enable_get(unit, port,
   9304                                                      is_subtag_port, enable);
   9305        }
   9306     }
   9307 #endif
   9308 
   9309     BCM_IF_ERROR_RETURN(
   9310         _bcm_esw_port_gport_validate(unit, port, &port));
   9311 
   9312     if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   9313         *enable = 0;
   9314         return BCM_E_NONE;
   9315     }
   9316 
   9317     PORT_LOCK(unit);
   9318     rv = soc_phyctrl_enable_get(unit, port, enable);
   9319 #ifdef BCM_TRIDENT2_SUPPORT
   9320     if (SOC_IS_TD2_TT2(unit)) {
   9321         *enable = (PORT(unit, port).enable) & (*enable);
   9322     }
   9323 #endif /* BCM_TRIDENT2_SUPPORT */
   9324 
   9325     PORT_UNLOCK(unit);
   9326 
   9327     LOG_INFO(BSL_LS_BCM_PORT,
   9328              (BSL_META_U(unit,
   9329                          "bcm_port_enable_get: u=%d p=%d rv=%d enable=%d\n"),
   9330               unit, port, rv, *enable));
   9331 
   9332     return rv;
   9333 }
   9334 
   9335 /*
   9336  * Function:
   9337  *      _bcm_port_mode_setup
   9338  * Purpose:
   9339  *      Set initial operating mode for a port.
   9340  * Parameters:
   9341  *      unit - StrataSwitch unit #.
   9342  *      port - StrataSwitch port #.
   9343  *      enable - Whether to enable or disable
   9344  * Returns:
   9345  *      BCM_E_XXX
   9346  * Notes:
   9347  *      Must be called with PORT_LOCK held.
   9348  */
   9349 
   9350 int
   9351 _bcm_port_mode_setup(int unit, bcm_port_t port, int enable)
   9352 {
   9353     soc_port_if_t       pif;
   9354     bcm_port_ability_t  local_pa, advert_pa;
   9355 
   9356     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
   9357         return (bcmi_esw_portctrl_mode_setup(unit, port, enable));
   9358     }
   9359 
   9360     sal_memset(&local_pa,  0, sizeof(bcm_port_ability_t));
   9361     sal_memset(&advert_pa, 0, sizeof(bcm_port_ability_t));
   9362 
   9363     LOG_INFO(BSL_LS_BCM_PORT,
   9364              (BSL_META_U(unit,
   9365                          "_bcm_port_mode_setup: u=%d p=%d\n"), unit, port));
   9366 
   9367     SOC_IF_ERROR_RETURN(bcm_esw_port_ability_local_get(unit, port, &local_pa));
   9368 
   9369     if (IS_TDM_PORT(unit, port)) {
   9370         return BCM_E_NONE;
   9371     }
   9372 
   9373     /* If MII supported, enable it, otherwise use TBI */
   9374     if (local_pa.interface & (SOC_PA_INTF_MII | SOC_PA_INTF_GMII |
   9375                               SOC_PA_INTF_SGMII | SOC_PA_INTF_XGMII)) {
   9376         if (IS_GE_PORT(unit, port)) {
   9377             pif = SOC_PORT_IF_GMII;
   9378         } else if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) {
   9379             if (local_pa.interface & SOC_PA_INTF_XGMII) {
   9380                 pif = SOC_PORT_IF_XGMII;
   9381             } else { /*  external GbE phy in xe port mode */
   9382                 pif = SOC_PORT_IF_SGMII;
   9383             }
   9384         } else {
   9385             pif = SOC_PORT_IF_MII;
   9386         }
   9387     } else if (local_pa.interface & SOC_PA_INTF_CGMII) {
   9388         pif = SOC_PORT_IF_CGMII;
   9389     } else {
   9390         pif = SOC_PORT_IF_TBI;
   9391     }
   9392 
   9393     SOC_IF_ERROR_RETURN
   9394         (soc_phyctrl_interface_set(unit, port, pif));
   9395     SOC_IF_ERROR_RETURN
   9396         (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif));
   9397 
   9398     if (IS_ST_PORT(unit, port)) {
   9399 
   9400         /* Since stacking port doesn't support flow control,
   9401          * make sure that PHY is not advertising flow control capabilities.
   9402          */
   9403         SOC_IF_ERROR_RETURN(
   9404             soc_phyctrl_ability_advert_get(unit, port, &advert_pa));
   9405         advert_pa.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM);
   9406         SOC_IF_ERROR_RETURN(
   9407             soc_phyctrl_ability_advert_set(unit, port, &advert_pa));
   9408     }
   9409 
   9410     if (!SOC_WARM_BOOT(unit) &&
   9411         !(SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) ) {
   9412 #ifdef BCM_RCPU_SUPPORT
   9413         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
   9414             /* Do not enable/disable rcpu port. */
   9415             return BCM_E_NONE;
   9416         }
   9417 #endif /* BCM_RCPU_SUPPORT */
   9418         SOC_IF_ERROR_RETURN
   9419             (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable));
   9420     }
   9421 
   9422     return BCM_E_NONE;
   9423 }
   9424 
   9425 STATIC int
   9426 _bcm_esw_port_e2ecc_hdr_set(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr)
   9427 {
   9428     uint64 rval64;
   9429 
   9430     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
   9431         return bcmi_esw_portctrl_e2ecc_hdr_set(unit, port, e2ecc_hdr);
   9432     }
   9433 
   9434     if (!e2ecc_hdr) {
   9435         return BCM_E_PARAM;
   9436     }
   9437 
   9438     if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
   9439         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
   9440         if (IS_CL_PORT(unit, port)) {
   9441             COMPILER_64_ZERO(rval64);
   9442             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9443                                   E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]);
   9444             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9445                                   E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]);
   9446             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_0r,
   9447                                             port, 0, rval64));
   9448 
   9449             COMPILER_64_ZERO(rval64);
   9450             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9451                                   E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]);
   9452             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9453                                   E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]);
   9454             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_1r,
   9455                                             port, 0, rval64));
   9456 
   9457             COMPILER_64_ZERO(rval64);
   9458             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9459                                   E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]);
   9460             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9461                                   E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]);
   9462             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_0r,
   9463                                             port, 0, rval64));
   9464 
   9465             COMPILER_64_ZERO(rval64);
   9466             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9467                                   E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]);
   9468             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9469                                   E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]);
   9470             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_1r,
   9471                                             port, 0, rval64));
   9472         } else {
   9473             COMPILER_64_ZERO(rval64);
   9474             soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9475                                   E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]);
   9476             soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9477                                   E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]);
   9478             BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_0r,
   9479                                             port, 0, rval64));
   9480 
   9481             COMPILER_64_ZERO(rval64);
   9482             soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9483                                   E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]);
   9484             soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9485                                   E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]);
   9486             BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_1r,
   9487                                             port, 0, rval64));
   9488 
   9489             COMPILER_64_ZERO(rval64);
   9490             soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9491                                   E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]);
   9492             soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9493                                   E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]);
   9494             BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_0r,
   9495                                             port, 0, rval64));
   9496 
   9497             COMPILER_64_ZERO(rval64);
   9498             soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9499                                   E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]);
   9500             soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9501                                   E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]);
   9502             BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_1r,
   9503                                             port, 0, rval64));
   9504         }
   9505     } else {
   9506         SOC_IF_ERROR_RETURN
   9507             (WRITE_XHOL_MH0r(unit, port, e2ecc_hdr->overlay1.words[0]));
   9508         SOC_IF_ERROR_RETURN
   9509             (WRITE_XHOL_MH1r(unit, port, e2ecc_hdr->overlay1.words[1]));
   9510         SOC_IF_ERROR_RETURN
   9511             (WRITE_XHOL_MH2r(unit, port, e2ecc_hdr->overlay1.words[2]));
   9512         SOC_IF_ERROR_RETURN
   9513             (WRITE_XHOL_MH3r(unit, port, e2ecc_hdr->overlay1.words[3]));
   9514 
   9515         SOC_IF_ERROR_RETURN
   9516             (WRITE_XHOL_D0r(unit, port, e2ecc_hdr->overlay1.words[4]));
   9517         SOC_IF_ERROR_RETURN
   9518             (WRITE_XHOL_D1r(unit, port, e2ecc_hdr->overlay1.words[5]));
   9519         SOC_IF_ERROR_RETURN
   9520             (WRITE_XHOL_D2r(unit, port, e2ecc_hdr->overlay1.words[6]));
   9521         SOC_IF_ERROR_RETURN
   9522             (WRITE_XHOL_D3r(unit, port, e2ecc_hdr->overlay1.words[7]));
   9523     }
   9524 
   9525     return BCM_E_NONE;
   9526 }
   9527 
   9528 #ifdef BCM_WARM_BOOT_SUPPORT
   9529 #if defined(BCM_TRX_SUPPORT)
   9530 STATIC int
   9531 _bcm_esw_port_e2ecc_hdr_get(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr)
   9532 {
   9533     uint64 rval64;
   9534 
   9535     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
   9536         return bcmi_esw_portctrl_e2ecc_hdr_get(unit, port, e2ecc_hdr);
   9537     }
   9538 
   9539     if (!e2ecc_hdr) {
   9540         return BCM_E_PARAM;
   9541     }
   9542 
   9543     sal_memset(e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
   9544 
   9545     if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
   9546         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
   9547         if (IS_CL_PORT(unit, port)) {
   9548             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_0r,
   9549                                             port, 0, &rval64));
   9550             e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit,
   9551                 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf);
   9552             e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit,
   9553                 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf);
   9554 
   9555             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_1r,
   9556                                             port, 0, &rval64));
   9557             e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit,
   9558                 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf);
   9559             e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit,
   9560                 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf);
   9561 
   9562             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_0r,
   9563                                             port, 0, &rval64));
   9564             e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit,
   9565                 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf);
   9566             e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit,
   9567                 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf);
   9568 
   9569             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_1r,
   9570                                             port, 0, &rval64));
   9571             e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit,
   9572                 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf);
   9573             e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit,
   9574                 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf);
   9575         } else {
   9576             BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_0r,
   9577                                             port, 0, &rval64));
   9578             e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit,
   9579                 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf);
   9580             e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit,
   9581                 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf);
   9582 
   9583             BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_1r,
   9584                                             port, 0, &rval64));
   9585             e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit,
   9586                 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf);
   9587             e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit,
   9588                 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf);
   9589 
   9590             BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_0r,
   9591                                             port, 0, &rval64));
   9592             e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit,
   9593                 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf);
   9594             e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit,
   9595                 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf);
   9596 
   9597             BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_1r,
   9598                                             port, 0, &rval64));
   9599             e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit,
   9600                 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf);
   9601             e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit,
   9602                 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf);
   9603         }
   9604     } else {
   9605         SOC_IF_ERROR_RETURN
   9606             (READ_XHOL_MH0r(unit, port, &e2ecc_hdr->overlay1.words[0]));
   9607         SOC_IF_ERROR_RETURN
   9608             (READ_XHOL_MH1r(unit, port, &e2ecc_hdr->overlay1.words[1]));
   9609         SOC_IF_ERROR_RETURN
   9610             (READ_XHOL_MH2r(unit, port, &e2ecc_hdr->overlay1.words[2]));
   9611         SOC_IF_ERROR_RETURN
   9612             (READ_XHOL_MH3r(unit, port, &e2ecc_hdr->overlay1.words[3]));
   9613 
   9614         SOC_IF_ERROR_RETURN
   9615             (READ_XHOL_D0r(unit, port, &e2ecc_hdr->overlay1.words[4]));
   9616         SOC_IF_ERROR_RETURN
   9617             (READ_XHOL_D1r(unit, port, &e2ecc_hdr->overlay1.words[5]));
   9618         SOC_IF_ERROR_RETURN
   9619             (READ_XHOL_D2r(unit, port, &e2ecc_hdr->overlay1.words[6]));
   9620         SOC_IF_ERROR_RETURN
   9621             (READ_XHOL_D3r(unit, port, &e2ecc_hdr->overlay1.words[7]));
   9622     }
   9623 
   9624     return BCM_E_NONE;
   9625 }
   9626 #endif
   9627 #endif /* BCM_WARM_BOOT_SUPPORT */
   9628 
   9629 #ifdef BCM_WARM_BOOT_SUPPORT
   9630 
   9631 STATIC int
   9632 _bcm_port_vd_pbvl_reinit(int unit)
   9633 {
   9634 
   9635 #if defined(BCM_TRX_SUPPORT)
   9636     if (SOC_IS_TRX(unit)) {
   9637         /*
   9638          * Reinit of vd_pbvl takes place at the end of function
   9639          * _bcm_trx_vlan_action_profile_init().  This routine initializes
   9640          * the VLAN profile tables first, which need to happen before
   9641          * the vd_pbvl data is recovered.
   9642          */
   9643         return BCM_E_NONE;
   9644     }
   9645 #endif /* BCM_TRX_SUPPORT */
   9646 
   9647 #ifdef BCM_FIREBOLT_SUPPORT
   9648     if (SOC_IS_FBX(unit)) {
   9649         bcm_port_t port;
   9650         _bcm_port_info_t *pinfo;
   9651         int        idxmin, idx, i, index;
   9652         int start, end;
   9653         vlan_protocol_data_entry_t   vde;
   9654         vlan_protocol_entry_t vpe;
   9655         bcm_vlan_t            cvid, defvid;
   9656         uint32                ft;
   9657         bcm_pbmp_t            all_pbmp;
   9658 
   9659         BCM_PBMP_CLEAR(all_pbmp);
   9660         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
   9661 
   9662 #ifdef BCM_KATANA2_SUPPORT
   9663         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   9664             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
   9665         }
   9666         if (soc_feature(unit, soc_feature_linkphy_coe) ||
   9667             soc_feature(unit, soc_feature_subtag_coe)) {
   9668             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
   9669         }
   9670 #endif
   9671 
   9672         idxmin = soc_mem_index_min(unit, VLAN_PROTOCOL_DATAm);
   9673         idx = soc_mem_index_min(unit, VLAN_PROTOCOLm);
   9674         PBMP_ITER(all_pbmp, port) {
   9675 
   9676             start = idxmin + port*16;
   9677             end   = start + 16;
   9678             BCM_IF_ERROR_RETURN
   9679                 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid));
   9680             for (i = start; i < end; i++) {
   9681 
   9682                 SOC_IF_ERROR_RETURN
   9683                     (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
   9684                                               i, &vde));
   9685                 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
   9686                                                            VLAN_IDf);
   9687                 if ((cvid == 0) || (cvid == defvid)) {
   9688                     
   9689                     continue;
   9690                 }
   9691 
   9692                 /*
   9693                  * Check against the VLAN_PROTOCOL table to see if a
   9694                  * valid entry exists for matching the packet protocol
   9695                  */
   9696                 index = i - start;
   9697                 SOC_IF_ERROR_RETURN
   9698                     (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY,
   9699                                          idx+index, &vpe));
   9700                 ft = 0;
   9701                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) {
   9702                     ft |= BCM_PORT_FRAMETYPE_ETHER2;
   9703                 }
   9704                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) {
   9705                     ft |= BCM_PORT_FRAMETYPE_8023;
   9706                 }
   9707                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) {
   9708                     ft |= BCM_PORT_FRAMETYPE_LLC;
   9709                 }
   9710                 if (ft == 0) {
   9711                     /*
   9712                      * Something wrong here.. bail out
   9713                      */
   9714                     continue;
   9715                 }
   9716                 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   9717                 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx+index)) {
   9718                     /* Set as explicit VID */
   9719                     _BCM_PORT_VD_PBVL_SET(pinfo, idx+index);
   9720                 }
   9721             }
   9722         }
   9723         return BCM_E_NONE;
   9724     }
   9725 #endif /* BCM_FIREBOLT_SUPPORT */
   9726 
   9727     return BCM_E_NONE;
   9728 }
   9729 
   9730 #if defined(BCM_TRX_SUPPORT)
   9731 /* Recover the port dtag_mode from Warm Boot cached info, if available. */
   9732 STATIC int
   9733 _bcm_trx_port_dtag_mode_reinit(int unit, bcm_pbmp_t dtm_pbmp, int use_pbmp)
   9734 {
   9735     uint32   tpid_enable;
   9736     bcm_port_t port;
   9737     _bcm_port_info_t *pinfo;
   9738     bcm_vlan_action_set_t action;
   9739     bcm_pbmp_t all_pbmp;
   9740 
   9741     BCM_PBMP_CLEAR(all_pbmp);
   9742     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
   9743     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   9744 
   9745 #ifdef BCM_KATANA2_SUPPORT
   9746     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   9747         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
   9748     }
   9749     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   9750         soc_feature(unit, soc_feature_subtag_coe)) {
   9751         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
   9752     }
   9753 #endif
   9754 
   9755 #if defined(BCM_SABER2_SUPPORT)
   9756     if(SOC_IS_SABER2(unit)){
   9757         int oamp_enable;
   9758         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
   9759         /* Skip OAMP port for saber2 device */
   9760         if(oamp_enable) {
   9761             SOC_PBMP_PORT_REMOVE(all_pbmp,
   9762                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
   9763         }
   9764     }
   9765 #endif
   9766 
   9767     PBMP_ITER(all_pbmp, port) {
   9768         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   9769         BCM_IF_ERROR_RETURN
   9770             (_bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, (int *)&tpid_enable));
   9771 
   9772         if (0 == tpid_enable) {
   9773             if (use_pbmp && !BCM_PBMP_MEMBER(dtm_pbmp, port)) {
   9774                 /* Bitmap claims this is DT mode NONE, but it is
   9775                  * configured for EXTERNAL */
   9776                 BCM_IF_ERROR_RETURN
   9777                     (soc_event_generate(unit,
   9778                                         BCM_SWITCH_EVENT_STABLE_ERROR,
   9779                                         SOC_STABLE_STALE,
   9780                                         SOC_STABLE_BASIC, 0));
   9781                 use_pbmp = FALSE; /* Cached info is not trustworthy */
   9782             } else {
   9783                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_EXTERNAL;
   9784             }
   9785         } else {
   9786             if (use_pbmp && BCM_PBMP_MEMBER(dtm_pbmp, port)) {
   9787                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_INTERNAL;
   9788             } else {
   9789                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE;
   9790             }
   9791         }
   9792 
   9793         if (!SOC_IS_SHADOW(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   9794             if (soc_feature(unit, soc_feature_vlan_action)) {
   9795                 BCM_IF_ERROR_RETURN
   9796                     (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
   9797 
   9798 
   9799                 if (bcmVlanActionAdd == action.ut_inner) {
   9800                     pinfo->dtag_mode |= BCM_PORT_DTAG_ADD_EXTERNAL_TAG;
   9801                 }
   9802 
   9803 
   9804                 BCM_IF_ERROR_RETURN
   9805                     (_bcm_trx_vlan_port_egress_default_action_get(unit, port,
   9806                                                                   &action));
   9807                 if ((bcmVlanActionDelete == action.dt_inner) &&
   9808                     (bcmVlanActionDelete == action.dt_inner_prio)) {
   9809                     pinfo->dtag_mode |= BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG;
   9810                 }
   9811             }
   9812         }
   9813     }
   9814     return BCM_E_NONE;
   9815 }
   9816 
   9817 /**
   9818  * Function:
   9819  *      _bcm_esw_hcfc_ingress_enable_check();
   9820  * Purpose:
   9821  *      check HCFC ingress enable status of unit. If any port ingress enable, enable =1;
   9822  *
   9823  * Parameters:
   9824  *      unit     - (IN)device number
   9825  *      enable - (OUT) hcfc ingress enable
   9826  *
   9827  * Returns:
   9828  *      BCM_E_xxx
   9829  * Notes:
   9830  */
   9831 STATIC int
   9832 _bcm_esw_hcfc_ingress_enable_check(int unit, int *enable)
   9833 {
   9834     soc_reg_t reg0, reg1;
   9835     uint64 rval64, fval64;
   9836 
   9837     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
   9838         reg0 = OOBFC_ING_PORT_EN0_64r;
   9839         reg1 = OOBFC_ING_PORT_EN1_64r;
   9840     } else {
   9841         reg0 = OOBFC_ING_PORT_EN_0_64r;
   9842         reg1 = OOBFC_ING_PORT_EN_1_64r;
   9843     }
   9844 
   9845     if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) {
   9846         *enable = 0;
   9847         return BCM_E_NONE;
   9848     }
   9849 
   9850     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64));
   9851     fval64 = soc_reg64_field_get(unit, reg0, rval64, ING_PORT_ENf);
   9852     if(0 != fval64) {
   9853         *enable = 1;
   9854         return BCM_E_NONE;
   9855     }
   9856     else {
   9857         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64));
   9858         fval64 = soc_reg64_field_get(unit, reg1, rval64, ING_PORT_ENf);
   9859         if(0 != fval64) {
   9860             *enable = 1;
   9861             return BCM_E_NONE;
   9862         }
   9863     }
   9864 
   9865     return BCM_E_NONE;
   9866 }
   9867 
   9868 /**
   9869  * Function:
   9870  *      _bcm_esw_hcfc_egress_enable_check();
   9871  * Purpose:
   9872  *      check HCFC ingress enable status of unit. If any port egress enable, enable =1;
   9873  *
   9874  * Parameters:
   9875  *      unit     - (IN)device number
   9876  *      enable - (OUT) hcfc egress enable
   9877  *
   9878  * Returns:
   9879  *      BCM_E_xxx
   9880  * Notes:
   9881  */
   9882 STATIC int
   9883 _bcm_esw_hcfc_egress_enable_check(int unit, int *enable)
   9884 {
   9885     soc_reg_t reg0, reg1;
   9886     uint64 rval64, fval64;
   9887 
   9888     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
   9889         reg0 = OOBFC_ENG_PORT_EN0_64r;
   9890         reg1 = OOBFC_ENG_PORT_EN1_64r;
   9891     } else {
   9892         reg0 = OOBFC_ENG_PORT_EN_0_64r;
   9893         reg1 = OOBFC_ENG_PORT_EN_1_64r;
   9894     }
   9895 
   9896     if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) {
   9897        *enable = 0;
   9898        return BCM_E_NONE;
   9899     }
   9900 
   9901     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64));
   9902     fval64 = soc_reg64_field_get(unit, reg0, rval64, ENG_PORT_ENf);
   9903     if(0 != fval64) {
   9904         *enable = 1;
   9905         return BCM_E_NONE;
   9906     }
   9907     else {
   9908         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64));
   9909         fval64 = soc_reg64_field_get(unit, reg1, rval64, ENG_PORT_ENf);
   9910         if(0 != fval64) {
   9911             *enable = 1;
   9912             return BCM_E_NONE;
   9913         }
   9914     }
   9915 
   9916     return BCM_E_NONE;
   9917 }
   9918 
   9919 /**
   9920  * Function:
   9921  *      _bcm_esw_port_hcfc_ingress_enable_check();
   9922  * Purpose:
   9923  *     check HCFC ingress enable status of given port.
   9924  *
   9925  * Parameters:
   9926  *      unit     - (IN)device number
   9927  *      port     - (IN)port number
   9928  *      enable - (OUT)hcfc ingress enable
   9929  *
   9930  * Returns:
   9931  *      BCM_E_xxx
   9932  * Notes:
   9933  */
   9934 STATIC int
   9935 _bcm_esw_port_hcfc_ingress_enable_check(int unit, bcm_port_t port, int *enable)
   9936 {
   9937     soc_reg_t reg, reg0, reg1;
   9938     int len;
   9939     uint64 rval64, fval64;
   9940     uint32 fval_hi, fval_lo;
   9941 
   9942     if (!SOC_PORT_VALID(unit, port)) {
   9943         return BCM_E_PORT;
   9944     }
   9945 
   9946     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
   9947         reg0 = OOBFC_ING_PORT_EN0_64r;
   9948         reg1 = OOBFC_ING_PORT_EN1_64r;
   9949     } else {
   9950         reg0 = OOBFC_ING_PORT_EN_0_64r;
   9951         reg1 = OOBFC_ING_PORT_EN_1_64r;
   9952     }
   9953     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
   9954         *enable = 0;
   9955         return BCM_E_NONE;
   9956     }
   9957 
   9958     /* Configure ingress status reporting */
   9959     len = soc_reg_field_length(unit, reg0, ING_PORT_ENf);
   9960     if (len < 1) {
   9961         return BCM_E_PORT;
   9962     }
   9963     if (port < len) { /* First half of logical ports (not mmu port) */
   9964         reg = reg0;
   9965     } else {          /* Second half of logical ports (not mmu port) */
   9966         reg = reg1;
   9967     }
   9968     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   9969     fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf);
   9970     fval_hi = COMPILER_64_HI(fval64);
   9971     fval_lo = COMPILER_64_LO(fval64);
   9972 
   9973     if (port < len) {
   9974         if ( port < 32 ) {
   9975             *enable = fval_lo & (1 << port);
   9976         } else {
   9977             /* coverity[large_shift : FALSE] */
   9978             *enable = fval_hi & (1 << (port - 32));
   9979         }
   9980     } else {
   9981         int port_offset = port - len;
   9982         if ( port_offset < 32 ) {
   9983             *enable = fval_lo & (1 << port_offset);
   9984         } else {
   9985             *enable = fval_hi & (1 << (port_offset - 32));
   9986         }
   9987     }
   9988 
   9989     return BCM_E_NONE;
   9990 }
   9991 
   9992 /**
   9993  * Function:
   9994  *      _bcm_esw_port_hcfc_egress_enable_check();
   9995  * Purpose:
   9996  *      check HCFC egress enable status of given port.
   9997  *
   9998  * Parameters:
   9999  *      unit     - (IN)device number
  10000  *      port     - (IN)port number
  10001  *      enable - (OUT)hcfc egress enable
  10002  *
  10003  * Returns:
  10004  *      BCM_E_xxx
  10005  * Notes:
  10006  */
  10007 STATIC int
  10008 _bcm_esw_port_hcfc_egress_enable_check(int unit, bcm_port_t port, int *enable)
  10009 {
  10010     soc_reg_t reg, reg0, reg1;
  10011     int len;
  10012     uint64 rval64, fval64;
  10013     uint32 fval_hi, fval_lo;
  10014 
  10015     if (!SOC_PORT_VALID(unit, port)) {
  10016         return BCM_E_PORT;
  10017     }
  10018 
  10019     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
  10020         reg0 = OOBFC_ENG_PORT_EN0_64r;
  10021         reg1 = OOBFC_ENG_PORT_EN1_64r;
  10022     } else {
  10023         reg0 = OOBFC_ENG_PORT_EN_0_64r;
  10024         reg1 = OOBFC_ENG_PORT_EN_1_64r;
  10025     }
  10026     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
  10027         *enable = 0;
  10028         return BCM_E_NONE;
  10029     }
  10030 
  10031     /* Configure egress status reporting */
  10032     len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf);
  10033     if (len < 1) {
  10034         return BCM_E_PORT;
  10035     }
  10036     if (port < len) { /* First half of logical ports (not mmu port) */
  10037         reg = reg0;
  10038     } else {          /* Second half of logical ports (not mmu port) */
  10039         reg = reg1;
  10040     }
  10041     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  10042     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
  10043     fval_hi = COMPILER_64_HI(fval64);
  10044     fval_lo = COMPILER_64_LO(fval64);
  10045     if (port < len) {
  10046         if ( port < 32 ) {
  10047             *enable = fval_lo & (1 << port);
  10048         } else {
  10049             /* coverity[large_shift : FALSE] */
  10050             *enable = fval_hi & (1 << (port - 32));
  10051         }
  10052     } else {
  10053         int port_offset = port - len;
  10054         if ( port_offset < 32 ) {
  10055             *enable = fval_lo & (1 << port_offset);
  10056         } else {
  10057             *enable = fval_hi & (1 << (port_offset - 32));
  10058         }
  10059     }
  10060 
  10061     return BCM_E_NONE;
  10062 }
  10063 
  10064 
  10065 STATIC int
  10066 _bcm_esw_port_e2ecc_reinit(int unit)
  10067 {
  10068     bcm_port_t port, phy_port;
  10069     bcm_port_congestion_config_t *config;
  10070     int    time_unit_sel = 0, time_units = 0;
  10071     soc_higig_e2ecc_hdr_t e2ecc_hdr;
  10072     int    src_modid, src_pid;
  10073     uint64 regval64;
  10074     uint32 regval, field_val = 0;
  10075     int tx_enabled = FALSE, rx_enabled = FALSE;
  10076     int port_tx_enabled, port_rx_enabled, voqfc = 0;
  10077     int hcfc_tx = 0, hcfc_rx = 0;
  10078     int port_hcfc_tx = 0, port_hcfc_rx = 0;
  10079     int blk, blk_num = -1, bindex = 0;
  10080 #ifdef  BCM_KATANA2_SUPPORT
  10081     uint16      dev_id;
  10082     uint8       rev_id;
  10083     int e2ecc_coe = 0;
  10084     int e2ecc_strict = 0;
  10085 #endif
  10086 #ifdef  BCM_TRIDENT2PLUS_SUPPORT
  10087     int fc_format;
  10088     int copy_to_cpu = 0 ;
  10089 #endif
  10090     if (SOC_IS_SC_CQ(unit)) {
  10091         SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, &regval));
  10092         if (0 != soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf)) {
  10093             tx_enabled = TRUE;
  10094         }
  10095     } else {
  10096         SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, &regval));
  10097         if (0 != soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf)) {
  10098             tx_enabled = TRUE;
  10099         }
  10100     }
  10101 
  10102     BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_egress_enable_check(unit, &hcfc_tx));
  10103     if (hcfc_tx) {
  10104         tx_enabled = TRUE;
  10105     }
  10106 
  10107     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &regval64));
  10108     if (0 == soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
  10109                               DISABLE_E2E_HOL_CHECKf)) {
  10110         rx_enabled = TRUE;
  10111     }
  10112 
  10113     BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_ingress_enable_check(unit, &hcfc_rx));
  10114     if (hcfc_rx) {
  10115         rx_enabled = TRUE;
  10116     }
  10117 
  10118     if (!tx_enabled && !rx_enabled) {
  10119         /* Nothing further to do */
  10120         return BCM_E_NONE;
  10121     }
  10122 
  10123     PBMP_HG_ITER(unit, port) {
  10124         port_tx_enabled = port_rx_enabled = FALSE;
  10125 
  10126         if (tx_enabled) {
  10127             if (hcfc_tx) {
  10128                 port_hcfc_tx = 0;
  10129                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_egress_enable_check(unit, port, &port_hcfc_tx));
  10130                 if (port_hcfc_tx) {
  10131                     port_tx_enabled = 1;
  10132                 }
  10133             }
  10134             else {
  10135                 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
  10136                     SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
  10137                     port_tx_enabled =
  10138                         (0 != soc_reg_field_get(unit, XPORT_CONFIGr, regval,
  10139                                                 E2E_HOL_ENf));
  10140                 } else {
  10141                     if (soc_feature(unit, soc_feature_logical_port_num)) {
  10142                         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  10143                     } else {
  10144                         phy_port = port;
  10145                     }
  10146                     blk = SOC_PORT_BLOCK(unit, phy_port);
  10147 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  10148                    if (SOC_IS_TRIDENT2X(unit)) {
  10149                        blk_num = SOC_INFO(unit).port_serdes[port];
  10150                    } else
  10151 #endif
  10152                    {
  10153                     blk_num = SOC_BLOCK_INFO(unit, blk).number;
  10154                    }
  10155                     bindex = SOC_PORT_BINDEX(unit, phy_port);
  10156                     /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  10157                     if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  10158                         if (SOC_IS_TRIUMPH3(unit)) {
  10159                             if (IS_CL_PORT(unit, port)) {
  10160                                 blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  10161                                 bindex = bindex%4;
  10162                             } else {
  10163                                 blk_num = 3;
  10164                             }
  10165                         }
  10166                         if (SOC_IS_KATANA2(unit)) {
  10167                         /* In KT2 E2ECC is implemented only in blocks 6..9 */
  10168                             if (blk_num >= 6) {
  10169                                 blk_num -= 6;
  10170                             }
  10171                         }
  10172                         SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  10173                                                                       &regval));
  10174                         if ((regval & (1 << bindex))) {
  10175                             port_tx_enabled= TRUE;
  10176                         }
  10177                     }
  10178                 }
  10179             }
  10180         }
  10181 
  10182         if (rx_enabled) {
  10183             if (hcfc_rx) {
  10184                 port_hcfc_rx = 0;
  10185                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_ingress_enable_check(unit, port, &port_hcfc_rx));
  10186                 if (port_hcfc_rx) {
  10187                     port_rx_enabled = 1;
  10188                 }
  10189             }
  10190             else {
  10191                 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  10192                 port_rx_enabled = 0;
  10193                 voqfc = 0;
  10194                 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf)) {
  10195                     port_rx_enabled = 1;
  10196                 }
  10197 
  10198                 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) {
  10199                     if (0 != soc_reg_field_get(unit, IE2E_CONTROLr,
  10200                                                regval, VOQFC_ENABLEf)) {
  10201                         port_rx_enabled = 1;
  10202                         voqfc = 1;
  10203                     }
  10204                 }
  10205             }
  10206         }
  10207 
  10208         /* For HX4 and TR3, tx restore from OP_QUEUE_CONFIG1_CELLr */
  10209         if (SOC_IS_TRIUMPH3(unit)) {
  10210             BCM_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIG1_CELLr(unit, port, 0, &regval));
  10211             port_tx_enabled = soc_reg_field_get(unit,OP_QUEUE_CONFIG1_CELLr, regval, Q_E2E_DS_EN_CELLf);
  10212         }
  10213 
  10214         if (!port_tx_enabled && !port_rx_enabled) {
  10215             /* On to the next port */
  10216             continue;
  10217         }
  10218 
  10219         /* Allocate space for the E2ECC configuration */
  10220         if (PORT(unit, port).e2ecc_config == NULL) {
  10221             PORT(unit, port).e2ecc_config =
  10222                 sal_alloc(sizeof(bcm_port_congestion_config_t),
  10223                           "bcm_port_congestion_config");
  10224             if (PORT(unit, port).e2ecc_config == NULL) {
  10225                 LOG_ERROR(BSL_LS_BCM_PORT,
  10226                           (BSL_META_U(unit,
  10227                                       "Error: unable to allocate memory for"
  10228                                       " bcm_port_congestion_config.\n")));
  10229                 return BCM_E_MEMORY;
  10230             }
  10231         } else {
  10232             /* This is initialized to NULL pointers by
  10233              * port init.  How did it get changed? */
  10234             return BCM_E_INTERNAL;
  10235         }
  10236 
  10237         config = PORT(unit, port).e2ecc_config;
  10238         bcm_port_congestion_config_t_init(config);
  10239 
  10240         if (port_tx_enabled) {
  10241             if (port_hcfc_tx) {
  10242                 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC|
  10243                    BCM_PORT_CONGESTION_CONFIG_TX;
  10244             } else {
  10245                 /* Recover TX state */
  10246                 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC |
  10247                     BCM_PORT_CONGESTION_CONFIG_TX;
  10248 
  10249                 /* Message timer paramters to packets/sec */
  10250                 if (SOC_IS_SC_CQ(unit)) {
  10251                     SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, &regval));
  10252                     time_unit_sel = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr,
  10253                                                       regval, LGf);
  10254                     time_units = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr,
  10255                                                    regval, TIMERf);
  10256                 } else {
  10257                     SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, &regval));
  10258                     time_unit_sel = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr,
  10259                                                       regval, LGf);
  10260                     time_units = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr,
  10261                                                    regval, TIMERf);
  10262                     SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval));
  10263                 }
  10264 
  10265                 /* See _bcm_esw_port_e2ecc_tx for an explanation of
  10266                  * the timer calculation. */
  10267                 config->packets_per_sec = time_unit_sel ?
  10268                     (40000 / time_units) : (4000000 / time_units);
  10269 
  10270                 /* Recover the E2ECC module header
  10271                  * (see _bcm_esw_port_e2ecc_tx for the header format) */
  10272                 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_get(unit, port, &e2ecc_hdr));
  10273 
  10274                 config->traffic_class =
  10275                     (e2ecc_hdr.overlay1.words[0] >> 16) & 0x0F;
  10276                 config->multicast_id  = e2ecc_hdr.overlay1.words[0] & 0xFFFF;
  10277 
  10278                 src_modid = (e2ecc_hdr.overlay1.words[1] >> 24) & 0xFF;
  10279                 src_pid = (e2ecc_hdr.overlay1.words[1] >> 16) & 0xFF;
  10280                 BCM_GPORT_MODPORT_SET(config->src_port, src_modid, src_pid);
  10281 
  10282                 config->color = (e2ecc_hdr.overlay1.words[1] >> 6) & 0x3;
  10283 
  10284                 config->pri = (e2ecc_hdr.overlay1.words[3] >> 29) & 0x7;
  10285                 config->cfi = (e2ecc_hdr.overlay1.words[3] >> 28) & 0x1;
  10286                 config->vlan = (e2ecc_hdr.overlay1.words[3] >> 16) & 0xfff;
  10287 
  10288                 config->dest_mac[0] =
  10289                     ((e2ecc_hdr.overlay1.words[4] >> 24) & 0xff);
  10290                 config->dest_mac[1] =
  10291                     ((e2ecc_hdr.overlay1.words[4] >> 16) & 0xff);
  10292                 config->dest_mac[2] =
  10293                     ((e2ecc_hdr.overlay1.words[4] >> 8) & 0xff);
  10294                 config->dest_mac[3] =
  10295                     (e2ecc_hdr.overlay1.words[4] & 0xff);
  10296                 config->dest_mac[4] =
  10297                     ((e2ecc_hdr.overlay1.words[5] >> 24) & 0xff);
  10298                 config->dest_mac[5] =
  10299                     ((e2ecc_hdr.overlay1.words[5] >> 16) & 0xff);
  10300 
  10301                 config->src_mac[0] =
  10302                     ((e2ecc_hdr.overlay1.words[5] >> 8) & 0xff);
  10303                 config->src_mac[1] =
  10304                     (e2ecc_hdr.overlay1.words[5] & 0xff);
  10305                 config->src_mac[2] =
  10306                     ((e2ecc_hdr.overlay1.words[6] >> 24) & 0xff);
  10307                 config->src_mac[3] =
  10308                     ((e2ecc_hdr.overlay1.words[6] >> 16) & 0xff);
  10309                 config->src_mac[4] =
  10310                     ((e2ecc_hdr.overlay1.words[6] >> 8) & 0xff);
  10311                 config->src_mac[5] =
  10312                     (e2ecc_hdr.overlay1.words[6] & 0xff);
  10313 
  10314                 config->ethertype =
  10315                     (e2ecc_hdr.overlay1.words[7] >> 16) & 0xFFFF;
  10316                 config->opcode = e2ecc_hdr.overlay1.words[7] & 0xFFFF;
  10317 
  10318                 /* All the info from RX is encoded in the header, so
  10319                  * just mark if it is enabled. */
  10320                 if (port_rx_enabled) {
  10321                     config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10322                 }
  10323             }
  10324         } else if (port_rx_enabled) {
  10325             /* Recover RX state */
  10326             config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10327 
  10328             if (port_hcfc_rx) {
  10329                 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC;
  10330             } else if (voqfc) {
  10331                 config->flags |= BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL;
  10332                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10333                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10334                                               regval, DAf);
  10335                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10336                 config->dest_mac[1] = (field_val & 0xff);
  10337 
  10338                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10339                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10340                                               regval, DAf);
  10341                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10342                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10343                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10344                 config->dest_mac[5] = (field_val & 0xff);
  10345 
  10346                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10347                 config->ethertype =
  10348                     soc_reg_field_get(unit, ING_VOQFC_IDr, regval, LENGTH_TYPEf);
  10349                 config->opcode =
  10350                     soc_reg_field_get(unit, ING_VOQFC_IDr, regval, OPCODEf);
  10351 
  10352             } else {
  10353                 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC;
  10354                 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, &regval));
  10355                 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_MSr,
  10356                                               regval, DAf);
  10357                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10358                 config->dest_mac[1] = (field_val & 0xff);
  10359 
  10360                 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, &regval));
  10361                 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_LSr,
  10362                                               regval, DAf);
  10363                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10364                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10365                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10366                 config->dest_mac[5] = (field_val & 0xff);
  10367 
  10368                 SOC_IF_ERROR_RETURN
  10369                     (READ_E2E_HOL_RX_LENGTH_TYPEr(unit, &regval));
  10370                 config->ethertype =
  10371                     soc_reg_field_get(unit, E2E_HOL_RX_LENGTH_TYPEr,
  10372                                       regval, LENGTH_TYPEf);
  10373 
  10374                 SOC_IF_ERROR_RETURN
  10375                     (READ_E2E_HOL_RX_OPCODEr(unit, &regval));
  10376                 config->opcode =
  10377                     soc_reg_field_get(unit, E2E_HOL_RX_OPCODEr,
  10378                                       regval, OPCODEf);
  10379             }
  10380         }
  10381     }
  10382 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10383     if (SOC_IS_TRIDENT2PLUS(unit) ||
  10384         (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) {
  10385         PBMP_ALL_ITER(unit, port) {
  10386 
  10387             if (IS_HG_PORT(unit, port)) {
  10388                 continue;
  10389             }
  10390             SOC_IF_ERROR_RETURN(
  10391                READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  10392 
  10393            fc_format = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10394                                 regval, FLOW_CONTROL_FORMATf);
  10395            copy_to_cpu = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10396                                 regval, COPY_TO_CPUf);
  10397            if(!fc_format)
  10398            {
  10399               continue;
  10400            }
  10401 
  10402             /* Allocate space for the E2ECC configuration */
  10403             if (PORT(unit, port).e2ecc_config == NULL) {
  10404                 PORT(unit, port).e2ecc_config =
  10405                     sal_alloc(sizeof(bcm_port_congestion_config_t),
  10406                               "bcm_port_congestion_config");
  10407                 if (PORT(unit, port).e2ecc_config == NULL) {
  10408                     LOG_ERROR(BSL_LS_BCM_PORT,
  10409                               (BSL_META_U(unit,
  10410                                  "Error: unable to allocate memory for"
  10411                                  " bcm_port_congestion_config.\n")));
  10412                     return BCM_E_MEMORY;
  10413                 }
  10414             } else {
  10415                 /* This is initialized to NULL pointers by
  10416                  * port init.  How did it get changed? */
  10417                 return BCM_E_INTERNAL;
  10418             }
  10419 
  10420             config = PORT(unit, port).e2ecc_config;
  10421             bcm_port_congestion_config_t_init(config);
  10422 
  10423             /* Recover RX state */
  10424             config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10425             if (copy_to_cpu == 1) {
  10426                 config->flags |=
  10427                 BCM_PORT_CONGESTION_CONFIG_COPY_TO_CPU;
  10428             }
  10429             if (fc_format == 1) {
  10430                 config->flags |=
  10431                 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE;
  10432                 SOC_IF_ERROR_RETURN(
  10433                         READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10434                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10435                                             regval, DAf);
  10436                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10437                 config->dest_mac[1] = (field_val & 0xff);
  10438                 SOC_IF_ERROR_RETURN(
  10439                          READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10440                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10441                                               regval, DAf);
  10442                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10443                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10444                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10445                 config->dest_mac[5] = (field_val & 0xff);
  10446                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10447                 config->ethertype =
  10448                   soc_reg_field_get(unit, ING_VOQFC_IDr,
  10449                                              regval, LENGTH_TYPEf);
  10450                 config->opcode =
  10451                    soc_reg_field_get(unit, ING_VOQFC_IDr,
  10452                                          regval, OPCODEf);
  10453 
  10454             } else if (fc_format == 2) {
  10455                 config->flags |=
  10456                 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE;
  10457                 SOC_IF_ERROR_RETURN(
  10458                         READ_COE_VLAN_PAUSE_MACDA_MSr(unit, &regval));
  10459                 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_MSr,
  10460                                             regval, DAf);
  10461                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10462                 config->dest_mac[1] = (field_val & 0xff);
  10463                 SOC_IF_ERROR_RETURN(
  10464                         READ_COE_VLAN_PAUSE_MACDA_LSr(unit, &regval));
  10465                 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_LSr,
  10466                                             regval, DAf);
  10467                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10468                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10469                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10470                 config->dest_mac[5] = (field_val & 0xff);
  10471                 SOC_IF_ERROR_RETURN(READ_COE_VLAN_PAUSE_IDr(unit, &regval));
  10472                 config->ethertype =
  10473                   soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr,
  10474                                              regval, LENGTH_TYPEf);
  10475                 config->opcode =
  10476                    soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr,
  10477                                          regval, OPCODEf);
  10478             }
  10479 
  10480         }
  10481      }
  10482 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10483 #ifdef     BCM_KATANA2_SUPPORT
  10484     if (SOC_IS_KATANA2(unit)) {
  10485         PBMP_ALL_ITER(unit, port) {
  10486             port_rx_enabled = 0;
  10487             e2ecc_coe = 0;
  10488 
  10489             if (IS_HG_PORT(unit, port)) {
  10490                 continue;
  10491             }
  10492             soc_cm_get_id(unit, &dev_id, &rev_id);
  10493 
  10494             if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  10495                 SOC_IF_ERROR_RETURN(
  10496                   READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  10497 
  10498                 if (soc_reg_field_valid(unit, COE_FLOW_CONTROL_CONFIGr,
  10499                          FLOW_CONTROL_FORMATf)) {
  10500                     if (0 != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10501                                 regval, FLOW_CONTROL_FORMATf)) {
  10502                         port_rx_enabled = 1;
  10503                         e2ecc_coe = 1;
  10504                         e2ecc_strict = soc_reg_field_get(unit,
  10505                                          COE_FLOW_CONTROL_CONFIGr,
  10506                                          regval, E2ECC_MODEf);
  10507                      }
  10508                 }
  10509             } else if (rev_id == BCM56450_A0_REV_ID) {
  10510                 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  10511                 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) {
  10512                     if (0 != soc_reg_field_get(unit, IE2E_CONTROLr,
  10513                                                regval, VOQFC_ENABLEf)) {
  10514                         port_rx_enabled = 1;
  10515                         e2ecc_coe = 1;
  10516                     }
  10517                 }
  10518             }
  10519             if (!port_rx_enabled) {
  10520                 /* On to the next port */
  10521                 continue;
  10522             }
  10523 
  10524             /* Allocate space for the E2ECC configuration */
  10525             if (PORT(unit, port).e2ecc_config == NULL) {
  10526                 PORT(unit, port).e2ecc_config =
  10527 
  10528                     sal_alloc(sizeof(bcm_port_congestion_config_t),
  10529                               "bcm_port_congestion_config");
  10530                 if (PORT(unit, port).e2ecc_config == NULL) {
  10531                     LOG_ERROR(BSL_LS_BCM_PORT,
  10532                               (BSL_META_U(unit,
  10533                                  "Error: unable to allocate memory for"
  10534                                  " bcm_port_congestion_config.\n")));
  10535                     return BCM_E_MEMORY;
  10536                 }
  10537             } else {
  10538                 /* This is initialized to NULL pointers by
  10539                  * port init.  How did it get changed? */
  10540                 return BCM_E_INTERNAL;
  10541             }
  10542 
  10543             config = PORT(unit, port).e2ecc_config;
  10544             bcm_port_congestion_config_t_init(config);
  10545 
  10546             if (port_rx_enabled) {
  10547                 /* Recover RX state */
  10548                 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10549                 if (e2ecc_coe) {
  10550                     if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  10551                         if (e2ecc_strict) {
  10552                             config->flags |=
  10553                               BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE;
  10554                         } else {
  10555                             config->flags |=
  10556                               BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE;
  10557                         }
  10558                     } else if (rev_id == BCM56450_A0_REV_ID) {
  10559                         config->flags |=
  10560                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE;
  10561                     }
  10562                     SOC_IF_ERROR_RETURN(
  10563                                READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10564                     field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10565                                                   regval, DAf);
  10566                     config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10567                     config->dest_mac[1] = (field_val & 0xff);
  10568 
  10569                     SOC_IF_ERROR_RETURN(
  10570                                READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10571                     field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10572                                                   regval, DAf);
  10573                     config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10574                     config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10575                     config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10576                     config->dest_mac[5] = (field_val & 0xff);
  10577 
  10578                     SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10579                     config->ethertype =
  10580                         soc_reg_field_get(unit, ING_VOQFC_IDr,
  10581                                                regval, LENGTH_TYPEf);
  10582                     config->opcode =
  10583                         soc_reg_field_get(unit, ING_VOQFC_IDr,
  10584                                                regval, OPCODEf);
  10585                 }
  10586             }
  10587         }
  10588     }
  10589 #endif /* BCM_KATANA2_SUPPORT */
  10590 
  10591     return BCM_E_NONE;
  10592 }
  10593 #endif /* BCM_TRX_SUPPORT */
  10594 
  10595 STATIC void
  10596 _scache_port_print_ll_init(int unit)
  10597 {
  10598     int i;
  10599 
  10600     for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) {
  10601         scache_head[i] = NULL;
  10602         scache_tail[i] = NULL;
  10603     }
  10604 }
  10605 
  10606 STATIC void
  10607 _scache_port_print_clear_ll(int unit, scache_port_type_t type)
  10608 {
  10609     scache_port_print_port_t *entry;
  10610 
  10611     if (bsl_check(bslLayerShared, bslSourceScache,
  10612                 bslSeverityVerbose, unit)) {
  10613         assert(type < SCACHE_PORT_TYPE_MAX);
  10614 
  10615         /* delete from the head */
  10616         while (scache_head[type] != NULL) {
  10617             entry = scache_head[type];
  10618             scache_head[type] = scache_head[type]->next;
  10619             sal_free(entry);
  10620         }
  10621         /* now that the list is empty and head is NULL, make tail pointer NULL */
  10622         scache_tail[type] = NULL;
  10623     }
  10624 }
  10625 
  10626 STATIC void
  10627 _scache_port_print_clear_all(int unit)
  10628 {
  10629     int i;
  10630 
  10631     for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) {
  10632         _scache_port_print_clear_ll(unit, i);
  10633     }
  10634 }
  10635 
  10636 STATIC void
  10637 _scache_port_print_add_ll(int unit, scache_port_type_t type,
  10638                                 scache_port_print_port_t * entry)
  10639 {
  10640     if (NULL == entry) {
  10641         return;
  10642     }
  10643 
  10644     /* Head of linked list is NULL */
  10645     if (scache_head[type] == NULL) {
  10646         scache_head[type] = entry;
  10647         scache_tail[type] = entry;
  10648     } else {
  10649         /* put the entry at the end */
  10650 
  10651         /* Update the current tail's next */
  10652         scache_tail[type]->next = entry;
  10653 
  10654         /* Store the entry at the end */
  10655         scache_tail[type] = entry;
  10656     }
  10657 }
  10658 
  10659 STATIC int
  10660 _scache_port_print_add(int unit, int port, scache_port_type_t type, int len,
  10661                         uint8 *val)
  10662 {
  10663     scache_port_print_port_t *new_entry;
  10664 
  10665     if (bsl_check(bslLayerShared, bslSourceScache,
  10666                 bslSeverityVerbose, unit)) {
  10667         assert(type < SCACHE_PORT_TYPE_MAX);
  10668 
  10669         new_entry = (scache_port_print_port_t *)
  10670             sal_alloc(sizeof(scache_port_print_port_t), "scache_port");
  10671         if (NULL == new_entry) {
  10672             return BCM_E_MEMORY;
  10673         }
  10674 
  10675         new_entry->next = NULL;
  10676         new_entry->val = val;
  10677         new_entry->len = len;
  10678         new_entry->port = port;
  10679 
  10680         _scache_port_print_add_ll(unit, type, new_entry);
  10681     }
  10682 
  10683     return BCM_E_NONE;
  10684 }
  10685 
  10686 STATIC void
  10687 _scache_port_print(int unit, scache_port_type_t type)
  10688 {
  10689     uint8 *scache_runner;
  10690     scache_port_print_port_t *runner;
  10691 
  10692     if (bsl_check(bslLayerShared, bslSourceScache,
  10693                 bslSeverityVerbose, unit)) {
  10694         assert(type < SCACHE_PORT_TYPE_MAX);
  10695 
  10696         runner = scache_head[type];
  10697 
  10698         /* No scache entries in this type */
  10699         if (runner == NULL) {
  10700             return;
  10701         }
  10702 
  10703         /* If port == -1, not a port based entry */
  10704         if (runner->port == -1) {
  10705             LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10706                 (BSL_META_U(unit,
  10707                             "\nS$BEGIN:<port>:<%s>"),
  10708                             port_scache_strs[type]));
  10709 
  10710             while(NULL != runner) {
  10711                 if (runner->len == sizeof(uint8)) {
  10712                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10713                             (BSL_META_U(unit,
  10714                                         "\n{0x%02x}"),
  10715                              *(int *)(runner->val) & 0xff));
  10716                 } else if (runner->len == sizeof(uint16) ||
  10717                         runner->len == sizeof(uint32)) {
  10718                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10719                             (BSL_META_U(unit,
  10720                                         "\n{%d}"),
  10721                              *(int *)(runner->val)));
  10722                 } else {
  10723                     /* larger than 32 bits */
  10724                     scache_runner = runner->val;
  10725                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10726                             (BSL_META_U(unit,
  10727                                         "\n{")));
  10728                     while (scache_runner < runner->val + runner->len) {
  10729                         LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10730                                 (BSL_META_U(unit,
  10731                                             "%d%s"), *(int *)(runner->val),
  10732                                  ((scache_runner+sizeof(int)) <
  10733                                   (runner->val + runner->len))?" ":""));
  10734                         scache_runner += sizeof(int);
  10735                     }
  10736                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10737                             (BSL_META_U(unit,
  10738                                         "}")));
  10739                 }
  10740 
  10741                 /* Go to the next entry */
  10742                 runner = runner->next;
  10743             }
  10744         } else {
  10745             LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10746                 (BSL_META_U(unit,
  10747                             "\nS$BEGIN:<port>:<port;%s>"),
  10748                             port_scache_strs[type]));
  10749 
  10750             while(NULL != runner) {
  10751                 if (runner->len == sizeof(uint8)) {
  10752                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10753                             (BSL_META_U(unit,
  10754                                         "\n{%d;0x%02x}"), runner->port,
  10755                              *(int *)(runner->val) & 0xff));
  10756                 } else if (runner->len == sizeof(uint16) ||
  10757                         runner->len == sizeof(uint32)) {
  10758                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10759                             (BSL_META_U(unit,
  10760                                         "\n{%d;%d}"), runner->port,
  10761                              *(int *)(runner->val)));
  10762                 } else {
  10763                     /* larger than 32 bits */
  10764                     scache_runner = runner->val;
  10765                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10766                             (BSL_META_U(unit,
  10767                                         "\n{%d;"), runner->port));
  10768                     while (scache_runner < runner->val + runner->len) {
  10769                         LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10770                                 (BSL_META_U(unit,
  10771                                             "%d%s"), *(int *)(runner->val),
  10772                                  ((scache_runner+sizeof(int)) <
  10773                                   (runner->val + runner->len))?" ":""));
  10774                         scache_runner += sizeof(int);
  10775                     }
  10776                     LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10777                             (BSL_META_U(unit,
  10778                                         "}")));
  10779                 }
  10780 
  10781                 /* Go to the next entry */
  10782                 runner = runner->next;
  10783             }
  10784         }
  10785 
  10786 
  10787         LOG_VERBOSE(BSL_LS_SHARED_SCACHE,
  10788                 (BSL_META_U(unit,
  10789                             "\nS$END:port\n")));
  10790     }
  10791 }
  10792 
  10793 STATIC void
  10794 _scache_port_print_all(int unit)
  10795 {
  10796     int i;
  10797 
  10798     for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) {
  10799         _scache_port_print(unit, i);
  10800     }
  10801 }
  10802 
  10803 STATIC int
  10804 _bcm_esw_port_sync_scache(int unit, uint8 *port_state, int stable_size,
  10805                             uint32 asf_wbmem_sz, uint32 latency_wbmem_sz,
  10806                             bcm_pbmp_t *all_pbmp)
  10807 {
  10808     bcm_port_t port;
  10809     bcm_pbmp_t dtm_pbmp;
  10810     _bcm_port_info_t *pinfo = NULL;
  10811     int rv = BCM_E_NONE;
  10812 #ifdef BCM_TRIDENT_SUPPORT
  10813         soc_info_t *si = &SOC_INFO(unit);
  10814 #endif
  10815 
  10816     BCM_PBMP_CLEAR(dtm_pbmp);
  10817 
  10818     PBMP_ITER(*all_pbmp, port) {
  10819         if (port < SOC_MAX_NUM_PORTS) {
  10820             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10821         }
  10822 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10823         if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  10824             int idxmin, idxmax, idx;
  10825             idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  10826             idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  10827 
  10828             for (idx = idxmin; idx <= idxmax; idx++) {
  10829                 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx)) {
  10830                     sal_memcpy(port_state, &idx, sizeof(int));
  10831                     port_state += sizeof(int);
  10832 
  10833                     BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10834                                 SPT_PBVL, sizeof(int), port_state - sizeof(int)));
  10835                     break;
  10836                 }
  10837             }
  10838             if (idx > idxmax) {
  10839                 idx = -1;
  10840                 sal_memcpy(port_state, &idx, sizeof(int));
  10841                 port_state += sizeof(int);
  10842 
  10843                 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_PBVL,
  10844                             sizeof(int), port_state - sizeof(int)));
  10845             }
  10846 
  10847             sal_memcpy(port_state, &(pinfo->vlan_prot_ptr),
  10848                     sizeof(uint32));
  10849             port_state += sizeof(uint32);
  10850 
  10851             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10852                         SPT_VLAN_PROT_PTR, sizeof(uint32),
  10853                         port_state - sizeof(uint32)));
  10854         }
  10855 #endif
  10856         /* In Apache information is saved and recovered for 76 ports which is
  10857          * greater than SOC_MAX_NUM_PORTS value of 75. These checks are
  10858          * needed to prevent invalid memory access.
  10859          */
  10860         if (port < SOC_MAX_NUM_PORTS) {
  10861             if (0 != (pinfo->dtag_mode &
  10862                         (BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL))) {
  10863                 /* Some sort of double-tagged mode */
  10864                 BCM_PBMP_PORT_ADD(dtm_pbmp, port);
  10865             }
  10866             sal_memcpy(port_state, &(pinfo->vp_count), sizeof(pinfo->vp_count));
  10867         }
  10868         port_state += sizeof(int);
  10869 
  10870         BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_VP_COUNT,
  10871                             sizeof(int), port_state - sizeof(int)));
  10872     }
  10873     sal_memcpy(port_state, &dtm_pbmp, sizeof(dtm_pbmp));
  10874     port_state += sizeof(dtm_pbmp);
  10875     BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_DTM_PBMP,
  10876                 sizeof(dtm_pbmp), port_state - sizeof(dtm_pbmp)));
  10877 
  10878     PBMP_ITER(*all_pbmp, port) {
  10879         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  10880             if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  10881                 if (port < SOC_MAX_NUM_PORTS) {
  10882                     sal_memcpy(port_state, &(PORT(unit, port).cosmask), sizeof(uint32));
  10883                 }
  10884                 port_state += sizeof(uint32);
  10885 
  10886                 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10887                             SPT_COSMASK, sizeof(uint32), port_state - sizeof(uint32)));
  10888             } else {
  10889                 if (port < SOC_MAX_NUM_PORTS) {
  10890                     sal_memcpy(port_state, &(PORT(unit, port).m_info),
  10891                             sizeof(_bcm_port_metering_info_t));
  10892                 }
  10893                 port_state += sizeof(_bcm_port_metering_info_t);
  10894 
  10895                 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_METERING_INFO,
  10896                         sizeof(_bcm_port_metering_info_t),
  10897                         port_state - sizeof(_bcm_port_metering_info_t)));
  10898             }
  10899             if (port < SOC_MAX_NUM_PORTS) {
  10900                 sal_memcpy(port_state, &(PORT(unit, port).flags), sizeof(uint8));
  10901             }
  10902             port_state += sizeof(uint8);
  10903 
  10904             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10905                         SPT_PORT_FLAGS, sizeof(uint8),
  10906                         port_state - sizeof(uint8)));
  10907         }
  10908 
  10909     }
  10910 #ifdef BCM_TRIDENT_SUPPORT
  10911     if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  10912             soc_feature(unit, soc_feature_flex_port)) {
  10913         /* coverity[overrun-local] */
  10914         PBMP_ALL_ITER(unit, port) {
  10915             if (port < SOC_MAX_NUM_PORTS) {
  10916                 sal_memcpy(port_state, &(si->port_num_lanes[port]), sizeof(int));
  10917             }
  10918             port_state += sizeof(int);
  10919 
  10920             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10921                         SPT_PORT_NUM_LANES, sizeof(int),
  10922                         port_state - sizeof(int)));
  10923         }
  10924     }
  10925 #endif
  10926 
  10927     /* Restore SW RX LOS status */
  10928     PBMP_ITER(*all_pbmp, port) {
  10929         if (port < SOC_MAX_NUM_PORTS) {
  10930             sal_memcpy(port_state, &(PORT(unit, port).rx_los), sizeof(uint8));
  10931         }
  10932         port_state += sizeof(uint8);
  10933 
  10934         BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_RX_LOS,
  10935                     sizeof(uint8), port_state - sizeof(uint8)));
  10936     }
  10937 
  10938 
  10939 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT)
  10940     if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) {
  10941         /* Restore port enable status */
  10942         PBMP_ITER(*all_pbmp, port) {
  10943             if (port < SOC_MAX_NUM_PORTS) {
  10944                 sal_memcpy(port_state, &(PORT(unit, port).enable), sizeof(int));
  10945             }
  10946             port_state += sizeof(int);
  10947 
  10948             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  10949                         SPT_PORT_ENABLE, sizeof(int), port_state - sizeof(int)));
  10950         }
  10951     }
  10952 #endif /* BCM_TRIDENT2_SUPPORT */
  10953 #ifdef BCM_TRIUMPH3_SUPPORT
  10954     if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  10955         if (_port_ibod_ctrl[unit]) {
  10956             sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrbyt,
  10957                     sizeof(((_port_ibod_ctrl_t *)0)->rrbyt));
  10958             port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  10959             sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrpkt,
  10960                     sizeof(((_port_ibod_ctrl_t *)0)->rrpkt));
  10961             port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  10962             sal_memcpy(port_state, &(_port_ibod_ctrl[unit]->event_count),
  10963                     sizeof(((_port_ibod_ctrl_t *)0)->event_count));
  10964             port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  10965         }  else {
  10966             sal_memset(port_state, 0,
  10967                     2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10968                     + sizeof((((_port_ibod_ctrl_t *)0)->event_count)));
  10969             port_state += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10970                 + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  10971         }
  10972 
  10973     }
  10974     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  10975         BCM_IF_ERROR_RETURN(_bcm_port_force_forward_sync(unit, &port_state));
  10976     }
  10977 #endif /* BCM_TRIUMPH3_SUPPORT */
  10978 
  10979 #ifdef  BCM_TOMAHAWK_SUPPORT
  10980     /* ASF WB */
  10981     BCM_IF_ERROR_RETURN(_bcm_esw_asf_wb_sync(unit, port_state));
  10982     port_state += asf_wbmem_sz;
  10983 
  10984     BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_ASF, asf_wbmem_sz,
  10985                         port_state - asf_wbmem_sz));
  10986 
  10987     /* Switch Latency Bypass WB */
  10988     BCM_IF_ERROR_RETURN(bcmi_esw_switch_latency_wb_sync(unit, port_state));
  10989     port_state += latency_wbmem_sz;
  10990 
  10991     BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_LATENCY,
  10992                 latency_wbmem_sz, port_state - latency_wbmem_sz));
  10993 
  10994 #endif /* BCM_TOMAHAWK_SUPPORT */
  10995 
  10996     /*IFG WB*/
  10997     if (soc_feature(unit, soc_feature_xmac) ||
  10998             soc_feature(unit, soc_feature_xlmac) ||
  10999             soc_feature(unit, soc_feature_cmac) ||
  11000             soc_feature(unit, soc_feature_clmac)) {
  11001 
  11002         BCM_IF_ERROR_RETURN(_bcm_esw_port_ifg_wb_sync(unit, &port_state));
  11003     }
  11004     /* PORT DSCP MAP SETTING */
  11005     if (soc_feature(unit, soc_feature_dscp) &&
  11006             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11007         /* Allocate size for port dscp map setting status */
  11008         PBMP_ITER(*all_pbmp, port) {
  11009             sal_memcpy(port_state, &(PORT(unit, port).port_dscp_map_set), sizeof(int));
  11010             port_state += sizeof(int);
  11011 
  11012             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_DSCP_MAP,
  11013                         sizeof(int), port_state - sizeof(int)));
  11014         }
  11015     }
  11016 
  11017 #if defined(BCM_CLMAC_SUPPORT)
  11018     if (SOC_IS_TOMAHAWK(unit)) {
  11019         soc_port_if_t       pif;
  11020         /* Restore port interface type */
  11021         PBMP_ITER(*all_pbmp, port) {
  11022             if (IS_XE_PORT(unit, port) ||
  11023                     IS_CE_PORT(unit, port) ||
  11024                     IS_HG_PORT(unit, port) ||
  11025                     IS_GE_PORT(unit, port) ||
  11026                     IS_MANAGEMENT_PORT(unit, port)) {
  11027                 BCM_IF_ERROR_RETURN(soc_phyctrl_interface_get(unit, port, &pif));
  11028                 sal_memcpy(port_state, &pif, sizeof(int));
  11029                 port_state += sizeof(int);
  11030 
  11031                 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  11032                             SPT_PORT_INTF_TYPE, sizeof(int),
  11033                             port_state - sizeof(int)));
  11034             }
  11035         }
  11036     }
  11037 #endif
  11038 
  11039     if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  11040         soc_port_if_t       pif;
  11041 
  11042         /* Restore port interface type */
  11043         PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11044             rv = soc_phyctrl_interface_get(unit, port, &pif);
  11045             if (BCM_FAILURE(rv)) {
  11046                 pif = 0;
  11047             }
  11048             sal_memcpy(port_state, &pif, sizeof(int));
  11049             port_state += sizeof(int);
  11050 
  11051             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  11052                         SPT_PORT_INTF_TYPE,
  11053                         sizeof(int), port_state - sizeof(int)));
  11054         }
  11055     }
  11056 
  11057     return BCM_E_NONE;
  11058 }
  11059 /*
  11060  * Function:
  11061  *      _bcm_esw_port_sync
  11062  * Purpose:
  11063  *      Record Port module persisitent info for Level 2 Warm Boot
  11064  *
  11065  * Warm Boot Version Map:
  11066  *      Fields for previous version to be documented
  11067  *  BCM_PORT_WB_VERSION_1_0
  11068  *      ...
  11069  *  BCM_PORT_WB_VERSION_1_1
  11070  *      ...
  11071  *  BCM_PORT_WB_VERSION_1_2
  11072  *    rx_los            SW RX LOS
  11073  *      ...
  11074  *  BCM_PORT_WB_VERSION_1_3
  11075  *    enable            port eanble status
  11076  *
  11077  * Parameters:
  11078  *      unit - StrataSwitch unit number.
  11079  * Returns:
  11080  *      BCM_E_XXX
  11081  */
  11082 int
  11083 _bcm_esw_port_sync(int unit)
  11084 {
  11085     int rv = BCM_E_NONE;
  11086 
  11087 #if defined(BCM_TRX_SUPPORT)
  11088     if (SOC_IS_TRX(unit)) {
  11089         int alloc_sz;
  11090         bcm_port_t port;
  11091         uint8 *port_state;
  11092         bcm_pbmp_t dtm_pbmp;
  11093         int stable_size;
  11094         soc_scache_handle_t scache_handle;
  11095         bcm_pbmp_t all_pbmp;
  11096         uint32 asf_wbmem_sz = 0;
  11097         /* Switch Latency Bypass WB will move to a different module later */
  11098         uint32 latency_wbmem_sz = 0;
  11099 
  11100         BCM_PBMP_CLEAR(all_pbmp);
  11101         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  11102 
  11103 #ifdef BCM_KATANA2_SUPPORT
  11104         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  11105             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  11106         }
  11107         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  11108             soc_feature(unit, soc_feature_subtag_coe)) {
  11109             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  11110         }
  11111 #endif
  11112 
  11113 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11114         if (SOC_IS_TD2P_TT2P(unit)) {
  11115             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  11116                                                  &all_pbmp));
  11117         }
  11118 #endif
  11119 #ifdef BCM_MONTEREY_SUPPORT
  11120             if (SOC_IS_MONTEREY(unit)) {
  11121                 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  11122             }
  11123 #endif
  11124 #ifdef BCM_APACHE_SUPPORT
  11125         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  11126             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  11127         }
  11128 #endif
  11129 
  11130         alloc_sz = 0;
  11131         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  11132         PBMP_ITER(all_pbmp, port) {
  11133 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  11134             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  11135                 /* vp entry and vlan prot ptr */
  11136                 alloc_sz += (sizeof(int) + sizeof(uint32));
  11137             }
  11138 #endif
  11139             alloc_sz += sizeof(int); /* vp count */
  11140         }
  11141         alloc_sz += sizeof(dtm_pbmp); /* Bitmap of dtag_mode set */
  11142 
  11143         PBMP_ITER(all_pbmp, port) {
  11144             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11145                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11146                     alloc_sz += sizeof(uint32);
  11147                 } else {
  11148                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  11149                 }
  11150                 alloc_sz += sizeof(uint8); /* flags */
  11151             }
  11152         }
  11153 
  11154 #ifdef BCM_TRIDENT_SUPPORT
  11155         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  11156             soc_feature(unit, soc_feature_flex_port)) {
  11157             /* Number of lanes per port needs to be stored.*/
  11158             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  11159         }
  11160 #endif
  11161 
  11162         /* Size for SW RX LOS status */
  11163         PBMP_ITER(all_pbmp, port) {
  11164             alloc_sz += sizeof(uint8);
  11165         }
  11166 
  11167 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT)
  11168         if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) {
  11169             /* Size for port enable status */
  11170             PBMP_ITER(all_pbmp, port) {
  11171                 alloc_sz += sizeof(int);
  11172             }
  11173         }
  11174 #endif /* BCM_TRIDENT2_SUPPORT */
  11175 #ifdef BCM_TRIUMPH3_SUPPORT
  11176         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  11177             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  11178                         + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  11179         }
  11180 #endif /* BCM_TRIUMPH3_SUPPORT */
  11181 #if defined(BCM_TRIUMPH3_SUPPORT)
  11182         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  11183             int port_forward_size;
  11184             BCM_IF_ERROR_RETURN(
  11185                 _bcm_port_force_forward_scache_size(unit,
  11186                                                     &port_forward_size));
  11187             alloc_sz += port_forward_size;
  11188         }
  11189 #endif
  11190 
  11191 #ifdef  BCM_TOMAHAWK_SUPPORT
  11192         /* ASF WB */
  11193         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz,
  11194                                        BCM_PORT_WB_DEFAULT_VERSION);
  11195         if (BCM_E_NONE == rv) {
  11196             alloc_sz += asf_wbmem_sz;
  11197         }
  11198 
  11199         /* Switch Latency Bypass WB */
  11200         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  11201                                                   BCM_PORT_WB_DEFAULT_VERSION);
  11202         if (BCM_E_NONE == rv) {
  11203             alloc_sz += latency_wbmem_sz;
  11204         }
  11205 #endif /* BCM_TOMAHAWK_SUPPORT */
  11206 
  11207         /*IFG WB*/
  11208         if (soc_feature(unit, soc_feature_xmac) ||
  11209                 soc_feature(unit, soc_feature_xlmac) ||
  11210                 soc_feature(unit, soc_feature_cmac) ||
  11211                 soc_feature(unit, soc_feature_clmac)) {
  11212             PBMP_ITER(all_pbmp, port) {
  11213                 alloc_sz += sizeof(uint32);
  11214             }
  11215         }
  11216         /* PORT DSCP MAP SETTING */
  11217         if (soc_feature(unit, soc_feature_dscp) &&
  11218             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11219             /* Allocate size for port dscp map setting status */
  11220             PBMP_ITER(all_pbmp, port) {
  11221                 alloc_sz += sizeof(int);
  11222             }
  11223         }
  11224 
  11225 #ifdef  BCM_TOMAHAWK_SUPPORT
  11226         if (SOC_IS_TOMAHAWK(unit)) {
  11227             /* Allocate size for port interface type */
  11228             PBMP_ITER(all_pbmp, port) {
  11229                 alloc_sz += sizeof(int);
  11230             }
  11231         }
  11232 #endif /* BCM_TOMAHAWK_SUPPORT */
  11233 
  11234        if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  11235             /* Allocate size for port interface type */
  11236             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11237                 alloc_sz += sizeof(int);
  11238             }
  11239        }
  11240 
  11241         SOC_SCACHE_HANDLE_SET(scache_handle,
  11242                               unit, BCM_MODULE_PORT,
  11243                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  11244         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  11245                                      alloc_sz, (uint8**)&port_state,
  11246                                      BCM_PORT_WB_DEFAULT_VERSION, NULL);
  11247         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  11248             return rv;
  11249         }
  11250 
  11251         _scache_port_print_ll_init(unit);
  11252 
  11253         PORT_LOCK(unit);
  11254 
  11255         rv = _bcm_esw_port_sync_scache(unit, port_state, stable_size, asf_wbmem_sz, latency_wbmem_sz,
  11256                             &all_pbmp);
  11257 
  11258         PORT_UNLOCK(unit);
  11259 
  11260         if (BCM_SUCCESS(rv)) {
  11261             _scache_port_print_all(unit);
  11262         }
  11263         _scache_port_print_clear_all(unit);
  11264         if (BCM_FAILURE(rv)) {
  11265             return rv;
  11266         }
  11267     }
  11268 #endif /* BCM_TRX_SUPPORT */
  11269 
  11270 #ifdef BCM_PREEMPTION_SUPPORT
  11271     if (BCM_SUCCESS(rv) && soc_feature(unit, soc_feature_preemption)) {
  11272         soc_scache_handle_t scache_handle;
  11273 
  11274         SOC_SCACHE_HANDLE_SET(scache_handle,
  11275                               unit, BCM_MODULE_PORT,
  11276                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  11277 
  11278         rv = bcmi_esw_preemption_sync(unit, scache_handle);
  11279     }
  11280 #endif /* BCM_PREEMPTION_SUPPORT */
  11281     return rv;
  11282 }
  11283 
  11284 int
  11285 _bcm_esw_port_wb_alloc(int unit)
  11286 {
  11287 
  11288 #if defined(BCM_TRX_SUPPORT)
  11289     if (SOC_IS_TRX(unit)) {
  11290         int alloc_sz, rv = BCM_E_NONE;
  11291         bcm_port_t port;
  11292         uint8 *port_state;
  11293         int stable_size;
  11294         bcm_pbmp_t all_pbmp;
  11295         soc_scache_handle_t scache_handle;
  11296 #ifdef  BCM_TOMAHAWK_SUPPORT
  11297         uint32 asf_wbmem_sz = 0;
  11298 
  11299         /* Switch Latency Bypass WB will move to a different module later */
  11300         uint32 latency_wbmem_sz = 0;
  11301 #endif /* BCM_TOMAHAWK_SUPPORT */
  11302 
  11303         BCM_PBMP_CLEAR(all_pbmp);
  11304         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  11305 
  11306 #ifdef BCM_KATANA2_SUPPORT
  11307         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  11308             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  11309         }
  11310         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  11311             soc_feature(unit, soc_feature_subtag_coe)) {
  11312             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  11313         }
  11314 #endif
  11315 
  11316 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11317         if (SOC_IS_TD2P_TT2P(unit)) {
  11318             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  11319                                                  &all_pbmp));
  11320         }
  11321 #endif
  11322 #ifdef BCM_MONTEREY_SUPPORT
  11323             if (SOC_IS_MONTEREY(unit)) {
  11324                 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  11325             }
  11326 #endif
  11327 #ifdef BCM_APACHE_SUPPORT
  11328         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  11329             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  11330         }
  11331 #endif
  11332         alloc_sz = 0;
  11333         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  11334         PBMP_ITER(all_pbmp, port) {
  11335 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  11336             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  11337                 /* vp entry and vlan prot ptr */
  11338                 alloc_sz += (sizeof(int) + sizeof(uint32));
  11339             }
  11340 #endif
  11341             alloc_sz += sizeof(int); /* vp count */
  11342         }
  11343         alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  11344         PBMP_ITER(all_pbmp, port) {
  11345             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11346                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11347                     alloc_sz += sizeof(uint32);
  11348                 } else {
  11349                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  11350                 }
  11351                 alloc_sz += sizeof(uint8); /* flags */
  11352             }
  11353         }
  11354 
  11355 #ifdef BCM_TRIDENT_SUPPORT
  11356         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  11357             soc_feature(unit, soc_feature_flex_port)) {
  11358             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  11359         }
  11360 #endif
  11361 
  11362         /* Restore SW RX LOS status */
  11363         PBMP_ITER(all_pbmp, port) {
  11364             alloc_sz += sizeof(uint8);
  11365         }
  11366 
  11367 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT)
  11368         if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) {
  11369             /* Allocate size for port enable status */
  11370             PBMP_ITER(all_pbmp, port) {
  11371                 alloc_sz += sizeof(int);
  11372             }
  11373         }
  11374 #endif /* BCM_TRIDENT2_SUPPORT */
  11375 #ifdef BCM_TRIUMPH3_SUPPORT
  11376         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  11377             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  11378                          + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  11379         }
  11380 #endif /* BCM_TRIUMPH3_SUPPORT */
  11381 #if defined(BCM_TRIUMPH3_SUPPORT)
  11382         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  11383             int port_forward_size;
  11384             BCM_IF_ERROR_RETURN(
  11385                 _bcm_port_force_forward_scache_size(unit, &port_forward_size));
  11386             alloc_sz += port_forward_size;
  11387         }
  11388 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  11389 
  11390 #ifdef  BCM_TOMAHAWK_SUPPORT
  11391         /* ASF WB */
  11392         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, BCM_PORT_WB_DEFAULT_VERSION);
  11393         if (BCM_E_NONE == rv) {
  11394             alloc_sz += asf_wbmem_sz;
  11395         }
  11396 
  11397         /* Switch Latency Bypass WB */
  11398         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  11399                                                   BCM_PORT_WB_DEFAULT_VERSION);
  11400         if (BCM_E_NONE == rv) {
  11401             alloc_sz += latency_wbmem_sz;
  11402         }
  11403 #endif /* BCM_TOMAHAWK_SUPPORT */
  11404 
  11405         /*IFG WB*/
  11406         if (soc_feature(unit, soc_feature_xmac) ||
  11407                 soc_feature(unit, soc_feature_xlmac) ||
  11408                 soc_feature(unit, soc_feature_cmac) ||
  11409                 soc_feature(unit, soc_feature_clmac)) {
  11410             PBMP_ITER(all_pbmp, port) {
  11411                 alloc_sz += sizeof(uint32);
  11412             }
  11413         }
  11414         /* PORT DSCP MAP SETTING */
  11415         if (soc_feature(unit, soc_feature_dscp) &&
  11416             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11417             /* Allocate size for port dscp map setting status */
  11418             PBMP_ITER(all_pbmp, port) {
  11419                 alloc_sz += sizeof(int);
  11420             }
  11421         }
  11422 
  11423 #ifdef  BCM_TOMAHAWK_SUPPORT
  11424         if (SOC_IS_TOMAHAWK(unit)) {
  11425             /* Allocate size for port interface type */
  11426             PBMP_ITER(all_pbmp, port) {
  11427                 alloc_sz += sizeof(int);
  11428             }
  11429         }
  11430 #endif /* BCM_TOMAHAWK_SUPPORT */
  11431 
  11432         if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  11433             /* Allocate size for port interface type */
  11434             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11435                 alloc_sz += sizeof(int);
  11436             }
  11437         }
  11438 
  11439         SOC_SCACHE_HANDLE_SET(scache_handle,
  11440                               unit, BCM_MODULE_PORT,
  11441                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  11442         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
  11443                                      alloc_sz, (uint8**)&port_state,
  11444                                      BCM_PORT_WB_DEFAULT_VERSION, NULL);
  11445         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  11446             return rv;
  11447         }
  11448     }
  11449 #endif /* BCM_TRX_SUPPORT */
  11450 
  11451 #ifdef BCM_PREEMPTION_SUPPORT
  11452     if (soc_feature(unit, soc_feature_preemption)) {
  11453         soc_scache_handle_t scache_handle;
  11454 
  11455         SOC_SCACHE_HANDLE_SET(scache_handle,
  11456                               unit, BCM_MODULE_PORT,
  11457                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  11458         BCM_IF_ERROR_RETURN(
  11459             bcmi_esw_preemption_wb_alloc(unit, scache_handle));
  11460     }
  11461 #endif /* BCM_PREEMPTION_SUPPORT */
  11462 
  11463     return BCM_E_NONE;
  11464 }
  11465 
  11466 #ifdef BCM_TRIUMPH2_SUPPORT
  11467 /*
  11468  * Function:
  11469  *      _bcm_tr2_flexport_recover
  11470  * Purpose:
  11471  *     To recover/reconstruct the HL port configuration
  11472  *     during warmboot. This is a 'level one' warmboot
  11473  *     recovery. It depends on the reg configuration of
  11474  *     EDATABUF_XQP_FLEXPORT_CONFIGr which maintains the
  11475  *     flexport config of the HL ports that was done
  11476  *     in coldboot mode.
  11477  * Parameters:
  11478  *      unit - StrataSwitch unit number.
  11479  *      port - Port number of the HL
  11480  *             flexport controlling port.
  11481  * Returns:
  11482  *      BCM_E_XXX
  11483  */
  11484 STATIC int
  11485 _bcm_tr2_flexport_recover(int unit, bcm_port_t port)
  11486 {
  11487     uint8 rev_id;
  11488     uint16 dev_id;
  11489     uint32 port_type;
  11490     int i, old_value, rv;
  11491     bcm_port_t it_port;
  11492     port_tab_entry_t pent;
  11493     soc_info_t *si = &SOC_INFO(unit);
  11494 
  11495     soc_cm_get_id(unit, &dev_id, &rev_id);
  11496     BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value));
  11497 
  11498 #define RECONFIGURE_TR2_PORT_TYPE_INFO(ptype) \
  11499     si->ptype.num = 0; \
  11500     si->ptype.min = si->ptype.max = -1; \
  11501     PBMP_ITER(si->ptype.bitmap, it_port) { \
  11502         si->ptype.port[si->ptype.num++] = it_port; \
  11503         if (si->ptype.min < 0) { \
  11504             si->ptype.min = it_port; \
  11505         } \
  11506         if (it_port > si->ptype.max) { \
  11507             si->ptype.max = it_port; \
  11508         } \
  11509     }
  11510 
  11511     /* Step 1: Change the SOC bitmaps */
  11512     if ((old_value == 1)) {
  11513         /* The block originally had 4 GE ports */
  11514         SOC_CONTROL_LOCK(unit);
  11515         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  11516         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
  11517         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  11518         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  11519         SOC_PBMP_PORT_ADD(si->ge.bitmap, port);
  11520         si->port_speed_max[port] = 1000;
  11521         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE);
  11522         for (i = port + 1; i < port + 4; i++) {
  11523             SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i);
  11524             SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i);
  11525             SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i);
  11526             SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i);
  11527             si->port_speed_max[i] = 1000;
  11528             soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE);
  11529         }
  11530         RECONFIGURE_TR2_PORT_TYPE_INFO(ether);
  11531         RECONFIGURE_TR2_PORT_TYPE_INFO(st);
  11532         RECONFIGURE_TR2_PORT_TYPE_INFO(hg);
  11533         RECONFIGURE_TR2_PORT_TYPE_INFO(xe);
  11534         RECONFIGURE_TR2_PORT_TYPE_INFO(ge);
  11535         SOC_CONTROL_UNLOCK(unit);
  11536     } else if (old_value == 4) {
  11537         /* The block was originally a single high-speed port */
  11538         SOC_CONTROL_LOCK(unit);
  11539         rv = soc_mem_read(unit, SOC_PORT_MEM_TAB(unit, port),
  11540                 MEM_BLOCK_ANY, SOC_PORT_MOD_OFFSET(unit, port), &pent);
  11541         if (BCM_FAILURE(rv)) {
  11542             SOC_CONTROL_UNLOCK(unit);
  11543             return rv;
  11544         }
  11545         port_type = soc_PORT_TABm_field32_get(unit, &pent, PORT_TYPEf);
  11546         switch(port_type) {
  11547           case 0 : /* xe */
  11548             SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
  11549             SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  11550             SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
  11551             SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  11552             break;
  11553           case 1 : /* hg */
  11554             SOC_PBMP_PORT_ADD(si->hg.bitmap, port);
  11555             SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  11556             SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  11557             SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  11558           default:
  11559             break;
  11560         }
  11561         SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
  11562 	switch (dev_id) {
  11563 	case BCM56526_DEVICE_ID:
  11564 	  si->port_speed_max[port] = 13000;
  11565 	  break;
  11566 	case BCM56636_DEVICE_ID:
  11567 	case BCM56638_DEVICE_ID:
  11568 	  si->port_speed_max[port] = 12000;
  11569 	  break;
  11570 	default:
  11571 	  si->port_speed_max[port] = 10000;
  11572 	}
  11573         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
  11574         for (i = port + 1; i < port + 4; i++) {
  11575             SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i);
  11576             SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i);
  11577             SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i);
  11578             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i);
  11579         }
  11580         RECONFIGURE_TR2_PORT_TYPE_INFO(ether);
  11581         RECONFIGURE_TR2_PORT_TYPE_INFO(st);
  11582         RECONFIGURE_TR2_PORT_TYPE_INFO(hg);
  11583         RECONFIGURE_TR2_PORT_TYPE_INFO(ge);
  11584         SOC_CONTROL_UNLOCK(unit);
  11585     }
  11586 #undef RECONFIGURE_PORT_TYPE_INFO
  11587     soc_dport_map_update(unit);
  11588 
  11589     return BCM_E_NONE;
  11590 }
  11591 #endif /* BCM_TRIUMPH2_SUPPORT */
  11592 
  11593 #ifdef BCM_TRIDENT2_SUPPORT
  11594 /*
  11595  * Function:
  11596  *      _bcm_td2_flexport_recover
  11597  * Purpose:
  11598  *     To recover/reconstruct the HL port configuration
  11599  *     during warmboot. This is a 'level one' warmboot
  11600  *     recovery. It depends on the reg configuration of
  11601  *     XLPORT_MODE_REGr which maintains the
  11602  *     flexport config of the HL ports that was done
  11603  *     in coldboot mode.
  11604  * Parameters:
  11605  *      unit - StrataSwitch unit number.
  11606  *      port - Port number of the HL
  11607  *             flexport controlling port.
  11608  * Returns:
  11609  *      BCM_E_XXX
  11610  */
  11611 STATIC int
  11612 _bcm_td2_flexport_recover(int unit, bcm_port_t port)
  11613 {
  11614     soc_info_t *si = &SOC_INFO(unit);
  11615     int i, phy_port, phy_port_base, port_base, lp;
  11616     int mode, phy_port_actived[4];
  11617     uint32 rval;
  11618 
  11619     phy_port      = si->port_l2p_mapping[port];
  11620     phy_port_base = (phy_port & ~0x3) + 1;
  11621     port_base     = si->port_p2l_mapping[phy_port_base];
  11622 
  11623     if (phy_port == -1 || phy_port != phy_port_base) {
  11624         return BCM_E_NONE;
  11625     }
  11626 
  11627     sal_memset(phy_port_actived, 0, sizeof(phy_port_actived));
  11628 
  11629     /* Get the current mode */
  11630     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  11631         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_mode_get(unit, port, &mode));
  11632     } else {
  11633         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval));
  11634         mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  11635                                  XPORT0_CORE_PORT_MODEf);
  11636     }
  11637 
  11638     switch(mode) {
  11639     case SOC_TD2_PORT_MODE_QUAD:
  11640         phy_port_actived[0] =
  11641         phy_port_actived[1] =
  11642         phy_port_actived[2] =
  11643         phy_port_actived[3] = 1;
  11644         break;
  11645     case SOC_TD2_PORT_MODE_TRI_012:
  11646         phy_port_actived[0] =
  11647         phy_port_actived[1] =
  11648         phy_port_actived[2] = 1;
  11649         break;
  11650     case SOC_TD2_PORT_MODE_TRI_023:
  11651         phy_port_actived[0] =
  11652         phy_port_actived[2] =
  11653         phy_port_actived[3] = 1;
  11654         break;
  11655     case SOC_TD2_PORT_MODE_DUAL:
  11656         phy_port_actived[0] =
  11657         phy_port_actived[2] = 1;
  11658         break;
  11659     case SOC_TD2_PORT_MODE_SINGLE:
  11660         phy_port_actived[0] = 1;
  11661         break;
  11662     default:
  11663         return SOC_E_FAIL;
  11664     }
  11665 
  11666     SOC_CONTROL_LOCK(unit);
  11667     for (i = 0; i < 4; i++) {
  11668         lp = si->port_p2l_mapping[phy_port_base + i];
  11669         if (lp != -1 &&
  11670             BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  11671             if (phy_port_actived[i]) {
  11672                 SOC_PBMP_PORT_REMOVE(/* port(s) to be added */
  11673                     SOC_PORT_DISABLED_BITMAP(unit, all), lp);
  11674             } else {
  11675                 SOC_PBMP_PORT_ADD(   /* port(s) to be removed */
  11676                     SOC_PORT_DISABLED_BITMAP(unit, all), lp);
  11677             }
  11678         }
  11679     }
  11680     SOC_CONTROL_UNLOCK(unit);
  11681 
  11682     return SOC_E_NONE;
  11683 }
  11684 #endif /* BCM_TRIDENT2_SUPPORT */
  11685 
  11686 void bcm_esw_port_mdix_wb_update(int unit)
  11687 {
  11688     int p;
  11689     bcm_port_mdix_t mdix;
  11690 
  11691     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  11692        /* Intentionally return value is not checked as this function
  11693         * is called to wb update mdix value for the port, if it exists.
  11694         */
  11695 #ifdef BCM_HURRICANE4_SUPPORT
  11696         if (SOC_IS_HURRICANE4(unit) &&
  11697             !IS_EGPHY_PORT(unit, p)) {
  11698             continue;
  11699         }
  11700 #endif /* BCM_HURRICANE4_SUPPORT */
  11701         bcm_esw_port_mdix_get(unit,p,&mdix);
  11702         LOG_VERBOSE(BSL_LS_BCM_PORT,
  11703                        (BSL_META_U(unit, "Port %d MDIX udate in wb !!\n"), p));
  11704     }
  11705 }
  11706 
  11707 STATIC int
  11708 _bcm_esw_port_wb_recover_scache(int unit, uint16 recovered_ver,
  11709             uint8 *port_state, int stable_size, uint32 asf_wbmem_sz,
  11710             uint32 latency_wbmem_sz, uint32 oamp_status,
  11711             soc_scache_handle_t scache_handle, int *use_pbmp, pbmp_t *port_bitmap,
  11712             bcm_pbmp_t *dtm_pbmp, bcm_pbmp_t *all_pbmp)
  11713 {
  11714     int rv = BCM_E_NONE;
  11715 #if defined(BCM_TRX_SUPPORT)
  11716     bcm_port_t port;
  11717     _bcm_port_info_t *pinfo;
  11718     int realloc_size = 0;
  11719 #ifdef BCM_TRIUMPH2_SUPPORT
  11720 #ifdef BCM_TRIDENT_SUPPORT
  11721         soc_info_t *si = &SOC_INFO(unit);
  11722         int _port_lanes_valid = 0;
  11723 #ifdef BCM_TRIUMPH3_SUPPORT
  11724         int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0};
  11725 #endif /* BCM_TRIUMPH3_SUPPORT */
  11726 #endif /* BCM_TRIDENT_SUPPORT */
  11727 #endif /* BCM_TRIUMPH2_SUPPORT */
  11728 
  11729     PBMP_ITER(*all_pbmp, port) {
  11730         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  11731 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  11732         if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) &&
  11733                 (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) {
  11734             /* Recover vp entry and vlan prot ptr */
  11735             uint32 vlan_protocol_data_index = 0;
  11736             int idxmin, idxmax, vpentry = 0;
  11737             idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  11738             idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  11739 
  11740             sal_memcpy(&vpentry, port_state, sizeof(int));
  11741             port_state += sizeof(int);
  11742 
  11743             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_PBVL,
  11744                             sizeof(int), port_state - sizeof(int)));
  11745 
  11746             if ((vpentry >= idxmin) && (vpentry <= idxmax) &&
  11747                     (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry))) {
  11748                 /* Set as explicit VID */
  11749                 _BCM_PORT_VD_PBVL_SET(pinfo, vpentry);
  11750             }
  11751 
  11752             sal_memcpy(&vlan_protocol_data_index, port_state,
  11753                     sizeof(uint32));
  11754             port_state += sizeof(uint32);
  11755 
  11756             BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port,
  11757                             SPT_VLAN_PROT_PTR,
  11758                             sizeof(uint32), port_state - sizeof(uint32)));
  11759 
  11760             pinfo->vp_count = 0;
  11761             /* update vlan port protocol data memory */
  11762             if (!IS_LB_PORT(unit, port)) {
  11763                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
  11764                             _BCM_CPU_TABS_ETHER,
  11765                             VLAN_PROTOCOL_DATA_INDEXf,
  11766                             vlan_protocol_data_index / 16));
  11767 
  11768                 pinfo->vlan_prot_ptr = vlan_protocol_data_index;
  11769                 BCM_IF_ERROR_RETURN(
  11770                         _bcm_port_vlan_protocol_data_entry_reference (unit,
  11771                             vlan_protocol_data_index, 16));
  11772             }
  11773         }
  11774 #endif
  11775         /* In Apache information is saved and recovered for 76 ports which is
  11776          * greater than SOC_MAX_NUM_PORTS value of 75. These checks are
  11777          * needed to prevent invalid memory access.
  11778          */
  11779         if (port < SOC_MAX_NUM_PORTS) {
  11780             /* Recover VP reference counts */
  11781             sal_memcpy(&(pinfo->vp_count), port_state, sizeof(pinfo->vp_count));
  11782         }
  11783         port_state += sizeof(int);
  11784 
  11785         BCM_IF_ERROR_RETURN(
  11786                 _scache_port_print_add(unit, port, SPT_VP_COUNT, sizeof(int),
  11787                                     port_state - sizeof(int)));
  11788     }
  11789 #ifdef BCM_KATANA2_SUPPORT
  11790     if (SOC_IS_KATANA2(unit) && (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) {
  11791         /* Keep one extra reference to the default profile */
  11792         BCM_IF_ERROR_RETURN(
  11793                 _bcm_port_vlan_protocol_data_entry_reference (unit,
  11794                     0, 16));
  11795     }
  11796 #endif
  11797     /* Recover dtag_mode port bitmap */
  11798     sal_memcpy(dtm_pbmp, port_state, sizeof(bcm_pbmp_t));
  11799     port_state += sizeof(bcm_pbmp_t);
  11800     *use_pbmp = TRUE; /* Cached info available */
  11801 
  11802     BCM_IF_ERROR_RETURN(
  11803             _scache_port_print_add(unit, -1, SPT_DTM_PBMP, sizeof(bcm_pbmp_t),
  11804                                 port_state - sizeof(bcm_pbmp_t)));
  11805 
  11806     if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) {
  11807         PBMP_ITER(*all_pbmp, port) {
  11808             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11809                 /* Recover port tx stop related info */
  11810                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11811                     if (port < SOC_MAX_NUM_PORTS) {
  11812                         sal_memcpy(&(PORT(unit, port).cosmask), port_state,
  11813                                    sizeof(uint32));
  11814                     }
  11815                     port_state += sizeof(uint32);
  11816 
  11817                     BCM_IF_ERROR_RETURN(
  11818                             _scache_port_print_add(unit, port, SPT_COSMASK,
  11819                             sizeof(uint32), port_state - sizeof(uint32)));
  11820                 } else {
  11821                     if (port < SOC_MAX_NUM_PORTS) {
  11822                         sal_memcpy(&(PORT(unit, port).m_info), port_state,
  11823                                    sizeof(_bcm_port_metering_info_t));
  11824                     }
  11825                     port_state += sizeof(_bcm_port_metering_info_t);
  11826 
  11827                     BCM_IF_ERROR_RETURN(
  11828                             _scache_port_print_add(unit, port, SPT_METERING_INFO,
  11829                                             sizeof(_bcm_port_metering_info_t),
  11830                             port_state - sizeof(_bcm_port_metering_info_t)));
  11831                 }
  11832                 if (port < SOC_MAX_NUM_PORTS) {
  11833                     /* Recover flags */
  11834                     sal_memcpy(&(PORT(unit, port).flags), port_state, sizeof(uint8));
  11835                 }
  11836                 port_state += sizeof(uint8);
  11837 
  11838                 BCM_IF_ERROR_RETURN(
  11839                         _scache_port_print_add(unit, port, SPT_PORT_FLAGS, sizeof(uint8),
  11840                         port_state - sizeof(uint8)));
  11841             }
  11842         }
  11843 #if defined(BCM_TOMAHAWK_SUPPORT)
  11844         if (SOC_IS_TOMAHAWK(unit)) {
  11845             PBMP_ALL_ITER(unit, port) {
  11846                 BCM_IF_ERROR_RETURN(soc_th_port_speed_recover(unit, port));
  11847             }
  11848         }
  11849 #endif
  11850 #ifdef BCM_TRIDENT_SUPPORT
  11851         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  11852             soc_feature(unit, soc_feature_flex_port)) {
  11853             int num_lanes = 0;
  11854             if (SOC_IS_TD_TT(unit)) {
  11855                 PBMP_ALL_ITER(unit, port) {
  11856                     sal_memcpy(&num_lanes, port_state, sizeof(int));
  11857                     port_state += sizeof(int);
  11858 
  11859                     BCM_IF_ERROR_RETURN(
  11860                             _scache_port_print_add(unit, port, SPT_PORT_NUM_LANES,
  11861                             sizeof(int), port_state - sizeof(int)));
  11862 #ifdef BCM_HURRICANE4_SUPPORT
  11863                     if (SOC_IS_HURRICANE4(unit) &&
  11864                         (IS_MACSEC_PORT(unit, port) ||
  11865                         IS_LB_PORT(unit,port))) {
  11866                         continue;
  11867                     }
  11868 #endif
  11869                     if (si->port_num_lanes[port] != num_lanes) {
  11870 #if defined(BCM_TOMAHAWK_SUPPORT)
  11871                         if (SOC_IS_TOMAHAWK(unit)) {
  11872                            BCM_IF_ERROR_RETURN(
  11873                                    soc_th_flexport_recover(unit, port));
  11874                         }
  11875 #endif /* BCM_TOMAHAWK_SUPPORT */
  11876 #ifdef BCM_TRIDENT2_SUPPORT
  11877                         if (SOC_IS_TD2_TT2(unit) &&
  11878                            (!(SOC_IS_TD2P_TT2P(unit) ||
  11879                               SOC_IS_APACHE(unit) ||
  11880                               SOC_IS_TOMAHAWK2(unit)))) {
  11881                             BCM_IF_ERROR_RETURN(
  11882                                     _bcm_td2_flexport_recover(unit, port));
  11883                         }
  11884 #endif /* BCM_TRIDENT2_SUPPORT */
  11885                         si->port_num_lanes[port] = num_lanes;
  11886                         _port_lanes_valid++;
  11887                     }
  11888                 }
  11889             }
  11890 #ifdef BCM_TRIUMPH3_SUPPORT
  11891             else if (SOC_IS_TRIUMPH3(unit)) {
  11892                 PBMP_ALL_ITER(unit, port) {
  11893                     sal_memcpy(&_port_num_lanes[port], port_state,
  11894                                sizeof(int));
  11895                     port_state += sizeof(int);
  11896                     _port_lanes_valid++;
  11897                 }
  11898             }
  11899 #endif /* BCM_TRIUMPH2_SUPPORT */
  11900             if (SOC_IS_TD_TT(unit) && (_port_lanes_valid > 0)) {
  11901                 /* Call PHY probe for flex port config to take effect */
  11902                 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit),
  11903                        port_bitmap)) != BCM_E_NONE) {
  11904                     LOG_ERROR(BSL_LS_BCM_PORT, \
  11905                               (BSL_META_U(unit, \
  11906                                           "Error unit %d:\
  11907                                           Failed port probe: %s\n"),
  11908                                unit, bcm_errmsg(rv)));
  11909                     return rv;
  11910                 }
  11911             }
  11912         }
  11913 #endif /* BCM_TRIDENT_SUPPORT */
  11914     } else {
  11915         PBMP_ITER(*all_pbmp, port) {
  11916             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11917                 /* Recover port tx stop related info */
  11918                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11919                     realloc_size += sizeof(uint32);
  11920                 } else {
  11921                     realloc_size += sizeof(_bcm_port_metering_info_t);
  11922                 }
  11923                 /* Recover flags */
  11924                 realloc_size += sizeof(uint8);
  11925             }
  11926         }
  11927     }
  11928 
  11929     if (recovered_ver >= BCM_PORT_WB_VERSION_1_2) {
  11930         uint8 rx_los = 0;
  11931         PBMP_ITER(*all_pbmp, port) {
  11932 #if defined(BCM_SABER2_SUPPORT)
  11933             if(SOC_IS_SABER2(unit)) {
  11934                 if ((port == SOC_SB2_SAT_OAMP_PHY_PORT_NUMBER) && (oamp_status == 1)){
  11935                     continue;
  11936                 }
  11937             }
  11938 #endif
  11939             /* Recover RX_LOS */
  11940             rx_los = *port_state;
  11941             port_state += sizeof(uint8);
  11942 
  11943             BCM_IF_ERROR_RETURN(
  11944                     _scache_port_print_add(unit, port, SPT_RX_LOS, sizeof(uint8),
  11945                     port_state - sizeof(uint8)));
  11946 
  11947             if (IS_E_PORT(unit, port)) {
  11948                 /* Call PHY control for RX_lOS config to take effect */
  11949                 if (rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_NONE ||
  11950                     rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_SOFTWARE) {
  11951 
  11952                     if (!soc_feature(unit, soc_feature_no_sw_rx_los)){
  11953                         rv = bcm_esw_port_phy_control_set(unit, port,
  11954                         BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los);
  11955                         if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
  11956                             LOG_ERROR(BSL_LS_BCM_PORT,
  11957                                   (BSL_META_U(unit,
  11958                                               "Error unit %d: "
  11959                                               "Failed port phy control set: %s\n"),
  11960                                    unit, bcm_errmsg(rv)));
  11961                             return rv;
  11962                         }
  11963                     }
  11964                 }
  11965             }
  11966         }
  11967     } else {
  11968         PBMP_ITER(*all_pbmp, port) {
  11969             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11970                 && (stable_size > 0)) {
  11971                 /* Recover SW RX LOS status */
  11972                 realloc_size += sizeof(uint8);
  11973             }
  11974         }
  11975     }
  11976 
  11977 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT)
  11978     if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) {
  11979         if (recovered_ver >= BCM_PORT_WB_VERSION_1_3) {
  11980             PBMP_ITER(*all_pbmp, port) {
  11981                 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11982                     && (stable_size > 0)) {
  11983                     if (port < SOC_MAX_NUM_PORTS) {
  11984                         /* Recover port enable status */
  11985                         sal_memcpy(&(PORT(unit, port).enable),
  11986                                    port_state, sizeof(int));
  11987                     }
  11988                     port_state += sizeof(int);
  11989 
  11990                     BCM_IF_ERROR_RETURN(
  11991                             _scache_port_print_add(unit, port, SPT_PORT_ENABLE,
  11992                             sizeof(int), port_state - sizeof(int)));
  11993                 }
  11994             }
  11995         } else {
  11996             PBMP_ITER(*all_pbmp, port) {
  11997                 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11998                     && (stable_size > 0)) {
  11999                     /* Recover SW port enable status */
  12000                     realloc_size += sizeof(int);
  12001                 }
  12002             }
  12003         }
  12004     }
  12005 #endif /* BCM_TRIDENT2_SUPPORT */
  12006 #ifdef BCM_TRIUMPH3_SUPPORT
  12007     if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  12008         if ((recovered_ver >= BCM_PORT_WB_VERSION_1_4) && _port_ibod_ctrl[unit]) {
  12009             sal_memcpy(_port_ibod_ctrl[unit]->rrbyt, port_state,
  12010                     sizeof(((_port_ibod_ctrl_t *)0)->rrbyt));
  12011             port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  12012             sal_memcpy(_port_ibod_ctrl[unit]->rrpkt, port_state,
  12013                     sizeof(((_port_ibod_ctrl_t *)0)->rrpkt));
  12014             port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  12015             sal_memcpy(&(_port_ibod_ctrl[unit]->event_count), port_state,
  12016                     sizeof(((_port_ibod_ctrl_t *)0)->event_count));
  12017             port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  12018         } else {
  12019             realloc_size +=  sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  12020             realloc_size +=  sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  12021             realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  12022         }
  12023     }
  12024     /*
  12025      * Recover the port force forward information from scache.
  12026      * If the recovered version is lower than 1.5, allocate
  12027      * space in scache for any further sync.
  12028      */
  12029     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  12030        if (recovered_ver >= BCM_PORT_WB_VERSION_1_5) {
  12031            BCM_IF_ERROR_RETURN(
  12032                    _bcm_port_force_forward_reinit(unit, &port_state));
  12033        } else {
  12034            bcm_port_t egr_port;
  12035            int enabled = 0;
  12036            int port_forward_size = 0;
  12037            PBMP_ITER(*all_pbmp, port) {
  12038               BCM_IF_ERROR_RETURN(
  12039                       bcm_esw_port_force_forward_get(unit, port,
  12040                                            &egr_port, &enabled));
  12041               if (enabled) {
  12042                   _bcm_port_force_forward_add(unit, port,
  12043                           egr_port);
  12044               }
  12045            }
  12046            BCM_IF_ERROR_RETURN(_bcm_port_force_forward_scache_size(unit,
  12047                                 &port_forward_size));
  12048            realloc_size += port_forward_size;
  12049        }
  12050     }
  12051 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  12052 
  12053 #ifdef  BCM_TOMAHAWK_SUPPORT
  12054     if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) {
  12055         /* ASF WB Recovery */
  12056         rv = _bcm_esw_asf_wb_recover(unit, port_state, recovered_ver);
  12057         if (BCM_E_NONE != rv) {
  12058             LOG_ERROR(BSL_LS_BCM_PORT, \
  12059                       (BSL_META_U(unit, \
  12060                                   "Error unit %d:\
  12061                                   ASF Warmboot Recovery Failed: %s\n"), \
  12062                        unit, bcm_errmsg(rv)));
  12063             return rv;
  12064         }
  12065         port_state += asf_wbmem_sz;
  12066 
  12067         BCM_IF_ERROR_RETURN(
  12068             _scache_port_print_add(unit, -1, SPT_ASF, asf_wbmem_sz,
  12069             port_state - asf_wbmem_sz));
  12070     }
  12071 
  12072     if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) {
  12073         /* Switch Latency Bypass WB Recovery */
  12074         rv = bcmi_esw_switch_latency_wb_recover(unit, port_state, recovered_ver);
  12075         if (BCM_E_NONE != rv) {
  12076             LOG_ERROR(BSL_LS_BCM_PORT, \
  12077                       (BSL_META_U(unit, \
  12078                                   "Error unit %d:\
  12079                                   Switch Latency Bypass \
  12080                                   Warmboot Recovery Failed: %s\n"), \
  12081                        unit, bcm_errmsg(rv)));
  12082             return rv;
  12083         }
  12084         port_state += latency_wbmem_sz;
  12085 
  12086         BCM_IF_ERROR_RETURN(
  12087             _scache_port_print_add(unit, -1, SPT_LATENCY, latency_wbmem_sz,
  12088             port_state - latency_wbmem_sz));
  12089     }
  12090 
  12091     /* sflow WB recovery */
  12092     rv = _bcm_esw_sflow_wb_recover(unit);
  12093     if (BCM_E_NONE != rv) {
  12094         LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit, "Error \
  12095               unit %d: sflow Warmboot Recovery Failed: %s\n"), unit,
  12096               bcm_errmsg(rv)));
  12097         return rv;
  12098     }
  12099 #endif /* BCM_TOMAHAWK_SUPPORT */
  12100     /*IFG WB*/
  12101     if (soc_feature(unit, soc_feature_xmac) ||
  12102             soc_feature(unit, soc_feature_xlmac) ||
  12103             soc_feature(unit, soc_feature_cmac) ||
  12104             soc_feature(unit, soc_feature_clmac)) {
  12105         if (recovered_ver >= BCM_PORT_WB_VERSION_1_7) {
  12106             BCM_IF_ERROR_RETURN(
  12107                     _bcm_esw_port_ifg_wb_reinit(unit, &port_state));
  12108         } else {
  12109             PBMP_ITER(*all_pbmp, port) {
  12110                 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  12111                     && (stable_size > 0)) {
  12112                     realloc_size += sizeof(uint32);
  12113                 }
  12114             }
  12115         }
  12116     }
  12117     /* PORT DSCP MAP SETTING */
  12118     if (soc_feature(unit, soc_feature_dscp) &&
  12119         soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  12120         if (recovered_ver >= BCM_PORT_WB_VERSION_1_11) {
  12121             PBMP_ITER(*all_pbmp, port) {
  12122                 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  12123                     && (stable_size > 0)) {
  12124                     /* Recover port dscp map status */
  12125                     sal_memcpy(&(PORT(unit, port).port_dscp_map_set),
  12126                                 port_state, sizeof(int));
  12127                     port_state += sizeof(int);
  12128 
  12129                     BCM_IF_ERROR_RETURN(
  12130                             _scache_port_print_add(unit, port, SPT_DSCP_MAP,
  12131                             sizeof(int), port_state - sizeof(int)));
  12132 
  12133                     if (PORT(unit, port).port_dscp_map_set) {
  12134                         BCM_IF_ERROR_RETURN(
  12135                                 _bcm_egr_dscp_table_entry_reference(
  12136                                 unit, port * _BCM_QOS_MAP_CHUNK_EGR_DSCP,
  12137                                 _BCM_QOS_MAP_CHUNK_EGR_DSCP));
  12138                     }
  12139                 }
  12140             }
  12141         } else {
  12142             PBMP_ITER(*all_pbmp, port) {
  12143                 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  12144                     && (stable_size > 0)) {
  12145                     /* Recover SW port dscp map status */
  12146                     realloc_size += sizeof(int);
  12147                 }
  12148             }
  12149         }
  12150     }
  12151 
  12152 #ifdef  BCM_TOMAHAWK_SUPPORT
  12153     if (SOC_IS_TOMAHAWK(unit) && recovered_ver >= BCM_PORT_WB_VERSION_1_12) {
  12154         /* Recover port interface type */
  12155         int pif;
  12156         PBMP_ITER(*all_pbmp, port) {
  12157             if (IS_XE_PORT(unit, port) ||
  12158                 IS_CE_PORT(unit, port) ||
  12159                 IS_HG_PORT(unit, port) ||
  12160                 IS_GE_PORT(unit, port) ||
  12161                 IS_MANAGEMENT_PORT(unit, port)) {
  12162 
  12163                 sal_memcpy(&pif, port_state, sizeof(int));
  12164                 port_state += sizeof(int);
  12165 
  12166                 BCM_IF_ERROR_RETURN(
  12167                         _scache_port_print_add(unit, port, SPT_PORT_INTF_TYPE,
  12168                             sizeof(int), port_state - sizeof(int)));
  12169 
  12170                 BCM_IF_ERROR_RETURN(soc_phyctrl_interface_set(unit, port, pif));
  12171             }
  12172         }
  12173     }
  12174 #endif /* BCM_TOMAHAWK_SUPPORT */
  12175     if (soc_feature(unit, soc_feature_phy_interface_wb) &&
  12176         (recovered_ver >= BCM_PORT_WB_VERSION_1_13)) {
  12177         /* Recover port interface type */
  12178         int pif;
  12179 
  12180         PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  12181             sal_memcpy(&pif, port_state, sizeof(int));
  12182             port_state += sizeof(int);
  12183 
  12184             BCM_IF_ERROR_RETURN(
  12185                     _scache_port_print_add(unit, port, SPT_PORT_INTF_TYPE,
  12186                     sizeof(int), port_state - sizeof(int)));
  12187 
  12188             if (pif) {
  12189                 BCM_IF_ERROR_RETURN(
  12190                         soc_phyctrl_interface_set(unit, port, pif));
  12191             }
  12192         }
  12193     }
  12194 
  12195     if (realloc_size > 0) {
  12196        BCM_IF_ERROR_RETURN(
  12197                soc_scache_realloc(unit, scache_handle, realloc_size));
  12198     }
  12199 #endif /* BCM_TRX_SUPPORT */
  12200 
  12201     return rv;
  12202 }
  12203 
  12204 int
  12205 _bcm_esw_port_wb_recover(int unit)
  12206 {
  12207     int rv = BCM_E_NONE;
  12208 
  12209 #if defined(BCM_TRX_SUPPORT)
  12210     if (SOC_IS_TRX(unit)) {
  12211         int alloc_sz, use_pbmp = FALSE;
  12212         uint8 *port_state;
  12213         uint16 recovered_ver;
  12214         bcm_port_t port;
  12215         bcm_pbmp_t dtm_pbmp;
  12216         int stable_size;
  12217         soc_scache_handle_t scache_handle;
  12218         uint32 oamp_status = 0;
  12219 #if defined(BCM_SABER2_SUPPORT)
  12220         uint32 rval = 0;
  12221 #endif
  12222         pbmp_t port_bitmap;
  12223         bcm_pbmp_t all_pbmp;
  12224         uint32 asf_wbmem_sz = 0;
  12225         /* Switch Latency Bypass WB will move to a different module later */
  12226         uint32 latency_wbmem_sz = 0;
  12227 #ifdef  BCM_TOMAHAWK_SUPPORT
  12228         uint16 scache_ver = BCM_PORT_WB_DEFAULT_VERSION;
  12229 
  12230 #endif
  12231 
  12232         BCM_PBMP_CLEAR(all_pbmp);
  12233         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12234 
  12235         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  12236                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  12237         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  12238                                      0, (uint8**)&port_state,
  12239                                      BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  12240         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  12241             return rv;
  12242         }
  12243 
  12244 #if defined(BCM_SABER2_SUPPORT)
  12245         if(SOC_IS_SABER2(unit)) {
  12246             SOC_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &rval));
  12247             oamp_status = soc_reg_field_get(unit, OAMP_ENABLEr, rval, ENABLEf);
  12248         }
  12249 #endif
  12250 #ifdef BCM_KATANA2_SUPPORT
  12251         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12252 #if defined(BCM_SABER2_SUPPORT)
  12253             if ( SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) &&
  12254                 (recovered_ver < BCM_PORT_WB_VERSION_1_10) ) {
  12255                 BCM_IF_ERROR_RETURN(_bcm_sb2_wb_v1_flexio_pbmp_update(unit, &all_pbmp));
  12256             } else
  12257 #endif
  12258             {
  12259                 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12260 #if defined(BCM_SABER2_SUPPORT)
  12261                 bcm_sb2_wb_v2_flexio_update = 1;
  12262 #endif
  12263             }
  12264         }
  12265         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12266             soc_feature(unit, soc_feature_subtag_coe)) {
  12267             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12268         }
  12269 #endif
  12270 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12271         if (SOC_IS_TD2P_TT2P(unit)) {
  12272             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  12273                                                  &all_pbmp));
  12274         }
  12275 #endif
  12276 #ifdef BCM_MONTEREY_SUPPORT
  12277         if (SOC_IS_MONTEREY(unit)) {
  12278             BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  12279         }
  12280 #endif
  12281 #ifdef BCM_APACHE_SUPPORT
  12282         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  12283             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  12284         }
  12285 #endif
  12286 
  12287         alloc_sz = 0;
  12288         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  12289         PBMP_ITER(all_pbmp, port) {
  12290 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  12291             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  12292                 /* vp entry and vlan prot ptr */
  12293                 alloc_sz += (sizeof(int) + sizeof(uint32));
  12294             }
  12295 #endif
  12296             alloc_sz += sizeof(int); /* vp count */
  12297         }
  12298         alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  12299         PBMP_ITER(all_pbmp, port) {
  12300             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  12301                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  12302                     alloc_sz += sizeof(uint32);
  12303                 } else {
  12304                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  12305                 }
  12306                 alloc_sz += sizeof(uint8);
  12307             }
  12308         }
  12309 
  12310 #ifdef BCM_TRIDENT_SUPPORT
  12311         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  12312             soc_feature(unit, soc_feature_flex_port)) {
  12313             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  12314         }
  12315 #endif
  12316 
  12317         /* Restore SW RX LOS status */
  12318         PBMP_ITER(all_pbmp, port) {
  12319             alloc_sz += sizeof(uint8);
  12320         }
  12321 
  12322 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT)
  12323         if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) {
  12324             /* Allocate size for port enable status */
  12325             PBMP_ITER(all_pbmp, port) {
  12326                 alloc_sz += sizeof(int);
  12327             }
  12328         }
  12329 #endif /* BCM_TRIDENT2_SUPPORT */
  12330 #ifdef BCM_TRIUMPH3_SUPPORT
  12331         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  12332             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  12333                             + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  12334         }
  12335 #endif /* BCM_TRIUMPH3_SUPPORT */
  12336 #if defined(BCM_TRIUMPH3_SUPPORT)
  12337         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  12338             int port_forward_size;
  12339             BCM_IF_ERROR_RETURN(
  12340                 _bcm_port_force_forward_scache_size(unit, &port_forward_size));
  12341             alloc_sz += port_forward_size;
  12342         }
  12343 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  12344 
  12345 #ifdef  BCM_TOMAHAWK_SUPPORT
  12346         if (SOC_WARM_BOOT(unit)) {
  12347             BCM_IF_ERROR_RETURN(
  12348                 bcm_esw_scache_ver_get(unit, BCM_MODULE_PORT, &scache_ver));
  12349         }
  12350         /* ASF WB */
  12351         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, scache_ver);
  12352         if (BCM_E_NONE == rv) {
  12353             alloc_sz += asf_wbmem_sz;
  12354         }
  12355 
  12356         /* Switch Latency Bypass WB */
  12357         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  12358                                                   scache_ver);
  12359         if (BCM_E_NONE == rv) {
  12360             alloc_sz += latency_wbmem_sz;
  12361         }
  12362 #endif /* BCM_TOMAHAWK_SUPPORT */
  12363 
  12364         /*IFG WB*/
  12365         if (soc_feature(unit, soc_feature_xmac) ||
  12366                 soc_feature(unit, soc_feature_xlmac) ||
  12367                 soc_feature(unit, soc_feature_cmac) ||
  12368                 soc_feature(unit, soc_feature_clmac)) {
  12369             PBMP_ITER(all_pbmp, port) {
  12370                 alloc_sz += sizeof(uint32);
  12371             }
  12372         }
  12373         /* PORT DSCP MAP SETTING */
  12374         if (soc_feature(unit, soc_feature_dscp) &&
  12375             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  12376             /* Allocate size for port dscp map setting status */
  12377             PBMP_ITER(all_pbmp, port) {
  12378                 alloc_sz += sizeof(int);
  12379             }
  12380         }
  12381 
  12382 #ifdef  BCM_TOMAHAWK_SUPPORT
  12383         if (SOC_IS_TOMAHAWK(unit)) {
  12384             /* Allocate size for port interface type */
  12385             PBMP_ITER(all_pbmp, port) {
  12386                 alloc_sz += sizeof(int);
  12387             }
  12388         }
  12389 #endif /* BCM_TOMAHAWK_SUPPORT */
  12390 
  12391         if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  12392             /* Allocate size for port interface type */
  12393             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  12394                 alloc_sz += sizeof(int);
  12395             }
  12396         }
  12397 
  12398         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  12399                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  12400         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  12401                                      alloc_sz, (uint8**)&port_state,
  12402                                      BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  12403         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  12404             return rv;
  12405         }
  12406         if (BCM_SUCCESS(rv)) {
  12407             _scache_port_print_ll_init(unit);
  12408 
  12409             rv = _bcm_esw_port_wb_recover_scache(unit, recovered_ver, port_state,
  12410                     stable_size, asf_wbmem_sz, latency_wbmem_sz, oamp_status,
  12411                     scache_handle, &use_pbmp, &port_bitmap, &dtm_pbmp, &all_pbmp);
  12412 
  12413             if (BCM_SUCCESS(rv) || rv == BCM_E_UNAVAIL) {
  12414                 _scache_port_print_all(unit);
  12415             }
  12416             _scache_port_print_clear_all(unit);
  12417 
  12418             if (BCM_FAILURE(rv) && rv != BCM_E_UNAVAIL) {
  12419                 return rv;
  12420             }
  12421         } else {
  12422             /*
  12423              * No level-2 cache configured. Proceed to Level-1 only recovery
  12424              */
  12425             BCM_PBMP_CLEAR(dtm_pbmp); /* Default is dtag_mode == NONE */
  12426 #if defined(BCM_TRIUMPH3_SUPPORT)
  12427             if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  12428                 bcm_port_t egr_port;
  12429                 int enabled = 0;
  12430 
  12431                 PBMP_ITER(all_pbmp, port) {
  12432                     SOC_IF_ERROR_RETURN
  12433                         (bcm_esw_port_force_forward_get(unit, port,
  12434                                                 &egr_port, &enabled));
  12435                     if (enabled) {
  12436                         _bcm_port_force_forward_add(unit, port,
  12437                                                 egr_port);
  12438                     }
  12439                 }
  12440             }
  12441 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  12442         }
  12443 
  12444 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \
  12445     defined(BCM_KATANA2_SUPPORT)
  12446         if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit) ||
  12447             SOC_IS_TRIDENT3X(unit) || SOC_IS_KATANA2(unit)) {
  12448             /* Recover port vlan action profile */
  12449             rv = _bcm_th_port_vlan_action_profile_reinit(unit);
  12450             if (BCM_FAILURE(rv)) {
  12451                 return rv;
  12452             }
  12453         }
  12454 #endif
  12455 
  12456         /* Recover DT mode */
  12457         rv = _bcm_trx_port_dtag_mode_reinit(unit, dtm_pbmp, use_pbmp);
  12458         if (BCM_FAILURE(rv)) {
  12459             return rv;
  12460         }
  12461 #ifdef BCM_TRIUMPH2_SUPPORT
  12462         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  12463             /* Recover ING_PRI_CNG_MAP references */
  12464             port_tab_entry_t pent;
  12465             int ptr;
  12466             uint32 ipc_ref_bmp[3];
  12467             /* Required: ING_PRI_CNG_MAP size <= 3 * 32 * 16 = 1536 */
  12468 
  12469             SHR_BITCLR_RANGE(ipc_ref_bmp, 0, 3*32);
  12470 
  12471             /* Read port pointer, recover reference count */
  12472             PBMP_ITER(all_pbmp, port) {
  12473 #ifdef BCM_TRIDENT3_SUPPORT
  12474                 if (SOC_IS_TRIDENT3X(unit)) {
  12475                     rv = _bcm_esw_port_tab_get(unit, port,
  12476                                                TRUST_DOT1P_PTRf, &ptr);
  12477                     if (BCM_FAILURE(rv)) {
  12478                         break;
  12479                     }
  12480                     if (0 != ptr) {
  12481                         rv = _bcm_ing_pri_cng_map_entry_reference(unit,
  12482                                 ptr * _BCM_TD3_PRI_CNG_MAP_SIZE,
  12483                                 _BCM_TD3_PRI_CNG_MAP_SIZE);
  12484                         if (BCM_FAILURE(rv)) {
  12485                             break;
  12486                         }
  12487                     }
  12488 
  12489                     /* Recover PROTOCOL_PKT_CONTROL &
  12490                      * IGMP_MLD_PKT_CONTROL references */
  12491                     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  12492                         soc_portreg) {
  12493                         /* Memory not allocated so no need to proceed */
  12494                         continue;
  12495                     }
  12496                     rv = _bcm_esw_port_tab_get(unit, port,
  12497                                                PROTOCOL_PKT_INDEXf, &ptr);
  12498                     if (BCM_FAILURE(rv)) {
  12499                         break;
  12500                     }
  12501                     if (0 != ptr) {
  12502                         rv = _bcm_prot_pkt_ctrl_reference(unit, ptr);
  12503                         if (BCM_FAILURE(rv)) {
  12504                             break;
  12505                         }
  12506                         /* Remove default reference */
  12507                         rv = _bcm_prot_pkt_ctrl_delete(unit, 0);
  12508                         if (BCM_FAILURE(rv)) {
  12509                             break;
  12510                         }
  12511                     }
  12512                 } else
  12513 #endif
  12514                 {
  12515                 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  12516                                   SOC_PORT_MOD_OFFSET(unit, port), &pent);
  12517                 if (BCM_FAILURE(rv)) {
  12518                     break;
  12519                 }
  12520                 if (soc_feature(unit, soc_feature_color)) {
  12521                     ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12522                                                     TRUST_DOT1P_PTRf);
  12523                     if (0 != ptr) {
  12524                         rv = _bcm_ing_pri_cng_map_entry_reference(unit,
  12525                                   ptr * _BCM_TR2_PRI_CNG_MAP_SIZE,
  12526                                         _BCM_TR2_PRI_CNG_MAP_SIZE);
  12527                         if (BCM_FAILURE(rv)) {
  12528                             break;
  12529                         }
  12530                     }
  12531                 }
  12532 
  12533                 /* Recover PROTOCOL_PKT_CONTROL &
  12534                  * IGMP_MLD_PKT_CONTROL references */
  12535                 if (soc_mem_field_valid(unit, PORT_TABm,
  12536                                         PROTOCOL_PKT_INDEXf)) {
  12537                     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  12538                         soc_portreg) {
  12539                         /* ========================================== */
  12540                         /* Memory not allocated so no need to proceed */
  12541                         /* if (SOC_IS_HURRICANE(unit))                */
  12542                         /* ========================================== */
  12543                         continue;
  12544                     }
  12545                     ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12546                                                     PROTOCOL_PKT_INDEXf);
  12547                     if (0 != ptr) {
  12548                         rv = _bcm_prot_pkt_ctrl_reference(unit, ptr);
  12549                         if (BCM_FAILURE(rv)) {
  12550                             break;
  12551                         }
  12552                         /* Remove default reference */
  12553                         rv = _bcm_prot_pkt_ctrl_delete(unit, 0);
  12554                         if (BCM_FAILURE(rv)) {
  12555                             break;
  12556                         }
  12557                     }
  12558                 }
  12559             }
  12560         }
  12561         }
  12562         if (BCM_FAILURE(rv)) {
  12563             return rv;
  12564         }
  12565 #endif /* BCM_TRIUMPH2_SUPPORT */
  12566 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12567         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  12568             port_tab_entry_t pent;
  12569             int ptr;
  12570             PBMP_ITER(all_pbmp, port) {
  12571                 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  12572                                   SOC_PORT_MOD_OFFSET(unit, port), &pent);
  12573                 if (BCM_FAILURE(rv)) {
  12574                     break;
  12575                 }
  12576                 ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12577                                                      MISC_PORT_PROFILE_INDEXf);
  12578                 if (0 != ptr) {
  12579                    rv  = _bcm_misc_port_profile_mem_reference(unit, ptr, 1);
  12580                    if (BCM_FAILURE(rv)) {
  12581                       break;
  12582                    }
  12583                }
  12584            }
  12585         }
  12586         if (BCM_FAILURE(rv)) {
  12587             return rv;
  12588         }
  12589 #endif
  12590 
  12591         if (soc_feature(unit, soc_feature_e2ecc)) {
  12592             rv = _bcm_esw_port_e2ecc_reinit(unit);
  12593         }
  12594         if (BCM_FAILURE(rv)) {
  12595             return rv;
  12596         }
  12597 
  12598 #ifdef BCM_TRIUMPH2_SUPPORT
  12599         /* Recover source modid egress blocking profiles */
  12600         if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  12601             uint32 regval, srcmod_index;
  12602             int i, modid_count;
  12603 
  12604             modid_count = SOC_MODID_MAX(unit) + 1;
  12605 
  12606             PBMP_ITER(all_pbmp, port) {
  12607                 BCM_IF_ERROR_RETURN
  12608                     (READ_SRC_MODID_EGRESS_SELr(unit, port, &regval));
  12609                 if (soc_reg_field_get(unit,
  12610                             SRC_MODID_EGRESS_SELr, regval, ENABLEf)) {
  12611                     srcmod_index = soc_reg_field_get(unit,
  12612                             SRC_MODID_EGRESS_SELr, regval, SRCMOD_INDEXf);
  12613                     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = srcmod_index;
  12614                     srcmod_index *= modid_count;
  12615                     for (i = 0; i < modid_count; i++) {
  12616                         SOC_PROFILE_MEM_REFERENCE(unit,
  12617                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  12618                                                   srcmod_index + i, 1);
  12619                         SOC_PROFILE_MEM_ENTRIES_PER_SET(unit,
  12620                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  12621                                                         srcmod_index + i,
  12622                                                         modid_count);
  12623                     }
  12624                 }
  12625             }
  12626         }
  12627 #endif /* BCM_TRIUMPH2_SUPPORT */
  12628 
  12629 #ifdef BCM_TRIUMPH2_SUPPORT
  12630         if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  12631              SOC_IS_VALKYRIE2(unit)) &&
  12632             soc_feature(unit, soc_feature_flex_port)) {
  12633             PBMP_ALL_ITER(unit, port) {
  12634                 if (_bcm_esw_valid_flex_port_controlling_port(unit, port)) {
  12635                     BCM_IF_ERROR_RETURN(_bcm_tr2_flexport_recover(unit, port));
  12636                 }
  12637             }
  12638             /* Call PHY probe for config to take effect */
  12639             if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit),
  12640                    &port_bitmap)) != BCM_E_NONE) {
  12641                 LOG_ERROR(BSL_LS_BCM_PORT, \
  12642                           (BSL_META_U(unit, \
  12643                                       "Error unit %d:\
  12644                                       Failed port probe: %s\n"),
  12645                            unit, bcm_errmsg(rv)));
  12646                 return rv;
  12647             }
  12648         }
  12649 #endif /* BCM_TRIUMPH2_SUPPORT */
  12650 
  12651 #if defined(BCM_GREYHOUND_SUPPORT)
  12652         if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  12653             /*
  12654              * Recover the ref_cnt of enabling treat packet priority as
  12655              * dot1p priority for different packet types or port controls,
  12656              * if available.
  12657              */
  12658             rv = bcmi_esw_port_treat_pktpri_as_dot1p_reinit(unit);
  12659             if (BCM_FAILURE(rv)) {
  12660                 return rv;
  12661             }
  12662         }
  12663 #endif /* BCM_GREYHOUND_SUPPORT */
  12664 
  12665         if (SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH2(unit) || \
  12666                 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit) || \
  12667                 SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || \
  12668                 SOC_IS_VALKYRIE(unit) || SOC_IS_HURRICANE4(unit)) {
  12669             bcm_esw_port_mdix_wb_update(unit);
  12670         }
  12671     }
  12672 #endif /* BCM_TRX_SUPPORT */
  12673 #if defined(BCM_RAVEN_SUPPORT)
  12674     if (SOC_IS_RAVEN(unit)) {
  12675         bcm_esw_port_mdix_wb_update(unit);
  12676     }
  12677 #endif /* BCM_RAVEN_SUPPORT */
  12678 #ifdef BCM_PREEMPTION_SUPPORT
  12679     if (soc_feature(unit, soc_feature_preemption)) {
  12680         soc_scache_handle_t scache_handle;
  12681 
  12682         SOC_SCACHE_HANDLE_SET(scache_handle,
  12683                               unit, BCM_MODULE_PORT,
  12684                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  12685         rv = bcmi_esw_preemption_recover(unit, scache_handle);
  12686         if (BCM_FAILURE(rv)) {
  12687             return rv;
  12688         }
  12689     }
  12690 #endif /* BCM_PREEMPTION_SUPPORT */
  12691 
  12692     return rv;
  12693 }
  12694 #else
  12695 #define _bcm_port_vd_pbvl_reinit(u)  (BCM_E_NONE)
  12696 #define _bcm_esw_port_wb_recover(u)  (BCM_E_NONE)
  12697 #define _bcm_esw_port_wb_alloc(u) (BCM_E_NONE)
  12698 #endif /* BCM_WARM_BOOT_SUPPORT */
  12699 
  12700 #ifndef BCM_SW_STATE_DUMP_DISABLE
  12701 /*
  12702  * Function:
  12703  *     _bcm_esw_flexport_sw_dump
  12704  * Purpose:
  12705  *     Displays port information after flexport.
  12706  * Parameters:
  12707  *     unit - Device unit number
  12708  * Returns:
  12709  *     None
  12710  * Note:
  12711  */
  12712 void
  12713 _bcm_esw_flexport_sw_dump(int unit)
  12714 {
  12715 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  12716     if (SOC_IS_TRIDENT2PLUS(unit)) {
  12717         soc_flexport_sw_dump(unit);
  12718     }
  12719 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  12720 
  12721 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12722     if (SOC_IS_TOMAHAWK3(unit)) {
  12723         soc_th3_flexport_sw_dump(unit);
  12724     }
  12725 #endif /* BCM_TOMAHAWK3_SUPPORT */
  12726 
  12727 #if defined(BCM_TOMAHAWK2_SUPPORT)
  12728     if (SOC_IS_TOMAHAWK2(unit)) {
  12729         soc_th2_flexport_sw_dump(unit);
  12730     }
  12731 #endif /* BCM_TOMAHAWK2_SUPPORT */
  12732 
  12733 #if defined(BCM_TOMAHAWK_SUPPORT)
  12734     if (SOC_IS_TOMAHAWK(unit)) {
  12735         soc_th_flexport_sw_dump(unit);
  12736     }
  12737 #endif /* BCM_TOMAHAWK_SUPPORT */
  12738 
  12739 }
  12740 
  12741 void
  12742 _bcm_esw_flexport_sw_pipe_speed_group_dump(
  12743         int unit,
  12744         int pipe,
  12745         int speed_id)
  12746 {
  12747 #if defined(BCM_TOMAHAWK_SUPPORT)
  12748     if (SOC_IS_TOMAHAWK(unit)) {
  12749         soc_th_flexport_sw_pipe_speed_group_dump(
  12750                 unit, pipe, speed_id);
  12751     }
  12752 #endif /* BCM_TOMAHAWK_SUPPORT */
  12753 }
  12754 
  12755 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  12756 
  12757 static int
  12758 _bcm_esw_glp_bits_pos(int unit,
  12759                       uint8 *trunk_pos, uint8 *max_modid,
  12760                       uint8 *modid_pos, uint8 *max_port);
  12761 
  12762 #if defined(BCM_FIREBOLT_SUPPORT)
  12763 /*
  12764  * Function:
  12765  *      _bcm_port_vd_pbvl_init
  12766  * Purpose:
  12767  *      Initialization of vd_pbvl bitmap in port
  12768  * Parameters:
  12769  *      unit - StrataSwitch unit number.
  12770  * Returns:
  12771  *      BCM_E_NONE - success (or already initialized)
  12772  *      BCM_E_MEMORY - failed to allocate required memory.
  12773  */
  12774 
  12775 STATIC int
  12776 _bcm_port_vd_pbvl_init(int unit)
  12777 {
  12778     bcm_port_t port;
  12779     int idxmax;
  12780     int inds_bytes;
  12781     bcm_pbmp_t all_pbmp;
  12782 
  12783 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12784     /* TH3 does not support VLAN Protocol feature. Return doing nothing */
  12785     if (SOC_IS_TOMAHAWK3(unit)) {
  12786         return BCM_E_NONE;
  12787     }
  12788 #endif
  12789 
  12790     idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  12791     /* Round to the next entry */
  12792     inds_bytes =
  12793         (idxmax + (_BCM_PORT_VD_PBVL_ESIZE -  1)) / _BCM_PORT_VD_PBVL_ESIZE;
  12794 
  12795     BCM_PBMP_CLEAR(all_pbmp);
  12796     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12797 
  12798 #ifdef BCM_KATANA2_SUPPORT
  12799     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12800         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12801     }
  12802     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12803         soc_feature(unit, soc_feature_subtag_coe)) {
  12804         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12805     }
  12806 #endif
  12807 
  12808     PBMP_ITER(all_pbmp, port) {
  12809         PORT(unit, port).p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info");
  12810         if (NULL == PORT(unit, port).p_vd_pbvl) {
  12811             return (BCM_E_MEMORY);
  12812         }
  12813 
  12814         sal_memset(PORT(unit, port).p_vd_pbvl, 0, inds_bytes);
  12815     }
  12816 
  12817 #ifdef BCM_WARM_BOOT_SUPPORT
  12818     if (SOC_WARM_BOOT(unit)) {
  12819         BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_reinit(unit));
  12820     }
  12821 #endif
  12822 
  12823     return BCM_E_NONE;
  12824 }
  12825 #endif /* BCM_FIREBOLT_SUPPORT */
  12826 
  12827 /*
  12828  * Function:
  12829  *      _bcm_esw_port_software_detach
  12830  * Purpose:
  12831  *      De-initialization of software for port subsystem.
  12832  * Parameters:
  12833  *      unit - StrataSwitch unit number.
  12834  * Returns:
  12835  *      BCM_E_NONE - success (or already initialized)
  12836  *      BCM_E_INTERNAL- failed to write PTABLE entries
  12837  *      BCM_E_MEMORY - failed to allocate required memory.
  12838  */
  12839 
  12840 int
  12841 _bcm_esw_port_software_detach(int unit)
  12842 {
  12843     bcm_port_t          port;
  12844     bcm_pbmp_t all_pbmp;
  12845 
  12846     BCM_PBMP_CLEAR(all_pbmp);
  12847     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12848 
  12849 #ifdef BCM_KATANA2_SUPPORT
  12850     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12851         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12852     }
  12853     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12854         soc_feature(unit, soc_feature_subtag_coe)) {
  12855         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12856     }
  12857 #endif
  12858 
  12859     if (bcm_port_info[unit] == NULL) {
  12860          return (BCM_E_NONE);
  12861     }
  12862 
  12863     PBMP_ITER(all_pbmp, port) {
  12864         if (NULL != PORT(unit, port).p_vd_pbvl) {
  12865             sal_free(PORT(unit, port).p_vd_pbvl);
  12866             PORT(unit, port).p_vd_pbvl = NULL;
  12867         }
  12868 
  12869         if (NULL != PORT(unit, port).e2ecc_config) {
  12870             sal_free(PORT(unit, port).e2ecc_config);
  12871             PORT(unit, port).e2ecc_config = NULL;
  12872         }
  12873     }
  12874 
  12875     SOC_IF_ERROR_RETURN(soc_phy_common_detach(unit));
  12876 
  12877 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  12878  || defined(BCM_RAVEN_SUPPORT)
  12879     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  12880         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_detach(unit));
  12881     }
  12882 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \
  12883           || BCM_RAPTOR_SUPPORT */
  12884 
  12885 #ifdef BCM_TRIUMPH2_SUPPORT
  12886     if (NULL != PORT_SRC_MOD_EGR_PROFILE(unit)) {
  12887         BCM_IF_ERROR_RETURN
  12888             (soc_profile_mem_destroy(unit, PORT_SRC_MOD_EGR_PROFILE(unit)));
  12889         sal_free(PORT_SRC_MOD_EGR_PROFILE(unit));
  12890         PORT_SRC_MOD_EGR_PROFILE(unit) = NULL;
  12891     }
  12892 #endif /* BCM_TRIUMPH2_SUPPORT */
  12893 #if defined(BCM_TRIDENT_SUPPORT)
  12894     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  12895         BCM_IF_ERROR_RETURN(bcm_td_port_deinit(unit));
  12896     }
  12897 #endif /* BCM_TRIDENT_SUPPORT */
  12898 
  12899     sal_free (bcm_port_info[unit]);
  12900     bcm_port_info[unit] = NULL;
  12901 
  12902     return BCM_E_NONE;
  12903 }
  12904 
  12905 /*
  12906  * Function:
  12907  *      _bcm_port_software_init
  12908  * Purpose:
  12909  *      Initialization of software for port subsystem.
  12910  * Parameters:
  12911  *      unit - StrataSwitch unit number.
  12912  * Returns:
  12913  *      BCM_E_NONE - success (or already initialized)
  12914  *      BCM_E_INTERNAL- failed to write PTABLE entries
  12915  *      BCM_E_MEMORY - failed to allocate required memory.
  12916  */
  12917 
  12918 STATIC int
  12919 _bcm_port_software_init(int unit)
  12920 {
  12921     bcm_port_t  port = 0;
  12922     int         max_num_port = 0;
  12923     bcm_pbmp_t  all_pbmp;
  12924 
  12925     BCM_PBMP_CLEAR(all_pbmp);
  12926     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12927     max_num_port = SOC_MAX_NUM_PORTS;
  12928 
  12929 #ifdef BCM_KATANA2_SUPPORT
  12930     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12931         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12932     }
  12933     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12934         soc_feature(unit, soc_feature_subtag_coe)) {
  12935         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12936         max_num_port = SOC_MAX_NUM_PP_PORTS;
  12937     }
  12938 #endif
  12939 
  12940     if (bcm_port_info[unit] != NULL) {
  12941         PBMP_ITER(all_pbmp, port) {
  12942             if (PORT(unit, port).p_vd_pbvl != NULL) {
  12943                 sal_free(PORT(unit, port).p_vd_pbvl);
  12944                 PORT(unit, port).p_vd_pbvl = NULL;
  12945             }
  12946 
  12947             if (PORT(unit, port).e2ecc_config != NULL) {
  12948                 sal_free(PORT(unit, port).e2ecc_config);
  12949                 PORT(unit, port).e2ecc_config = NULL;
  12950             }
  12951 
  12952             PORT(unit, port).flags = 0;
  12953 #ifdef BCM_TRIDENT2_SUPPORT
  12954             if (SOC_IS_TD2_TT2(unit)) {
  12955                 PORT(unit, port).enable = TRUE;
  12956             }
  12957 #endif /* BCM_TRIDENT2_SUPPORT */
  12958         }
  12959     }
  12960 
  12961     if (bcm_port_info[unit] == NULL) {
  12962         bcm_port_info[unit] = sal_alloc(sizeof(_bcm_port_info_t) * max_num_port,
  12963                                         "bcm_port_info");
  12964         if (bcm_port_info[unit] == NULL) {
  12965             return BCM_E_MEMORY;
  12966         }
  12967     }
  12968     sal_memset(bcm_port_info[unit], 0, sizeof(_bcm_port_info_t) * max_num_port);
  12969 
  12970     SOC_IF_ERROR_RETURN(soc_phy_common_init(unit));
  12971 #if defined(BCM_FIREBOLT_SUPPORT)
  12972     if (SOC_IS_FBX(unit)) {
  12973         BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_init(unit));
  12974     }
  12975 #endif /* BCM_FIREBOLT_SUPPORT */
  12976 
  12977 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  12978  || defined(BCM_RAVEN_SUPPORT)
  12979     if (SOC_WARM_BOOT(unit)) {
  12980 #ifdef BCM_TRIUMPH2_SUPPORT
  12981         /* Moved to here for TD3 since the warm boot function call order changed */
  12982         if (soc_feature(unit, soc_feature_lport_tab_profile)) {
  12983             BCM_IF_ERROR_RETURN(bcm_esw_port_lport_profile_recover(unit));
  12984         }
  12985         if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  12986             BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_profile_recover(unit));
  12987         }
  12988 #endif
  12989     }
  12990 
  12991     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  12992         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_init(unit));
  12993     }
  12994     if (soc_feature(unit, soc_feature_color_prio_map)) {
  12995         BCM_IF_ERROR_RETURN(_bcm_fb2_priority_map_init(unit));
  12996     }
  12997 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \
  12998           || BCM_RAPTOR_SUPPORT */
  12999 
  13000 #if defined(BCM_TRX_SUPPORT)
  13001     if (SOC_IS_TRX(unit)) {
  13002         for (port = 0; port < max_num_port; port++) {
  13003             PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE;
  13004         }
  13005     }
  13006 #endif
  13007 
  13008 #ifdef BCM_WARM_BOOT_SUPPORT
  13009     if (SOC_WARM_BOOT(unit) || SOC_FAST_REBOOT(unit)) {
  13010 #if defined(BCM_XGS_SWITCH_SUPPORT)
  13011         if (soc_feature(unit, soc_feature_remap_ut_prio)) {
  13012             bcm_port_cfg_t pcfg;
  13013             PBMP_ITER(all_pbmp, port) {
  13014                 SOC_IF_ERROR_RETURN
  13015                     (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port,
  13016                                                           &pcfg));
  13017                 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri;
  13018             }
  13019         }
  13020 #ifdef BCM_TRIDENT2_SUPPORT
  13021         if (SOC_IS_TD2_TT2(unit)) {
  13022             PBMP_ITER(all_pbmp, port) {
  13023                 PORT(unit, port).enable = TRUE;
  13024             }
  13025         }
  13026 #endif /* BCM_TRIDENT2_SUPPORT */
  13027 #endif /* BCM_XGS_SWITCH_SUPPORT */
  13028 #if defined(BCM_TRX_SUPPORT)
  13029         if (SOC_IS_TRX(unit)) {
  13030             PBMP_ITER(all_pbmp, port) {
  13031                 /* Recover port's dtag_mode */
  13032                 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE;
  13033             }
  13034         }
  13035 #endif /* BCM_TRX_SUPPORT */
  13036     }
  13037 #endif /* BCM_WARM_BOOT_SUPPORT */
  13038 
  13039     return BCM_E_NONE;
  13040 }
  13041 
  13042 /*
  13043  * Function:
  13044  *      _bcm_port_settings_init
  13045  * Purpose:
  13046  *      Initialize port settings if they are to be different from the
  13047  *      default ones
  13048  * Parameters:
  13049  *      unit - StrataSwitch unit number.
  13050  *      port - port number
  13051  * Returns:
  13052  *      BCM_E_NONE - success (or already initialized)
  13053  *      BCM_E_INTERNAL- failed to write PTABLE entries
  13054  * Notes:
  13055  *      This function initializes port settings based on the folowing config
  13056  *      variables:
  13057  *           port_init_speed
  13058  *           port_init_duplex
  13059  *           port_init_adv
  13060  *           port_init_autoneg
  13061  *      If a variable is not set, then no additional initialization of the
  13062  *      corresponding parameter is done (and the defaults will normally be
  13063  *      advertize everything you can do and use autonegotiation).
  13064  *
  13065  *      A typical use would be to set:
  13066  *          port_init_adv=0
  13067  *          port_init_autoneg=1
  13068  *      to force link down in the beginning.
  13069  *
  13070  *      Another setup that makes sense is something like:
  13071  *          port_init_speed=10
  13072  *          port_init_duplex=0
  13073  *          port_init_autoneg=0
  13074  *      in order to force link into a certain mode. (It is very important to
  13075  *      disable autonegotiation in this case).
  13076  *
  13077  *      PLEASE NOTE:
  13078  *          The standard rc.soc forces autoneg=on on all the ethernet ports
  13079  *          (FE and GE). Thus, to use the second example one has to edit rc.soc
  13080  *          as well.
  13081  *
  13082  *     This function has been declared as global, but not exported. This will
  13083  *     make port initialization easier when using VxWorks shell.
  13084  */
  13085 int
  13086 bcm_port_settings_init(int unit, bcm_port_t port)
  13087 {
  13088     int             val;
  13089     bcm_port_info_t info;
  13090 
  13091     LOG_INFO(BSL_LS_BCM_PORT,
  13092              (BSL_META_U(unit,
  13093                          "bcm_port_settings_init: u=%d p=%d\n"),unit, port));
  13094 
  13095     bcm_port_info_t_init(&info);
  13096 
  13097     val = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, -1);
  13098     if (val != -1) {
  13099         info.speed = val;
  13100         info.action_mask |= BCM_PORT_ATTR_SPEED_MASK;
  13101     }
  13102 
  13103     val = soc_property_port_get(unit, port, spn_PORT_INIT_DUPLEX, -1);
  13104     if (val != -1) {
  13105         info.duplex = val;
  13106         info.action_mask |= BCM_PORT_ATTR_DUPLEX_MASK;
  13107     }
  13108 
  13109     val = soc_property_port_get(unit, port, spn_PORT_INIT_ADV, -1);
  13110     if (val != -1) {
  13111         info.local_advert = val;
  13112         info.action_mask |= BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  13113     }
  13114 
  13115     val = soc_property_port_get(unit, port, spn_PORT_INIT_AUTONEG, -1);
  13116     if (val != -1) {
  13117         info.autoneg = val;
  13118         info.action_mask |= BCM_PORT_ATTR_AUTONEG_MASK;
  13119     }
  13120     return bcm_esw_port_selective_set(unit, port, &info);
  13121 }
  13122 
  13123 #ifdef BCM_TRIUMPH2_SUPPORT
  13124 /* Helper function to program logical to physical (and reverse) port mapping */
  13125 STATIC int
  13126 _bcm_port_remap_set(int unit, bcm_port_t phys, bcm_port_t logical)
  13127 {
  13128     port_tab_entry_t ptab;
  13129     sys_portmap_entry_t sys_portmap;
  13130     uint32 regval;
  13131 
  13132     SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm,
  13133                                      MEM_BLOCK_ANY, phys, &ptab));
  13134     soc_PORT_TABm_field32_set(unit, &ptab, SRC_SYS_PORT_IDf, logical);
  13135     SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm,
  13136                                       MEM_BLOCK_ALL, phys, &ptab));
  13137 
  13138     SOC_IF_ERROR_RETURN(soc_mem_read(unit, SYS_PORTMAPm,
  13139                                      MEM_BLOCK_ANY, logical, &sys_portmap));
  13140     soc_SYS_PORTMAPm_field32_set(unit, &sys_portmap, PHYS_PORT_IDf, phys);
  13141     SOC_IF_ERROR_RETURN(soc_mem_write(unit, SYS_PORTMAPm,
  13142                                       MEM_BLOCK_ALL, logical, &sys_portmap));
  13143 
  13144     /* Configure E2ECC port mapping register */
  13145     SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPINGr(unit, phys, &regval));
  13146     soc_reg_field_set(unit, E2ECC_PORT_MAPPINGr, &regval, MAPPED_PORT_NUMf, logical);
  13147     SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPINGr(unit, phys, regval));
  13148 
  13149     return BCM_E_NONE;
  13150 }
  13151 
  13152 STATIC int
  13153 _bcm_tr2_system_tpid_init(int unit)
  13154 {
  13155     int tpid_index, sys_index, rv = BCM_E_NONE;
  13156     bcm_module_t module;
  13157     bcm_port_t port;
  13158     system_config_table_entry_t systab;
  13159     uint32 tpid_enable;
  13160     uint16 tpid;
  13161 
  13162     tpid = _bcm_fb2_outer_tpid_default_get(unit);
  13163     BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_index));
  13164 
  13165     for (module = 0; module <= SOC_MODID_MAX(unit); module++) {
  13166         for (port = 0; port < 64; port++) {
  13167             sys_index = module * 64 + port;
  13168             rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY,
  13169                                            sys_index, &systab);
  13170             BCM_IF_ERROR_RETURN(rv);
  13171             tpid_enable = (1 << tpid_index);
  13172             soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab,
  13173                                                  OUTER_TPID_ENABLEf,
  13174                                                  tpid_enable);
  13175             rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL,
  13176                                             sys_index, &systab);
  13177             BCM_IF_ERROR_RETURN(rv);
  13178         }
  13179     }
  13180     return rv;
  13181 }
  13182 #endif
  13183 
  13184 /*
  13185  * Function:
  13186  *      _bcm_esw_port_deinit
  13187  * Purpose:
  13188  *      De-initialize the PORT interface layer for the specified SOC device.
  13189  * Parameters:
  13190  *      unit - StrataSwitch unit number.
  13191  * Returns:
  13192  *      BCM_E_XXX
  13193  */
  13194 int
  13195 _bcm_esw_port_deinit(int unit)
  13196 {
  13197     int  rv;
  13198 
  13199     if (NULL == bcm_port_info[unit]) {
  13200         return (BCM_E_NONE);
  13201     }
  13202 
  13203     rv = _bcm_esw_port_software_detach(unit);
  13204     BCM_IF_ERROR_RETURN(rv);
  13205 
  13206 #ifdef BCM_TRX_SUPPORT
  13207     if (soc_feature(unit, soc_feature_vlan_action) ||
  13208         soc_feature(unit,soc_feature_egr_vlan_action)) {
  13209 #ifdef BCM_TRIUMPH2_SUPPORT
  13210         if (soc_feature(unit, soc_feature_vpd_profile)) {
  13211             _bcm_tr2_port_vpd_bitmap_free(unit);
  13212         }
  13213 #endif /* BCM_TRIUMPH2_SUPPORT */
  13214 
  13215         /* Initialize the vlan action profile table */
  13216 #if defined(BCM_TOMAHAWK3_SUPPORT)
  13217         if (SOC_IS_TOMAHAWK3(unit)) {
  13218             rv = _bcm_th3_vlan_action_profile_detach(unit);
  13219         } else
  13220 #endif /* BCM_TOMAHAWK3_SUPPORT */
  13221         {
  13222             rv = _bcm_trx_vlan_action_profile_detach(unit);
  13223         }
  13224         BCM_IF_ERROR_RETURN(rv);
  13225     }
  13226 #endif /* BCM_TRX_SUPPORT */
  13227 
  13228 #ifdef BCM_TRIUMPH2_SUPPORT
  13229     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  13230         rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport);
  13231         BCM_IF_ERROR_RETURN(rv);
  13232     }
  13233 #endif /* BCM_TRIUMPH2_SUPPORT */
  13234 
  13235 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  13236     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT)
  13237     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  13238          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  13239          SOC_IS_APACHE(unit)) &&
  13240         (soc_feature(unit,soc_feature_timesync_support))) {
  13241         _bcm_esw_port_timesync_profile_delete(unit);
  13242     }
  13243 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  13244           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  13245 
  13246 #if defined(BCM_TRIUMPH3_SUPPORT)
  13247     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  13248         rv = _bcm_port_force_forward_deinit(unit);
  13249         if(BCM_FAILURE(rv)) {
  13250             return rv;
  13251         }
  13252     }
  13253 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  13254 #if defined(BCM_TOMAHAWK_SUPPORT)
  13255     if (soc_feature(unit, soc_feature_asf_multimode)) {
  13256         /* deinit ASF (cutthrough) subsystem */
  13257         BCM_IF_ERROR_RETURN(_bcm_esw_asf_deinit(unit));
  13258     }
  13259 #endif
  13260 #ifdef BCM_TRIUMPH3_SUPPORT
  13261     if (SOC_IS_TRIUMPH3(unit)) {
  13262         _bcm_esw_ibod_sync_recovery_stop(unit);
  13263     }
  13264 #endif
  13265 #ifdef BCM_PREEMPTION_SUPPORT
  13266     if (soc_feature(unit, soc_feature_preemption)) {
  13267         bcmi_esw_preemption_cleanup(unit);
  13268     }
  13269     if (soc_feature(unit, soc_feature_preemption_cnt)) {
  13270         bcmi_esw_preemption_counter_cleanup(unit);
  13271     }
  13272 #endif /* BCM_PREEMPTION_SUPPORT */
  13273 #if defined(BCM_GREYHOUND_SUPPORT)
  13274     if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  13275         BCM_IF_ERROR_RETURN(
  13276             bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(unit));
  13277     }
  13278 #endif /* BCM_GREYHOUND_SUPPORT */
  13279 
  13280     return BCM_E_NONE;
  13281 }
  13282 
  13283 /*
  13284  * Function:
  13285  *      _bcm_esw_port_portmod_thread_stop
  13286  * Purpose:
  13287  *      Stop the portmod thread.
  13288  * Parameters:
  13289  *      unit - StrataSwitch unit number.
  13290  * Returns:
  13291  *      BCM_E_XXX
  13292  */
  13293 int _bcm_esw_port_portmod_thread_stop(int unit)
  13294 {
  13295     int  rv = BCM_E_NONE;
  13296     rv =  bcmi_esw_portctrl_portmod_thread_stop(unit);
  13297     return rv;
  13298 }
  13299 
  13300 #ifdef BCM_TRIDENT_SUPPORT
  13301 #ifdef BCM_WARM_BOOT_SUPPORT
  13302 /*
  13303  * Function:
  13304  *      _bcm_td_phymode_reconfigure
  13305  * Purpose:
  13306  *      Reconfigure the mode of the phys during warmboot.
  13307  *      This function has code copied from _soc_trident_misc_init
  13308  *      to keep the phy modes consistent in cold and warmboot modes.
  13309  *      This is required to be called before the phy probe routines
  13310  *      in order for the mode to be configured correctly.
  13311  * Parameters:
  13312  *      unit - StrataSwitch unit number.
  13313  * Returns:
  13314  *      BCM_E_XXX
  13315  */
  13316 STATIC int
  13317 _bcm_td_phymode_reconfigure(int unit) {
  13318 
  13319     soc_info_t *si = &SOC_INFO(unit);
  13320     int port, blk, blk_port, num_lanes, phy_port, bindex;
  13321 
  13322     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  13323         blk_port = SOC_BLOCK_PORT(unit, blk);
  13324         if (blk_port < 0) {
  13325             continue;
  13326         }
  13327         /*
  13328          * Program XLPORT mode and default Warpcore lanes setting
  13329          * core_mode: the number of ports on the system side of XMAC
  13330          * phy_mode: the number of ports on the Warpcore side of XMAC
  13331          * num_lanes: the number of lanes on the line side of Warpcore
  13332          */
  13333         if (si->port_speed_max[blk_port] > 20000) {
  13334             num_lanes = 4;
  13335         } else if (si->port_speed_max[blk_port] > 10000) {
  13336             if (si->port_speed_max[blk_port] == 20000 &&
  13337                 si->port_num_lanes[blk_port] == 4) {
  13338                 num_lanes = 4;
  13339             } else {
  13340                 num_lanes = 2;
  13341             }
  13342         } else {
  13343             num_lanes = 1;
  13344         }
  13345 
  13346         phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1;
  13347         for (bindex = 0; bindex < 4; bindex++) {
  13348             port = si->port_p2l_mapping[phy_port + bindex];
  13349             if (port == -1) {
  13350                 continue;
  13351             }
  13352             si->port_num_lanes[port] = num_lanes;
  13353         }
  13354     }
  13355     return BCM_E_NONE;
  13356 }
  13357 #endif /* BCM_WARM_BOOT_SUPPORT */
  13358 #endif /* BCM_TRIDENT_SUPPORT */
  13359 
  13360 #ifdef BCM_WARM_BOOT_SUPPORT
  13361 #ifdef BCM_TRIUMPH3_SUPPORT
  13362 STATIC int _bcm_tr3_flexport_wb_recover(int unit)
  13363 {
  13364     int rv = BCM_E_NONE;
  13365     int alloc_sz = 0;
  13366     uint8 *port_state;
  13367     uint16 recovered_ver;
  13368     bcm_port_t port;
  13369     int stable_size;
  13370     soc_scache_handle_t scache_handle;
  13371     soc_info_t *si = &SOC_INFO(unit);
  13372     int _port_lanes_valid = 0;
  13373     int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0};
  13374     bcm_pbmp_t all_pbmp;
  13375 
  13376     BCM_PBMP_CLEAR(all_pbmp);
  13377     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13378 
  13379     /* Calculate the offset of port_num_lanes */
  13380     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  13381     PBMP_ITER(all_pbmp, port) {
  13382         alloc_sz += sizeof(int); /* vp count */
  13383     }
  13384     alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  13385     PBMP_ITER(all_pbmp, port) {
  13386         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  13387             if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  13388                 alloc_sz += sizeof(uint32);
  13389             } else {
  13390                 alloc_sz += sizeof(_bcm_port_metering_info_t);
  13391             }
  13392             alloc_sz += sizeof(uint8); /* flags */
  13393         }
  13394     }
  13395     alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); /* num lanes of port */
  13396 
  13397     /* Get port_num_lanes from scahe */
  13398     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  13399                           BCM_PORT_WB_SCACHE_PART_DEFAULT);
  13400     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  13401                                  alloc_sz, (uint8**)&port_state,
  13402                                  BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  13403     if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  13404         return rv;
  13405     }
  13406 
  13407     port_state += (alloc_sz - (SOC_MAX_NUM_PORTS * sizeof(int)));
  13408     if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) {
  13409         PBMP_ALL_ITER(unit, port) {
  13410             sal_memcpy(&_port_num_lanes[port], port_state,
  13411                        sizeof(int));
  13412             port_state += sizeof(int);
  13413             _port_lanes_valid++;
  13414         }
  13415     }
  13416 
  13417     /* Recover port_num_lanes */
  13418     if (_port_lanes_valid) {
  13419          PBMP_ALL_ITER(unit, port) {
  13420              if (soc_tr3_port_is_flex_port(unit, port) &&
  13421                  (si->port_num_lanes[port] != _port_num_lanes[port])) {
  13422                  LOG_VERBOSE(BSL_LS_BCM_PORT,
  13423                              (BSL_META_U(unit,
  13424                                          "Port %d needs flex transform !!\n"),
  13425                               port));
  13426                  if ((rv = _bcm_tr3_port_lanes_set(unit, port,
  13427                                _port_num_lanes[port])) != BCM_E_NONE) {
  13428                      LOG_ERROR(BSL_LS_BCM_PORT, \
  13429                                (BSL_META_U(unit, \
  13430                                            "Error unit %d: "\
  13431                                            "Failed port lanes set: %s\n"),
  13432                                 unit, bcm_errmsg(rv)));
  13433                      return rv;
  13434                  }
  13435              }
  13436          }
  13437          (void)soc_port_type_verify(unit);
  13438     }
  13439 
  13440     return rv;
  13441 }
  13442 
  13443 STATIC void
  13444 _bcm_tr3_port_info_reconfig(int unit)
  13445 {
  13446     soc_port_t port;
  13447 
  13448     PBMP_ALL_ITER(unit, port) {
  13449         if (IS_AXP_PORT(unit, port)) {
  13450             /* Physical port table index doesn't exist for AXP ports */
  13451             continue;
  13452         }
  13453         /* cache num of port lanes */
  13454         (void)soc_tr3_port_lanes_gen(unit, port, &SOC_INFO(unit).port_num_lanes[port], NULL);
  13455     }
  13456 
  13457     if (soc_feature(unit, soc_feature_flex_port)) {
  13458         _bcm_tr3_flexport_wb_recover(unit);
  13459     }
  13460 }
  13461 #endif /* BCM_TRIUMPH3_SUPPORT */
  13462 #endif /* BCM_WARM_BOOT_SUPPORT */
  13463 
  13464 #ifdef BCM_HIGIG2_SUPPORT
  13465 /*
  13466  * Function:
  13467  *      _bcm_esw_port_higig2_mode_set
  13468  * Purpose:
  13469  *      Set port Higig2 mode
  13470  * Parameters:
  13471  *      unit - StrataSwitch unit #
  13472  *      port - StrataSwitch port #
  13473  *      higig2_mode - Higig2 mode
  13474  * Returns:
  13475  *      BCM_E_XXX
  13476  */
  13477 int
  13478 _bcm_esw_port_higig2_mode_set(int unit, bcm_port_t port, int higig2_mode)
  13479 {
  13480     soc_reg_t egr_port_reg;
  13481     soc_mem_t egr_port_mem;
  13482 
  13483     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  13484         return bcmi_esw_portctrl_higig2_mode_set(unit, port, higig2_mode);
  13485     }
  13486 
  13487     if (!SOC_IS_KATANA2(unit)) {
  13488         BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
  13489                             _BCM_CPU_TABS_NONE, HIGIG2f, higig2_mode));
  13490     }
  13491     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  13492             SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  13493             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  13494             EGR_PORT_64r : EGR_PORTr;
  13495     if (SOC_REG_FIELD_VALID(unit, egr_port_reg, HIGIG2f)) {
  13496         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, egr_port_reg, port,
  13497                     HIGIG2f, higig2_mode));
  13498     } else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HIGIG2f)) {
  13499         BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_PORTm, port,
  13500                     HIGIG2f, higig2_mode));
  13501     }
  13502 
  13503 #if defined(BCM_SABER2_SUPPORT)
  13504     if(SOC_IS_SABER2(unit)) {
  13505         /* For Saber2, configure IECELL along with XLPORT */
  13506         if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) {
  13507             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  13508                         IECELL_CONFIGr, port, HIGIG2_MODEf, higig2_mode));
  13509 
  13510         }
  13511     }
  13512 #endif
  13513 
  13514     if (IS_CL_PORT(unit, port) &&
  13515             SOC_REG_FIELD_VALID(unit, CLPORT_CONFIGr, HIGIG2_MODEf)) {
  13516         uint32 clp_hg2_mode = higig2_mode;
  13517 
  13518 #ifdef BCM_GREYHOUND2_SUPPORT
  13519         if (SOC_IS_GREYHOUND2(unit)) {
  13520             /* GH2 for CL port has PGW interface config for HG2/HG2-Lite */
  13521 #ifdef BCM_FIRELIGHT_SUPPORT
  13522             if (soc_feature(unit, soc_feature_fl)) {
  13523                 BCM_IF_ERROR_RETURN(soc_firelight_pgw_encap_field_modify(
  13524                     unit, port, HIGIG2_MODEf, higig2_mode));
  13525             } else
  13526 #endif /* BCM_FIRELIGHT_SUPPORT */
  13527             {
  13528                 BCM_IF_ERROR_RETURN(soc_greyhound2_pgw_encap_field_modify(
  13529                     unit, port, HIGIG2_MODEf, higig2_mode));
  13530             }
  13531 
  13532             /* GH2 sepcial design to set CLPORT_CONFIGr as IEEE encap mode for
  13533              * HG2-Lite. Thus the CLPORT_CONFIGr.HIGIG2_MODEf must be 0 here.
  13534              */
  13535             if (IS_HL_PORT(unit, port)) {
  13536                 clp_hg2_mode = 0;
  13537             }
  13538         }
  13539 #endif  /* GREYHOUND2 */
  13540 
  13541         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CLPORT_CONFIGr, port,
  13542                             HIGIG2_MODEf, clp_hg2_mode));
  13543     } else if (IS_C_PORT(unit, port) &&
  13544         SOC_REG_FIELD_VALID(unit, CPORT_CONFIGr, HIGIG2_MODEf)) {
  13545         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPORT_CONFIGr, port,
  13546                 HIGIG2_MODEf, higig2_mode));
  13547     } else if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, HIGIG2_MODEf)) {
  13548         uint32 xlp_hg2_mode = higig2_mode;
  13549 
  13550 #ifdef BCM_GREYHOUND_SUPPORT
  13551         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  13552             SOC_IS_GREYHOUND2(unit)){
  13553             BCM_IF_ERROR_RETURN(soc_greyhound_pgw_encap_field_modify(unit,
  13554                 port, HIGIG2_MODEf, higig2_mode));
  13555 
  13556             /* GH sepcial design to set XLPORT_CONFIGr as IEEE encap mode for
  13557              * HG2-Lite. Thus the XLPORT_CONFIGr.HIGIG2_MODEf must be 0 here.
  13558              */
  13559             if (IS_HL_PORT(unit, port)) {
  13560                 xlp_hg2_mode = 0;
  13561             }
  13562         }
  13563 #endif /* BCM_GREYHOUND_SUPPORT */
  13564 
  13565         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XLPORT_CONFIGr, port,
  13566                 HIGIG2_MODEf, xlp_hg2_mode));
  13567     } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, HIGIG2_MODEf)) {
  13568         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  13569                 HIGIG2_MODEf, higig2_mode));
  13570     } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, HIGIG2_MODEf)) {
  13571         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PORT_CONFIGr, port,
  13572                 HIGIG2_MODEf, higig2_mode));
  13573     }
  13574     if (soc_feature(unit, soc_feature_wh2)) {
  13575         SOC_IF_ERROR_RETURN(
  13576             soc_reg_field32_modify(unit, PGW_GE_CONFIGr, port,
  13577                                    HIGIG2_MODEf, higig2_mode));
  13578     }
  13579 
  13580     egr_port_mem = SOC_IS_KATANA2(unit) ? EGR_PHYSICAL_PORTm : EGR_ING_PORTm;
  13581     if (SOC_MEM_FIELD_VALID(unit, egr_port_mem, HIGIG2f)) {
  13582         if (IS_CPU_PORT(unit, port)) {
  13583             BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem,
  13584                         SOC_INFO(unit).cpu_hg_index, HIGIG2f, higig2_mode));
  13585         } else {
  13586             BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem,
  13587                         port, HIGIG2f, higig2_mode));
  13588         }
  13589     }
  13590 
  13591     return BCM_E_NONE;
  13592 }
  13593 #endif /* BCM_HIGIG2_SUPPORT */
  13594 
  13595 #ifdef BCM_TRIUMPH3_SUPPORT
  13596 /*
  13597  * Function:
  13598  *      _bcm_esw_tr3_port_lanes_init
  13599  * Purpose:
  13600  *      Initialize port lanes settings for 40g port of
  13601  *      Triumph3(56541,56542, 56545 and 56546)
  13602  * Parameters:
  13603  *      unit - StrataSwitch unit number.
  13604  *      port - port number
  13605  * Returns:
  13606  *      BCM_E_NONE - success (or already initialized)
  13607  *      BCM_E_INTERNAL- failed to set lane mode
  13608  * Notes:
  13609  *      This function initializes port lanes settings based on the following config
  13610  *      variables:
  13611  *           port_max_speed
  13612  *      If a variable is not set, then no additional initialization of the
  13613  *      parameter is done.
  13614  *
  13615  *      If user want to use 100Mbps on WC ports(xe4,xe5), configuration
  13616  *      must be setted as below:
  13617  *          port_max_speed=100
  13618  */
  13619 int
  13620 _bcm_esw_tr3_port_lanes_init(int unit)
  13621 {
  13622     int rv;
  13623     int max_speed;
  13624     int old_lanes = 0, new_lanes = -1;
  13625     int enable;
  13626     bcm_port_t port;
  13627     PBMP_PORT_ITER(unit, port) {
  13628         if (port != 54 && port != 55) {
  13629             continue;
  13630         }
  13631         if (soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0)) {
  13632             max_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0);
  13633             if ((max_speed == 100) || (max_speed == 1000)) {
  13634                 new_lanes = 1;
  13635             } else if ((max_speed != 100) && (max_speed != 1000)) {
  13636                 new_lanes = 4;
  13637             }
  13638             BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &old_lanes));
  13639             if (new_lanes > 0 && old_lanes != new_lanes) {
  13640                 /* Cache original configurations */
  13641                 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  13642                 COUNTER_LOCK(unit);
  13643                 rv = _bcm_tr3_port_lanes_set(unit, port, new_lanes);
  13644                 COUNTER_UNLOCK(unit);
  13645                 BCM_IF_ERROR_RETURN(rv);
  13646                 bcm_port_settings_init(unit, port);
  13647                 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable));
  13648             }
  13649         }
  13650     }
  13651     return BCM_E_NONE;
  13652 }
  13653 #endif
  13654 
  13655 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT)
  13656 /*
  13657  * Function:
  13658  *      _bcm_esw_td3_port_cmh_ctrl_set
  13659  * Description:
  13660  *      Configure CANCUN redefined port control.
  13661  * Parameters:
  13662  *      unit - Device number
  13663  *      port - Port number
  13664  *      type - Enum value of the feature
  13665  *      value - value to be set
  13666  * Return Value:
  13667  *      BCM_E_NONE
  13668  *      BCM_E_UNAVAIL - Functionality not available
  13669  */
  13670 int
  13671 _bcm_esw_td3_port_cmh_ctrl_set(int unit, bcm_port_t port,
  13672                          bcm_port_control_t type, int value)
  13673 {
  13674     int rv = BCM_E_NONE;
  13675     uint32 entry[SOC_MAX_MEM_WORDS];
  13676     bcm_module_t my_modid = 0, modid_out;
  13677     bcm_port_t port_out;
  13678     bcm_trunk_t trunk_out;
  13679     int    src_trk_idx = 0, id_out;
  13680     soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm;
  13681 
  13682     if (BCM_GPORT_IS_SET(port)) {
  13683         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  13684                                  &modid_out, &port_out, &trunk_out, &id_out));
  13685     } else {
  13686         port_out = port;
  13687     }
  13688 
  13689     if (!soc_cancun_cmh_check(unit, LPORT_TABm, VXLAN_SVP_ASSIGNMENT_KEY_TYPEf)) {
  13690         return rv;
  13691     }
  13692 
  13693     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  13694     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  13695                             port_out, &src_trk_idx));
  13696 
  13697     mem = SOURCE_TRUNK_MAP_TABLEm;
  13698     sal_memset(entry, 0, sizeof(entry));
  13699     soc_mem_lock(unit, mem);
  13700     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry);
  13701     if (SOC_SUCCESS(rv)) {
  13702         soc_mem_field32_set(unit, mem, entry, CTRL_PROFILE_IDX_0f,
  13703                              value? 0x1: 0x0);
  13704         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry);
  13705     }
  13706     soc_mem_unlock(unit, mem);
  13707 
  13708     return rv;
  13709 }
  13710 
  13711 #endif
  13712 
  13713 /*
  13714  * Function:
  13715  *      bcm_port_init
  13716  * Purpose:
  13717  *      Initialize the PORT interface layer for the specified SOC device.
  13718  * Parameters:
  13719  *      unit - StrataSwitch unit number.
  13720  * Returns:
  13721  *      BCM_E_NONE - success (or already initialized)
  13722  *      BCM_E_INTERNAL- failed to write PTABLE entries
  13723  *      BCM_E_MEMORY - failed to allocate required memory.
  13724  * Notes:
  13725  *      By default ports come up enabled. They can be made to come up disabled
  13726  *      at startup by a compile-time application policy flag in your Make.local
  13727  *      PTABLE initialized.
  13728  */
  13729 int
  13730 bcm_esw_port_init(int unit)
  13731 {
  13732     int                 rv, port_enable, length_check;
  13733     bcm_port_t          p;
  13734     int                 p_speed;
  13735     pbmp_t              okay_ports;
  13736     bcm_vlan_data_t     vd;
  13737     char                pfmtok[SOC_PBMP_FMT_LEN],
  13738                         pfmtall[SOC_PBMP_FMT_LEN];
  13739     bcm_pbmp_t          all_pbmp;
  13740 #ifdef BCM_TRX_SUPPORT
  13741     bcm_pbmp_t          hg_pbmp;
  13742 #endif /* BCM_TRX_SUPPORT */
  13743 #if defined(BCM_KATANA2_SUPPORT)
  13744     uint32 entry[SOC_MAX_MEM_WORDS];
  13745 #endif /* BCM_KATANA_SUPPORT */
  13746     uint32              rx_los;
  13747 #ifdef BCM_TRIDENT2_SUPPORT
  13748     int                 enable;
  13749 #endif /* BCM_TRIDENT2_SUPPORT */
  13750 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  13751     int index;
  13752     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  13753 #endif
  13754 #if defined(BCM_FIREBOLT6_SUPPORT)
  13755     egr_port_min_pkt_size_entry_t egr_port_mem_pkt_size_ent;
  13756 #endif
  13757 
  13758     int port_iter;
  13759 #ifdef BCM_METROLITE_SUPPORT
  13760     uint16 dev_id=0;
  13761     uint8  rev_id=0;
  13762     bcm_pbmp_t          non_sat_port_pbmp;
  13763     soc_cm_get_id(unit, &dev_id, &rev_id);
  13764 #endif
  13765 
  13766     LOG_VERBOSE(BSL_LS_BCM_PORT,
  13767                 (BSL_META_U(unit,
  13768                             "bcm_port_init: unit %d\n"), unit));
  13769     assert(unit < BCM_MAX_NUM_UNITS);
  13770     if ((rv = _bcm_port_software_init(unit)) != BCM_E_NONE) {
  13771         LOG_ERROR(BSL_LS_BCM_PORT,
  13772                   (BSL_META_U(unit,
  13773                               "Error unit %d:  Failed software port init: %s\n"),
  13774                    unit, bcm_errmsg(rv)));
  13775         return rv;
  13776     }
  13777     if (SAL_BOOT_SIMULATION &&
  13778         soc_property_get(unit, "skip_port_hw_init", 0)) {
  13779         return BCM_E_NONE;
  13780     }
  13781 
  13782     /* Initialize Port Function driver */
  13783     BCM_ESW_PORT_DRV(unit) = NULL;
  13784 
  13785 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  13786 #if defined(BCM_KATANA2_SUPPORT)
  13787     if (SOC_IS_KATANA2(unit)) {
  13788         BCM_IF_ERROR_RETURN(bcmi_katana2_port_fn_drv_init(unit));
  13789     } else
  13790 #endif
  13791 #if defined(BCM_MONTEREY_SUPPORT)
  13792     if (SOC_IS_MONTEREY(unit)) {
  13793         BCM_IF_ERROR_RETURN(bcmi_monterey_port_fn_drv_init(unit));
  13794     } else
  13795 #endif
  13796 #if defined(BCM_APACHE_SUPPORT)
  13797     if (SOC_IS_APACHE(unit)) {
  13798         BCM_IF_ERROR_RETURN(bcmi_apache_port_fn_drv_init(unit));
  13799     } else
  13800 #endif
  13801 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  13802     if (SOC_IS_TD2P_TT2P(unit)) {
  13803         BCM_IF_ERROR_RETURN(bcmi_td2p_port_fn_drv_init(unit));
  13804     } else
  13805 #endif
  13806 #ifdef BCM_TRIDENT3_SUPPORT
  13807     if (SOC_IS_TRIDENT3(unit)) {
  13808         BCM_IF_ERROR_RETURN(bcmi_td3_port_fn_drv_init(unit));
  13809     } else
  13810 #endif
  13811 #ifdef BCM_HURRICANE4_SUPPORT
  13812     if (SOC_IS_HURRICANE4(unit)) {
  13813         BCM_IF_ERROR_RETURN(bcmi_hr4_port_fn_drv_init(unit));
  13814     } else
  13815 #endif
  13816 #ifdef BCM_HELIX5_SUPPORT
  13817     if (SOC_IS_HELIX5(unit)) {
  13818         BCM_IF_ERROR_RETURN(bcmi_hx5_port_fn_drv_init(unit));
  13819     } else
  13820 #endif
  13821 #ifdef BCM_MAVERICK2_SUPPORT
  13822     if (SOC_IS_MAVERICK2(unit)) {
  13823         BCM_IF_ERROR_RETURN(bcmi_mv2_port_fn_drv_init(unit));
  13824     } else
  13825 #endif
  13826 #ifdef BCM_TOMAHAWK2_SUPPORT
  13827     if (SOC_IS_TOMAHAWK2(unit)) {
  13828         BCM_IF_ERROR_RETURN(bcmi_th2_port_fn_drv_init(unit));
  13829     } else
  13830 #endif
  13831 #ifdef BCM_TOMAHAWK3_SUPPORT
  13832     if (SOC_IS_TOMAHAWK3(unit)) {
  13833         BCM_IF_ERROR_RETURN(bcmi_th3_port_fn_drv_init(unit));
  13834     } else
  13835 #endif
  13836 #ifdef BCM_HURRICANE4_SUPPORT
  13837     if (SOC_IS_HURRICANE4(unit)) {
  13838         BCM_IF_ERROR_RETURN(bcmi_hr4_port_fn_drv_init(unit));
  13839     } else
  13840 #endif
  13841 #ifdef BCM_FIREBOLT6_SUPPORT
  13842     if (SOC_IS_FIREBOLT6(unit)) {
  13843         BCM_IF_ERROR_RETURN(bcmi_fb6_port_fn_drv_init(unit));
  13844     } else
  13845 #endif
  13846     {
  13847     }
  13848 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  13849 
  13850     SOC_PBMP_CLEAR(all_pbmp);
  13851 
  13852 #ifdef BCM_TRX_SUPPORT
  13853     SOC_PBMP_CLEAR(hg_pbmp);
  13854 
  13855     if (soc_feature(unit, soc_feature_vlan_action) ||
  13856         soc_feature(unit, soc_feature_egr_vlan_action)) {
  13857         bcm_vlan_action_set_t action;
  13858 
  13859         bcm_vlan_action_set_t_init(&action);
  13860 
  13861 #ifdef BCM_TRIUMPH2_SUPPORT
  13862         if (soc_feature(unit, soc_feature_vpd_profile)) {
  13863             BCM_IF_ERROR_RETURN(_bcm_tr2_port_vpd_bitmap_alloc(unit));
  13864         }
  13865 #endif
  13866 
  13867         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13868 
  13869 #ifdef BCM_KATANA2_SUPPORT
  13870         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  13871             /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
  13872              * causes the outer tag to be removed from packets that don't have
  13873              * a hit in the egress vlan tranlation table. Set to 0 to disable this.
  13874              */
  13875             uint32 rval = 0;
  13876             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
  13877             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,1);
  13878 
  13879             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  13880             PBMP_ITER(all_pbmp, p) {
  13881                BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, p, rval));
  13882             }
  13883         }
  13884 
  13885 		if (soc_feature(unit, soc_feature_linkphy_coe) ||
  13886             soc_feature(unit, soc_feature_subtag_coe)) {
  13887             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  13888 
  13889 
  13890         }
  13891 #endif
  13892 
  13893 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  13894         if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit)
  13895              || SOC_IS_TRIDENT3X(unit)) &&
  13896                 (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm) &&
  13897                  soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) {
  13898             vlan_protocol_data_entry_t vlan_protocol_data_entries[16];
  13899             uint32 vlan_protocol_data_index =0;
  13900             void *entries_buf[1];
  13901             int i, count = 0;
  13902                 vlan_protocol_data_entry_t vde;
  13903 
  13904             /* Create the default VLAN_PROTOCOL_DATA profile */
  13905             sal_memset(vlan_protocol_data_entries, 0,
  13906                 sizeof(vlan_protocol_data_entries));
  13907 
  13908                 entries_buf[0] = &vlan_protocol_data_entries;
  13909                 BCM_IF_ERROR_RETURN(
  13910                     _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf,
  13911                          16, (uint32 *)&vlan_protocol_data_index));
  13912 
  13913             /* First 16 entries of VLAN_PROTOCOL_DATA table are used for
  13914              * default profile for Katana2 */
  13915             for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOLm); i++) {
  13916                     sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t));
  13917                     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde,
  13918                     OVIDf, BCM_VLAN_DEFAULT);
  13919                     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde,
  13920                      TAG_ACTION_PROFILE_PTRf, 0);
  13921                     BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit,
  13922                         MEM_BLOCK_ALL, i, &vde));
  13923             }
  13924 
  13925             count = 0;
  13926             PBMP_ITER(all_pbmp, p) {
  13927                 PORT(unit, p).vp_count = 0;
  13928                 if (!IS_LB_PORT(unit, p) && !SOC_WARM_BOOT(unit)) {
  13929 
  13930                     /* Set vlan_protocol_data_ptr profile index in port table. */
  13931                     BCM_IF_ERROR_RETURN(
  13932                     _bcm_esw_port_tab_set(unit, p,
  13933                                          _BCM_CPU_TABS_ETHER,
  13934                                           VLAN_PROTOCOL_DATA_INDEXf,
  13935                                           vlan_protocol_data_index / 16));
  13936                     PORT(unit, p).vlan_prot_ptr = vlan_protocol_data_index;
  13937                     count++;
  13938                 }
  13939             }
  13940 
  13941             /* Keep one extra reference to the default profile */
  13942             for (i = 1; i < count + 1; i++) {
  13943                 BCM_IF_ERROR_RETURN(
  13944                 _bcm_port_vlan_protocol_data_entry_reference (unit,
  13945                     vlan_protocol_data_index, 16));
  13946             }
  13947         } else
  13948 
  13949 #endif
  13950         {
  13951             PBMP_ITER(all_pbmp, p) {
  13952                 PORT(unit, p).vp_count = 0;
  13953                 if (!IS_LB_PORT(unit, p)) {
  13954                     if (!SOC_IS_TOMAHAWKX(unit) &&
  13955                         !SOC_IS_TOMAHAWK3(unit) && !SOC_IS_TRIDENT3(unit)) {
  13956                         /* there are more ports the profile */
  13957 #ifdef BCM_TRIUMPH2_SUPPORT
  13958                         if (soc_feature(unit, soc_feature_vpd_profile)) {
  13959                             BCM_IF_ERROR_RETURN
  13960                                 (_bcm_port_vlan_prot_index_alloc
  13961                                     (unit, &(PORT(unit, p).vlan_prot_ptr)));
  13962                         } else
  13963 #endif
  13964                         {
  13965                             PORT(unit, p).vlan_prot_ptr = p * soc_mem_index_count
  13966                                                           (unit, VLAN_PROTOCOLm);
  13967                         }
  13968                     }
  13969                 }
  13970             }
  13971         }
  13972 
  13973         if (!SOC_WARM_BOOT(unit)) {
  13974             /* Clear the profile ptr of source table */
  13975             PBMP_ALL_ITER(unit, p) {
  13976                 BCM_IF_ERROR_RETURN
  13977                     (_bcm_trx_vlan_port_egress_action_profile_clear(unit, p));
  13978             }
  13979         }
  13980 
  13981 #ifdef BCM_FIREBOLT6_SUPPORT
  13982         if (SOC_IS_FIREBOLT6(unit)) {
  13983             PBMP_ALL_ITER(unit, p) {
  13984                 SOC_IF_ERROR_RETURN(
  13985                     soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, p,
  13986                    SRC_SUBPORT_NUMf, p));
  13987                 SOC_IF_ERROR_RETURN(
  13988                     soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, p,
  13989                   PP_PORT_NUMf, p));
  13990             }
  13991 
  13992             /* Set egr min pkt size to default value of 0x40 */
  13993             for (index = 0; index < soc_mem_index_count(unit,
  13994                         EGR_PORT_MIN_PKT_SIZEm); index++) {
  13995                 SOC_IF_ERROR_RETURN(READ_EGR_PORT_MIN_PKT_SIZEm(
  13996                             unit, MEM_BLOCK_ALL, index,
  13997                             &egr_port_mem_pkt_size_ent));
  13998                 soc_mem_field32_set(unit, EGR_PORT_MIN_PKT_SIZEm,
  13999                         &egr_port_mem_pkt_size_ent, MIN_PKT_SIZEf, 0x40);
  14000                 SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_MIN_PKT_SIZEm(
  14001                             unit, MEM_BLOCK_ALL, index,
  14002                             &egr_port_mem_pkt_size_ent));
  14003             }
  14004         }
  14005 #endif
  14006 
  14007         /* Initialize the vlan action profile table */
  14008 #if defined(BCM_TOMAHAWK3_SUPPORT)
  14009         if (SOC_IS_TOMAHAWK3(unit)) {
  14010             BCM_IF_ERROR_RETURN (_bcm_th3_vlan_action_profile_init(unit));
  14011         } else
  14012 #endif /* BCM_TOMAHAWK3_SUPPORT */
  14013         {
  14014             BCM_IF_ERROR_RETURN (_bcm_trx_vlan_action_profile_init(unit));
  14015         }
  14016 
  14017         if (SOC_IS_KATANA2(unit)) {
  14018             SOC_PBMP_ASSIGN(hg_pbmp,PBMP_ST_ALL(unit));
  14019         } else {
  14020             SOC_PBMP_ASSIGN(hg_pbmp,PBMP_HG_ALL(unit));
  14021         }
  14022 
  14023         if (!SOC_IS_TRIDENT3X(unit)) {
  14024             PBMP_ITER(hg_pbmp, p) {
  14025                 BCM_IF_ERROR_RETURN
  14026                     (_bcm_trx_vlan_port_egress_default_action_get(unit,
  14027                                                                  p, &action));
  14028                 /* Backward compatible defaults */
  14029                 action.ot_outer = bcmVlanActionDelete;
  14030                 action.dt_outer = bcmVlanActionDelete;
  14031                 BCM_IF_ERROR_RETURN
  14032                     (_bcm_trx_vlan_port_egress_default_action_set(unit,
  14033                                                                  p, &action));
  14034             }
  14035         }
  14036     }
  14037 #endif  /* BCM_TRX_SUPPORT*/
  14038 
  14039 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  14040     if (soc_feature(unit, soc_feature_higig_over_ethernet)) {
  14041 #ifdef BCM_WARM_BOOT_SUPPORT
  14042         if (SOC_WARM_BOOT(unit)) {
  14043             uint32 port_type, hg_type, update = 0;
  14044             bcm_pbmp_t e_pbm;
  14045             soc_info_t *si;
  14046             egr_port_entry_t egr_port;
  14047 
  14048             if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  14049                 si = &SOC_INFO(unit);
  14050                 SOC_PBMP_ASSIGN(e_pbm, PBMP_E_ALL(unit));
  14051                 PBMP_ITER(e_pbm, p) {
  14052                     BCM_IF_ERROR_RETURN
  14053                         (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, p, &egr_port));
  14054                     port_type =
  14055                         soc_mem_field32_get(unit, EGR_PORTm, &egr_port, PORT_TYPEf);
  14056                     hg_type =
  14057                         soc_mem_field32_get(unit, EGR_PORTm, &egr_port, HG_TYPEf);
  14058                     if ((port_type == 1) &&
  14059                         (hg_type == BCM_PORT_HG_TYPE_HGOE_TRANSPORT)) {
  14060                         SOC_PBMP_PORT_ADD(si->st.bitmap, p);
  14061                         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, p);
  14062                         SOC_PBMP_PORT_REMOVE(si->hg2_pbm, p);
  14063                         update = 1;
  14064                     }
  14065                 }
  14066 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \
  14067                 si->ptype.num = 0; \
  14068                 si->ptype.min = si->ptype.max = -1; \
  14069                 PBMP_ITER(si->ptype.bitmap, p) { \
  14070                     si->ptype.port[si->ptype.num++] = p; \
  14071                     if (si->ptype.min < 0) { \
  14072                         si->ptype.min = p; \
  14073                     } \
  14074                     if (p > si->ptype.max) { \
  14075                         si->ptype.max = p; \
  14076                     } \
  14077                 }
  14078 
  14079                 if (update) {
  14080                     /* Recalculate port type data */
  14081                     RECONFIGURE_PORT_TYPE_INFO(ether);
  14082                     RECONFIGURE_PORT_TYPE_INFO(st);
  14083                 }
  14084 #undef  RECONFIGURE_PORT_TYPE_INFO
  14085             }
  14086         }
  14087 #endif /* BCM_WARM_BOOT_SUPPORT */
  14088     }
  14089 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  14090 
  14091 #ifdef BCM_TRIUMPH2_SUPPORT
  14092     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14093 #ifdef BCM_WARM_BOOT_SUPPORT
  14094         if (SOC_WARM_BOOT(unit)) {
  14095             port_tab_entry_t ptab;
  14096             int fs_idx;
  14097             bcm_gport_t gport;
  14098 
  14099 #ifdef BCM_TRIDENT_SUPPORT
  14100             if (SOC_IS_TD_TT(unit)) {
  14101                 BCM_IF_ERROR_RETURN(_bcm_td_phymode_reconfigure(unit));
  14102             }
  14103 #endif /* BCM_TRIDENT_SUPPORT */
  14104             PBMP_ITER(all_pbmp, p) {
  14105                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm,
  14106                                                  MEM_BLOCK_ANY, p, &ptab));
  14107                 fs_idx =
  14108                     soc_mem_field32_get(unit, PORT_TABm, &ptab,
  14109                                         VINTF_CTR_IDXf);
  14110                 if (fs_idx) {
  14111                     BCM_IF_ERROR_RETURN
  14112                         (bcm_esw_port_gport_get(unit, p, &gport));
  14113                     _bcm_esw_flex_stat_reinit_add(unit,
  14114                              _bcmFlexStatTypeGport, fs_idx, gport);
  14115                 }
  14116             }
  14117         }
  14118 #endif /* BCM_WARM_BOOT_SUPPORT */
  14119     }
  14120 #endif /* BCM_TRIUMPH2_SUPPORT */
  14121 
  14122 #ifdef BCM_WARM_BOOT_SUPPORT
  14123 #ifdef BCM_TRIUMPH3_SUPPORT
  14124     if (SOC_IS_TRIUMPH3(unit)) {
  14125         if (SOC_WARM_BOOT(unit)) {
  14126             _bcm_tr3_port_info_reconfig(unit);
  14127         }
  14128     }
  14129 #endif /* BCM_TRIUMPH3_SUPPORT */
  14130 #endif /* BCM_WARM_BOOT_SUPPORT */
  14131     if (!SOC_WARM_BOOT(unit)) {
  14132         /*
  14133          * Write port configuration tables to contain the Initial System
  14134          * Configuration (see init.c).
  14135          */
  14136 
  14137         SOC_PBMP_CLEAR(all_pbmp);
  14138         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  14139 
  14140 #ifdef BCM_KATANA2_SUPPORT
  14141         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  14142             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  14143         }
  14144 #endif
  14145 
  14146 				SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit));
  14147 
  14148 #ifdef BCM_KATANA2_SUPPORT
  14149         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  14150             soc_feature(unit, soc_feature_subtag_coe)) {
  14151             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  14152         }
  14153 #endif
  14154 
  14155         vd.vlan_tag = BCM_VLAN_DEFAULT;
  14156         BCM_PBMP_ASSIGN(vd.port_bitmap, all_pbmp);
  14157         BCM_PBMP_ASSIGN(vd.ut_port_bitmap, all_pbmp);
  14158         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit));
  14159         PBMP_ITER(all_pbmp, p) {
  14160             BCM_IF_ERROR_RETURN
  14161                 (mbcm_driver[unit]->mbcm_port_cfg_init(unit, p, &vd));
  14162         }
  14163 
  14164         if (SOC_IS_TRIDENT3X(unit)) {
  14165             /* Initialize inner TPID
  14166              * (WAR)Set to 0x9100 then change back to take effort
  14167              */
  14168             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr,
  14169                                 REG_PORT_ANY, INNER_TPIDf, 0x9100));
  14170             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr,
  14171                                 REG_PORT_ANY, INNER_TPIDf, 0x8100));
  14172 
  14173             if (SOC_REG_FIELD_VALID(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) {
  14174                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  14175                                     REG_PORT_ANY, INNER_TPIDf, 0x9100));
  14176                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  14177                                 REG_PORT_ANY, INNER_TPIDf, 0x8100));
  14178         }
  14179         }
  14180 
  14181         /*
  14182          * Clear egress port blocking table
  14183          */
  14184         if (SOC_IS_XGS_SWITCH(unit)) {
  14185 #ifdef BCM_SHADOW_SUPPORT
  14186             if (!SOC_IS_SHADOW(unit)) {
  14187 #endif
  14188                 if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) {
  14189                     SOC_IF_ERROR_RETURN
  14190                         (soc_mem_clear(unit, MAC_BLOCKm, COPYNO_ALL, TRUE));
  14191                 }
  14192 #ifdef BCM_SHADOW_SUPPORT
  14193             }
  14194 #endif
  14195         }
  14196     }
  14197 
  14198 #ifdef BCM_SHADOW_SUPPORT
  14199     if (SOC_IS_SHADOW(unit)) {
  14200         PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  14201             if (BCM_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, p)) {
  14202                 SOC_PBMP_PORT_REMOVE(PBMP_PORT_ALL(unit), p);
  14203             }
  14204         }
  14205     }
  14206 #endif
  14207 #ifdef BCM_PREEMPTION_SUPPORT
  14208     if (soc_feature(unit, soc_feature_preemption)) {
  14209         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_init(unit));
  14210     }
  14211 #endif
  14212 
  14213     /* Probe for ports */
  14214     SOC_PBMP_CLEAR(okay_ports);
  14215 
  14216     /* Fast reboot will NOT cold boot portmod and the serdes because we
  14217      * want to keep the link up
  14218      */
  14219     if (SOC_FAST_REBOOT(unit)) {
  14220         SOC_WARM_BOOT_START(unit);
  14221     }
  14222 #ifdef BCM_METROLITE_SUPPORT
  14223     if (SOC_IS_METROLITE(unit) &&
  14224         (dev_id == BCM56272_DEVICE_ID)) {
  14225         BCM_PBMP_CLEAR(non_sat_port_pbmp);
  14226         BCM_PBMP_ASSIGN(non_sat_port_pbmp, PBMP_PORT_ALL(unit));
  14227         if(SOC_PBMP_MEMBER(non_sat_port_pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER)) {
  14228             /* TSC0 is OFF */
  14229             SOC_PBMP_PORT_REMOVE(non_sat_port_pbmp,
  14230                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  14231         }
  14232         rv = bcm_esw_port_probe(unit, non_sat_port_pbmp, &okay_ports);
  14233     } else
  14234 #endif
  14235     {
  14236         rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), &okay_ports);
  14237     }
  14238     if (rv != BCM_E_NONE) {
  14239         LOG_ERROR(BSL_LS_BCM_PORT,
  14240                   (BSL_META_U(unit,
  14241                               "Error unit %d:  Failed port probe: %s\n"),
  14242                    unit, bcm_errmsg(rv)));
  14243         return rv;
  14244     }
  14245 
  14246     LOG_VERBOSE(BSL_LS_BCM_PORT,
  14247                 (BSL_META_U(unit,
  14248                             "Probed ports okay: %s of %s\n"),
  14249                  SOC_PBMP_FMT(okay_ports, pfmtok),
  14250                  SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmtall)));
  14251 
  14252     if (SOC_FAST_REBOOT(unit)) {
  14253         SOC_WARM_BOOT_DONE(unit);
  14254 
  14255         /* Add all ports that would have been added during portmod init to
  14256          * the pbmp because the rest of the cold boot sequence is going
  14257          * to need it
  14258          */
  14259         PBMP_PORT_ITER(unit, port_iter) {
  14260             if (IS_CPU_PORT(unit, port_iter) || IS_LB_PORT(unit, port_iter)) {
  14261                 continue;
  14262             }
  14263             SOC_PBMP_PORT_ADD(okay_ports, port_iter);
  14264         }
  14265 
  14266     }
  14267 
  14268     /*
  14269      * A compile-time application policy may prefer to disable ports
  14270      * when switch boots up
  14271      */
  14272 #ifdef BCM_PORT_DEFAULT_DISABLE
  14273             port_enable = FALSE;
  14274 #else
  14275             port_enable = TRUE;
  14276 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  14277 
  14278     if(SOC_IS_SABER2(unit) && (!SOC_WARM_BOOT(unit))) {
  14279         PBMP_ITER(okay_ports, p) {
  14280             if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) {
  14281                 LOG_WARN(BSL_LS_BCM_PORT,
  14282                          (BSL_META_U(unit,
  14283                                      "Warning: Unit %d Port %s: "
  14284                                      "Failed to %s port: %s\n"),
  14285                           unit, SOC_PORT_NAME(unit, p),(port_enable) ? \
  14286                           "enable" : "disable" ,bcm_errmsg(rv)));
  14287             }
  14288         }
  14289     }
  14290 
  14291 
  14292 
  14293     length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0);
  14294 
  14295     /* Probe and initialize MAC and PHY drivers for ports that were OK */
  14296     PBMP_ITER(okay_ports, p) {
  14297         LOG_VERBOSE(BSL_LS_BCM_PORT,
  14298                     (BSL_META_U(unit,
  14299                                 "bcm_port_init: unit %d port %s\n"),
  14300                                 unit, SOC_PORT_NAME(unit, p)));
  14301 
  14302         PORT_LOCK(unit);
  14303 
  14304         
  14305         if (SOC_PORT_USE_PORTCTRL(unit, p)) {
  14306         } else {
  14307             if ((rv = _bcm_port_mode_setup(unit, p, TRUE)) < 0) {
  14308                 LOG_WARN(BSL_LS_BCM_PORT,
  14309                          (BSL_META_U(unit,
  14310                                      "Warning: Port %s: "
  14311                                      "Failed to set initial mode: %s\n"),
  14312                           SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  14313             }
  14314         }
  14315         PORT_UNLOCK(unit);
  14316 
  14317 #ifdef BCM_RCPU_SUPPORT
  14318         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, p)) {
  14319             if (SOC_PORT_USE_PORTCTRL(unit, p)) {
  14320                 bcmi_esw_portctrl_phy_enable_set(unit, p, TRUE);
  14321             } else {
  14322                 soc_phyctrl_enable_set(unit, p, TRUE);
  14323             }
  14324             continue;
  14325         }
  14326 #endif /* BCM_RCPU_SUPPORT */
  14327 
  14328 #ifdef BCM_WARM_BOOT_SUPPORT
  14329         if (SOC_WARM_BOOT(unit) || SOC_FAST_REBOOT(unit)) {
  14330             continue;
  14331         }
  14332 #endif /* BCM_WARM_BOOT_SUPPORT */
  14333         if ((rv = bcm_port_settings_init(unit, p)) < 0) {
  14334             LOG_WARN(BSL_LS_BCM_PORT,
  14335                      (BSL_META_U(unit,
  14336                                  "Warning: Port %s: "
  14337                                  "Failed to configure initial settings: %s\n"),
  14338                       SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  14339         }
  14340 
  14341 #ifdef BCM_TRIDENT2_SUPPORT
  14342         if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap)) {
  14343             uint32 addr;
  14344             int block;
  14345             uint8 acc_type;
  14346             uint32 rval;
  14347 
  14348             addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr, p, 0,
  14349                                     SOC_REG_ADDR_OPTION_NONE, &block,
  14350                                     &acc_type);
  14351             addr &= 0xffffff00;
  14352             /* coverity[overrun-local : FALSE] */
  14353             addr |= (SOC_INFO(unit).port_l2p_mapping[p] - 1) & 0xf;
  14354             SOC_IF_ERROR_RETURN(_soc_reg32_get(unit, block, acc_type, addr,
  14355                                                &rval));
  14356             if (length_check) {
  14357                 rval |= 0x20;  /* set bit 5 to enable frame length check */
  14358             } else {
  14359                 rval &= ~0x20; /* clear bit 5 to disable frame length check */
  14360             }
  14361             rval |= 1 << 18; /* set PFC frame detected indicator */
  14362             SOC_IF_ERROR_RETURN(_soc_reg32_set(unit, block, acc_type, addr,
  14363                                                rval));
  14364         } else
  14365 #endif /* BCM_TRIDENT2_SUPPORT */
  14366         /* Control 802.3 frame length field check in MAC for
  14367          * XL, XLB0, XT, CL, CLG2, XW (helix4) or MXQ blocks */
  14368         if (IS_XL_PORT(unit, p) || IS_XLB0_PORT(unit, p) || IS_XT_PORT(unit, p) ||
  14369             IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p) || IS_MXQ_PORT(unit,p) ||
  14370             IS_XW_PORT(unit,p) || IS_CD_PORT(unit, p)) {
  14371             uint32 rval;
  14372             soc_reg_t reg = INVALIDr;
  14373 
  14374             if ((IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p)) &&
  14375                 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  14376                 reg = CLPORT_MAC_RSV_MASKr;
  14377             } else if (IS_CD_PORT(unit, p)) {
  14378                 reg = CDMAC_RSV_MASKr;
  14379             } else if (SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  14380                 reg = PGW_MAC_RSV_MASKr;
  14381             } else if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_MAC_RSV_MASKr, p)) {
  14382                 reg = XLPORT_MAC_RSV_MASKr;
  14383             } else if (SOC_REG_IS_VALID(unit, MAC_RSV_MASKr)) {
  14384                 reg = MAC_RSV_MASKr;
  14385             } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  14386                 reg = XLPORT_MAC_RSV_MASKr;
  14387             }
  14388 
  14389             if (reg != INVALIDr) {
  14390                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, p, 0, &rval));
  14391                 if (length_check) {
  14392                     rval |= 0x20;  /* set bit 5 to enable frame length check */
  14393                 } else {
  14394                     rval &= ~0x20; /* clear bit 5 to disable frame length check */
  14395                 }
  14396                 if (SOC_IS_TD2_TT2(unit)|| SOC_IS_HELIX4(unit)) {
  14397                     rval |= 1 << 18; /* set PFC frame detected indicator */
  14398                 }
  14399                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, p, 0, rval));
  14400             }
  14401         }
  14402 
  14403         /*
  14404          * A compile-time application policy may prefer to disable ports
  14405          * when switch boots up
  14406          */
  14407 
  14408 #ifdef BCM_PORT_DEFAULT_DISABLE
  14409             port_enable = FALSE;
  14410 #else
  14411             port_enable = TRUE;
  14412 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  14413 
  14414         if(!SOC_IS_SABER2(unit)) {
  14415             if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) {
  14416             LOG_WARN(BSL_LS_BCM_PORT,
  14417                      (BSL_META_U(unit,
  14418                                  "Warning: Port %s: "
  14419                                  "Failed to %s port: %s\n"),
  14420                       SOC_PORT_NAME(unit, p),(port_enable) ? \
  14421                       "enable" : "disable" ,bcm_errmsg(rv)));
  14422             }
  14423         }
  14424 
  14425         /*
  14426          *  JAM should be enabled by default
  14427          */
  14428         if (IS_E_PORT(unit, p)) {
  14429             if (soc_mem_field_valid(unit, PORT_TABm, JAM_ENf) ||
  14430                 soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) ||
  14431                 soc_feature(unit, soc_feature_unimac)) {
  14432 
  14433 #if defined(BCM_HURRICANE_SUPPORT)
  14434                 if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) ||
  14435                     SOC_IS_GREYHOUND2(unit)) {
  14436                     rv = bcm_esw_port_jam_set(unit, p, 0);
  14437                 } else
  14438 #endif
  14439                 {
  14440                     rv = bcm_esw_port_jam_set(unit, p, 1);
  14441                 }
  14442                 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
  14443                     LOG_WARN(BSL_LS_BCM_PORT,
  14444                              (BSL_META_U(unit,
  14445                                          "Warning: Port %s: "
  14446                                          "Failed to enable JAM %s\n"),
  14447                               SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  14448                 }
  14449             }
  14450         }
  14451 #ifdef BCM_TRIUMPH2_SUPPORT
  14452         if (soc_feature(unit, soc_feature_unimac_tx_crs) && IS_XQ_PORT(unit, p)
  14453             && IS_GE_PORT(unit, p)) {
  14454             BCM_IF_ERROR_RETURN
  14455                 (soc_reg_field32_modify(unit, XPORT_CONFIGr, p,
  14456                                         UNIMAC_HD_ECO_ENABLEf, 1));
  14457         }
  14458 #endif
  14459 #ifdef BCM_RCPU_SUPPORT
  14460         if ((uint32)p == soc_property_get(unit, spn_RCPU_PORT, -1)) {
  14461             BCM_IF_ERROR_RETURN
  14462                 (bcm_esw_port_frame_max_set(unit, p, BCM_PORT_JUMBO_MAXSZ));
  14463         }
  14464 #endif /* BCM_RCPU_SUPPORT */
  14465     }
  14466 
  14467 #if defined(BCM_GREYHOUND_SUPPORT)
  14468     if (SOC_IS_GREYHOUND(unit)) {
  14469         BCM_IF_ERROR_RETURN(bcm_gh_port_init(unit));
  14470     }
  14471 #endif
  14472 
  14473 #if defined(BCM_HURRICANE3_SUPPORT)
  14474     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  14475         BCM_IF_ERROR_RETURN(bcm_hr3_port_init(unit));
  14476     }
  14477 #endif
  14478 
  14479 #if defined(BCM_TRIDENT_SUPPORT)
  14480     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  14481         BCM_IF_ERROR_RETURN(bcm_td_port_init(unit));
  14482     }
  14483 #endif /* BCM_TRIDENT_SUPPORT */
  14484 
  14485 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  14486     defined(BCM_TRX_SUPPORT)
  14487     if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) {
  14488         /* Enable the default outer TPID. */
  14489         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  14490         /* if (soc_feature(unit, soc_feature_vlan_ctrl) && * SOC_IS_SHADOW(unit)) { */
  14491 
  14492         SOC_PBMP_CLEAR(all_pbmp);
  14493         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  14494 
  14495 #ifdef BCM_KATANA2_SUPPORT
  14496         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  14497             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  14498         }
  14499 #endif
  14500 
  14501         SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit));
  14502 
  14503 #ifdef BCM_KATANA2_SUPPORT
  14504         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  14505             soc_feature(unit, soc_feature_subtag_coe)) {
  14506             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  14507         }
  14508 #endif
  14509 
  14510 #if defined(BCM_SABER2_SUPPORT)
  14511         /* If OAMP is enabled by default, skip the port init for oamp port */
  14512         if(SOC_IS_SABER2(unit)) {
  14513             int oamp_enable;
  14514             (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  14515 
  14516             if (soc_feature(unit, soc_feature_sat) &&
  14517                 ((!SOC_WARM_BOOT(unit) &&
  14518                     soc_property_get(unit, spn_SAT_ENABLE, 0)) ||
  14519                  (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) {
  14520                 SOC_PBMP_PORT_REMOVE(all_pbmp,
  14521                         _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  14522             }
  14523         }
  14524 #endif
  14525             PBMP_ITER(all_pbmp, p) {
  14526                 rv = bcm_esw_port_tpid_set(unit, p,
  14527                                 _bcm_fb2_outer_tpid_default_get(unit));
  14528                 if (BCM_FAILURE(rv)) {
  14529                  LOG_WARN(BSL_LS_BCM_PORT,
  14530                           (BSL_META_U(unit,
  14531                                       "Warning: "
  14532                                       "Failed to set %s port default TPID: %s\n"),
  14533                            SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  14534                 }
  14535                 if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
  14536                     /* Enable the default inner TPID. */
  14537                     rv = bcm_esw_port_inner_tpid_set(unit, p,
  14538                                     _bcm_fb2_outer_tpid_default_get(unit));
  14539                     if (BCM_FAILURE(rv)) {
  14540                      LOG_WARN(BSL_LS_BCM_PORT,
  14541                               (BSL_META_U(unit,
  14542                                           "Warning: "
  14543                                           "Failed to set %s port default inner TPID: %s\n"),
  14544                                SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  14545                     }
  14546                 }
  14547             }
  14548         }
  14549     }
  14550 #endif
  14551 
  14552 #ifdef BCM_XGS3_FABRIC_SUPPORT
  14553     if (SOC_IS_XGS3_FABRIC(unit)) {
  14554         PBMP_ALL_ITER(unit, p) {
  14555             bcm_esw_port_learn_set(unit, p, BCM_PORT_LEARN_FWD);
  14556         }
  14557     }
  14558 #endif
  14559     if (SAL_BOOT_SIMULATION &&
  14560         soc_property_get(unit, "skip_partial_port_hw_init", 0)) {
  14561         return BCM_E_NONE;
  14562     }
  14563 #ifdef BCM_TRIUMPH2_SUPPORT
  14564     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  14565         SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  14566         SOC_IS_TD_TT(unit) || SOC_IS_HURRICANEX(unit) ||
  14567         SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit) ||
  14568         SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) {
  14569         uint32 regval, profile_index;
  14570         bcm_pbmp_t port_pbmp;
  14571 
  14572         /* Set the chip-wide E2ECC port mapping enable bit */
  14573         if (soc_feature(unit, soc_feature_sysport_remap)) {
  14574             SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, &regval));
  14575             soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, &regval, PORT_MAPPING_ENf, 1);
  14576             SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval));
  14577         }
  14578 
  14579         SOC_PBMP_CLEAR(all_pbmp);
  14580         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  14581         SOC_PBMP_CLEAR(port_pbmp);
  14582         SOC_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit));
  14583 
  14584 #ifdef BCM_KATANA2_SUPPORT
  14585         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  14586             soc_feature(unit, soc_feature_subtag_coe)) {
  14587             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  14588             _bcm_kt2_subport_pbmp_update(unit, &port_pbmp);
  14589         }
  14590         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  14591             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  14592             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp));
  14593         }
  14594 #endif
  14595 
  14596         PBMP_ITER(all_pbmp, p) {
  14597             /* Initialize the logical to physical port mapping */
  14598             if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  14599                 !SOC_IS_TD_TT(unit) && !SOC_IS_TRIUMPH3(unit) &&
  14600                 !SOC_IS_KATANAX(unit) && !SOC_IS_GREYHOUND(unit) &&
  14601                 !SOC_IS_GREYHOUND2(unit)) {
  14602                 bcm_port_t sp = p;
  14603                 if (soc_feature(unit, soc_feature_sysport_remap)) {
  14604                     BCM_XLATE_SYSPORT_P2S(unit, &sp);
  14605                 }
  14606                 _bcm_port_remap_set(unit, p, sp);
  14607             }
  14608 
  14609             /* Initialize egress block profile pointer to invalid value */
  14610             PORT_SRC_MOD_EGR_PROF_PTR(unit, p) = -1;
  14611 
  14612             /* Program the VLAN_PROTOCOL_DATA / FP_PORT_FIELD_SEL_INDEX
  14613                / PROTOCOL_PKT_INDEX pointers */
  14614             if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) {
  14615                 int value = 0;
  14616                 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) {
  14617                     value = PORT(unit, p).vlan_prot_ptr /
  14618                             soc_mem_index_count(unit, VLAN_PROTOCOLm);
  14619                 }
  14620                 if ((0 != value) &&
  14621                     (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) {
  14622                     BCM_IF_ERROR_RETURN(
  14623                         _bcm_esw_port_tab_set(unit, p,
  14624                                        _BCM_CPU_TABS_ETHER,
  14625                                        VLAN_PROTOCOL_DATA_INDEXf,
  14626                                        BCM_PBMP_MEMBER(port_pbmp, p) ? value : 0));
  14627                 }
  14628 
  14629                 if (soc_mem_field_valid(unit, PORT_TABm,
  14630                     FP_PORT_FIELD_SEL_INDEXf)) {
  14631                     BCM_IF_ERROR_RETURN(
  14632                         _bcm_esw_port_tab_set(unit, p,
  14633                                    _BCM_CPU_TABS_ETHER,
  14634                                     FP_PORT_FIELD_SEL_INDEXf, p));
  14635                 }
  14636                 if (soc_mem_field_valid(unit, PORT_TABm, PROTOCOL_PKT_INDEXf) ||
  14637                     soc_mem_field_valid(unit, LPORT_TABm,
  14638                                         PROTOCOL_PKT_INDEXf)) {
  14639                     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  14640                         soc_portreg) {
  14641                             BCM_IF_ERROR_RETURN(
  14642                                 _bcm_esw_port_tab_set(unit, p,
  14643                                                    _BCM_CPU_TABS_ETHER,
  14644                                                    PROTOCOL_PKT_INDEXf,
  14645                                                    p));
  14646                     } else {
  14647                         BCM_IF_ERROR_RETURN
  14648                             (_bcm_prot_pkt_ctrl_add(unit, 0, 0,
  14649                                                     &profile_index));
  14650                         BCM_IF_ERROR_RETURN(
  14651                             _bcm_esw_port_tab_set(unit, p,
  14652                                                    _BCM_CPU_TABS_ETHER,
  14653                                                    PROTOCOL_PKT_INDEXf,
  14654                                                    profile_index));
  14655                     }
  14656                 }
  14657 
  14658                 if (soc_feature(unit, soc_feature_embedded_higig)
  14659                     && IS_E_PORT(unit, p)) {
  14660                     uint32 buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  14661                     uint32      mask[SOC_MAX_MEM_FIELD_WORDS];
  14662 
  14663                     sal_memset(buffer, 0,
  14664                            WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  14665                     sal_memset(mask, 0xFF, sizeof(mask));
  14666                     /* coverity[overrun-call : FALSE] */
  14667                     BCM_IF_ERROR_RETURN(
  14668                         _bcm_port_ehg_header_write(unit, p, buffer, buffer, mask,
  14669                                         _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  14670                 }
  14671             }
  14672         }
  14673 
  14674         if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm) &&
  14675             !SOC_MEM_IS_VALID(unit, SOURCE_TRUNK_MAP_MODBASEm) &&
  14676             SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) {
  14677             BCM_IF_ERROR_RETURN(_bcm_tr2_system_tpid_init(unit));
  14678         }
  14679     }
  14680 #endif /* BCM_TRIUMPH2_SUPPORT */
  14681 
  14682 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  14683     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT)
  14684     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  14685          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  14686          SOC_IS_APACHE(unit)) &&
  14687         (soc_feature(unit,soc_feature_timesync_support))) {
  14688         _bcm_esw_port_timesync_profile_init(unit);
  14689     }
  14690 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  14691           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  14692 
  14693 #ifdef BCM_SHADOW_SUPPORT
  14694         /* Static port load balancing configuration for shadow */
  14695     if (SOC_IS_SHADOW(unit))  {
  14696         port_tab_entry_t ptab;
  14697 
  14698         for (p = 0; p <= 16; p++) {
  14699             /* Enable IPV4 and IPV6 */
  14700             BCM_IF_ERROR_RETURN(
  14701                 _bcm_esw_port_tab_set(unit, p,
  14702                                      _BCM_CPU_TABS_ETHER,
  14703                                       IPV4_ENABLEf, 1));
  14704 
  14705             BCM_IF_ERROR_RETURN(
  14706                 _bcm_esw_port_tab_set(unit, p,
  14707                                      _BCM_CPU_TABS_ETHER,
  14708                                       IPV6_ENABLEf, 1));
  14709         }
  14710 
  14711         /* For shadow-petrab mode, configure uflow_A(xe0) and uflow_b(xe1)*/
  14712         if(soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0) &&
  14713                 ((soc_property_get(unit, spn_BCM88732_2X40_1X40, 0)) ||
  14714                  (soc_property_get(unit, spn_BCM88732_2X40_2X40, 0)))) {
  14715             BCM_IF_ERROR_RETURN(
  14716                 _bcm_esw_port_tab_set(unit, 1,
  14717                                      _BCM_CPU_TABS_ETHER,
  14718                                       AGGREGATION_GROUP_SELECTf, 0));
  14719 
  14720             /* port 5 (xe1) configure uflow_b for static load balancing */
  14721             BCM_IF_ERROR_RETURN(
  14722                 _bcm_esw_port_tab_set(unit, 5,
  14723                                      _BCM_CPU_TABS_ETHER,
  14724                                       AGGREGATION_GROUP_SELECTf, 1));
  14725 
  14726             /* Enable SAND interop header for Interlaken ports */
  14727             for (p = 9; p <= 16; p++) {
  14728                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p,
  14729                                            _BCM_CPU_TABS_ETHER,
  14730                                             SAND_COS_ENABLEf, 1));
  14731             }
  14732         }
  14733         if(soc_property_get(unit, spn_BCM88732_2X40_8X10, 0))  {
  14734             sal_memset(&ptab, 0, sizeof(ptab));
  14735             /* port 1 (xe0) configure uflow_a for static load balancing */
  14736             SOC_IF_ERROR_RETURN(
  14737                     READ_PORT_TABm(unit, MEM_BLOCK_ANY, 1, &ptab));
  14738             soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 0);
  14739             SOC_IF_ERROR_RETURN(
  14740                     WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 1, &ptab));
  14741 
  14742             /* port 5 (xe1) configure uflow_b for static load balancing */
  14743             SOC_IF_ERROR_RETURN(
  14744                     READ_PORT_TABm(unit, MEM_BLOCK_ANY, 5, &ptab));
  14745             soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 1);
  14746             SOC_IF_ERROR_RETURN(
  14747                     WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 5, &ptab));
  14748 
  14749         }
  14750 
  14751         /* By default Disable VLAN checks and enable TPID in port table */
  14752         for (p = 0; p <= 16; p++) {
  14753             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p,
  14754                                 _BCM_CPU_TABS_ETHER,
  14755                                  DISABLE_VLAN_CHECKSf, 1));
  14756 
  14757             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p,
  14758                                 _BCM_CPU_TABS_ETHER,
  14759                                  OUTER_TPID_ENABLEf, 1));
  14760         }
  14761     }
  14762 #endif /* BCM_SHADOW_SUPPORT */
  14763 
  14764 #ifdef BCM_TRIDENT_SUPPORT
  14765     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  14766         uint32 regval;
  14767         int blk;
  14768         int blk_num = -1;
  14769         int bindex = 0;
  14770         int tx_pbm = 0;
  14771         bcm_pbmp_t all_pbmp;
  14772 
  14773         if (SOC_IS_TRIUMPH3(unit)) {
  14774             /* Clear all bits for flex port considerations */
  14775             for (blk_num = 0; blk_num < 7; blk_num++) {
  14776                 SOC_IF_ERROR_RETURN
  14777                     (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 0));
  14778             }
  14779         }
  14780 
  14781         SOC_PBMP_CLEAR(all_pbmp);
  14782         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  14783 
  14784 #ifdef BCM_KATANA2_SUPPORT
  14785         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  14786             soc_feature(unit, soc_feature_subtag_coe)) {
  14787             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  14788         }
  14789 #endif
  14790 
  14791         PBMP_ITER(all_pbmp, p) {
  14792             if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) {
  14793                  if (soc_mem_field_valid(unit, PORT_TABm,
  14794                     FP_PORT_FIELD_SEL_INDEXf)) {
  14795                     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p,
  14796                                     _BCM_CPU_TABS_ETHER,
  14797                                     FP_PORT_FIELD_SEL_INDEXf, p));
  14798                 }
  14799             }
  14800         }
  14801 
  14802         PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  14803             /* In Trident all ports are enabled to send E2ECC messages by
  14804              * default. Disable E2ECC message TX here until congestion config
  14805              * set enables the port.
  14806              */
  14807 
  14808             if (soc_feature(unit, soc_feature_logical_port_num)) {
  14809                 /* coverity[overrun-local : FALSE] */
  14810                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[p]);
  14811                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[p]);
  14812             } else{
  14813                 blk = SOC_PORT_BLOCK(unit, p);
  14814                 bindex = SOC_PORT_BINDEX(unit, p);
  14815             }
  14816 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  14817            if (SOC_IS_TRIDENT2X(unit)) {
  14818                blk_num = SOC_INFO(unit).port_serdes[p];
  14819            } else
  14820 #endif
  14821            {
  14822               blk_num = SOC_BLOCK_INFO(unit, blk).number;
  14823            }
  14824             if (SOC_IS_KATANA2(unit)) {
  14825                 if (!IS_HG_PORT(unit, p)) {
  14826                     continue;
  14827                 }
  14828                 /* In KT2 E2ECC is implemented only in blocks 6..9 */
  14829                 if (blk_num >= 6) {
  14830                     blk_num -= 6;
  14831                 } else {
  14832                     continue;
  14833                 }
  14834             }
  14835             if (!SOC_IS_TRIUMPH3(unit) &&
  14836                 SOC_REG_IS_VALID(unit, E2ECC_TX_ENABLE_BMPr)) {
  14837                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  14838                                                               &regval));
  14839                 tx_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  14840                                            TX_ENABLE_BMPf);
  14841                 tx_pbm &= ~(1 << bindex);
  14842                 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  14843                                   TX_ENABLE_BMPf, tx_pbm);
  14844                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_ENABLE_BMPr(unit,
  14845                                                                blk_num, regval));
  14846             }
  14847         }
  14848         /* Set the chip-wide E2ECC port mapping enable bit */
  14849         if (soc_feature(unit, soc_feature_sysport_remap)) {
  14850             SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, &regval));
  14851             soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, &regval,
  14852                               PORT_MAPPING_ENf, 1);
  14853             SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval));
  14854         }
  14855     }
  14856 #endif
  14857 
  14858 #if defined (BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) \
  14859     || defined (BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  14860     || defined (BCM_HURRICANE2_SUPPORT)
  14861     if (SOC_IS_HURRICANE (unit) || SOC_IS_TD_TT (unit) ||
  14862         SOC_IS_HAWKEYE (unit) || SOC_IS_SHADOW(unit) ||
  14863         SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
  14864         SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  14865         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  14866         if (soc_feature (unit, soc_feature_eee)) {
  14867             int mac_val = 0;
  14868             _bcm_port_info_t *port_info;
  14869             PBMP_ALL_ITER(unit, p) {
  14870                 if (!IS_LB_PORT(unit, p) && !IS_CPU_PORT (unit, p) && !IS_FAE_PORT (unit, p) &&
  14871                     !IS_TDM_PORT(unit, p) && !IS_RDB_PORT(unit,p) && !IS_MACSEC_PORT(unit,p)) {
  14872                     /* EEE standard compliance Work Around:
  14873                      * Initialize the software state of native eee in MAC
  14874                      */
  14875                     eee_cfg[unit][p] = 0;
  14876                     /* Check if MAC supports Native EEE and set the value of
  14877                      * eee_cfg by reading the EEE status from MAC*/
  14878                     if (SOC_PORT_USE_PORTCTRL(unit, p)) {
  14879                         rv = bcmi_esw_portctrl_eee_enable_get(unit, p,
  14880                                                               &mac_val);
  14881 
  14882                     } else {
  14883                         _bcm_port_info_access(unit, p, &port_info);
  14884                         rv = MAC_CONTROL_GET(port_info->p_mac, unit, p,
  14885                                              SOC_MAC_CONTROL_EEE_ENABLE,
  14886                                              &mac_val);
  14887                     }
  14888                     if (rv != BCM_E_UNAVAIL) {
  14889                         eee_cfg[unit][p] = mac_val;
  14890                     }
  14891                 }
  14892             }
  14893         }
  14894     }
  14895 #endif /* (BCM_HURRICANE_SUPPORT) || (BCM_TRIDENT_SUPPORT) || (BCM_HAWKEYE_SUPPORT)*/
  14896 
  14897     /*
  14898      * CES TDM Port initialization
  14899      */
  14900     /* Set Higig/Higig2 mode */
  14901     if (!SOC_WARM_BOOT(unit)) {
  14902         if (SOC_USE_PORTCTRL(unit)) {
  14903             int hg_port;
  14904             PBMP_HG_ITER(unit, hg_port) {
  14905                 BCM_IF_ERROR_RETURN
  14906                     (bcmi_esw_portctrl_higig_mode_set(unit, hg_port, TRUE));
  14907             }
  14908         }
  14909 #ifdef BCM_HIGIG2_SUPPORT
  14910         if (soc_feature(unit, soc_feature_higig2)) {
  14911             int hg_port;
  14912 #if defined(BCM_KATANA_SUPPORT)
  14913             int hl_port;
  14914 
  14915             if (SOC_IS_KATANA(unit)) {
  14916                 PBMP_HL_ITER(unit, hl_port) {
  14917                     BCM_IF_ERROR_RETURN
  14918                         (_bcm_esw_port_higig2_mode_set(unit, hl_port, TRUE));
  14919                     SOC_HG2_ENABLED_PORT_ADD(unit, hl_port);
  14920                 }
  14921             }
  14922 #endif
  14923             PBMP_HG_ITER(unit, hg_port) {
  14924                 /*
  14925                  * Make all HG ports default to HiGig2, when
  14926                  * 1. spn_HIGIG2_HDR_MODE = 1. Or
  14927                  * 2. portmod is enabled
  14928                  */
  14929                 if (soc_property_port_get(unit, hg_port, spn_HIGIG2_HDR_MODE,
  14930                         soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) ||
  14931                     SOC_USE_PORTCTRL(unit)) {
  14932                     BCM_IF_ERROR_RETURN
  14933                         (_bcm_esw_port_higig2_mode_set(unit, hg_port, TRUE));
  14934                     SOC_HG2_ENABLED_PORT_ADD(unit, hg_port);
  14935                 }
  14936             }
  14937         }
  14938 #endif /* BCM_HIGIG2_SUPPORT */
  14939     }
  14940 
  14941     BCM_IF_ERROR_RETURN(_bcm_esw_port_mon_start(unit));
  14942 #ifdef BCM_TRIUMPH3_SUPPORT
  14943     if (SOC_IS_TRIUMPH3(unit)) {
  14944         BCM_IF_ERROR_RETURN
  14945             (_bcm_esw_ibod_sync_recovery_start(unit,
  14946              soc_property_get(unit, spn_PORTMON_INTERVAL, IBOD_SYNC_INTERVAL_MIN)));
  14947     }
  14948 #endif /* BCM_TRIUMPH3_SUPPORT */
  14949     /* Port translation call-back function for PHY drivers */
  14950     soc_phy_cb_xlate_port_func = _bcm_phy_cb_xlate_port;
  14951 
  14952 #ifdef BCM_TRIUMPH2_SUPPORT
  14953     if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  14954         soc_mem_t mem = SRC_MODID_EGRESSm;
  14955         int mem_words;
  14956         int rv;
  14957 
  14958         if (SOC_MEM_IS_VALID(unit, mem)) {
  14959             if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) {
  14960                 PORT_SRC_MOD_EGR_PROFILE(unit) =
  14961                     sal_alloc(sizeof(soc_profile_mem_t),
  14962                               "SRC_MODID_EGRESS Profile Mem");
  14963                 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) {
  14964                     return BCM_E_MEMORY;
  14965                 }
  14966                 soc_profile_mem_t_init(PORT_SRC_MOD_EGR_PROFILE(unit));
  14967 
  14968                 mem_words = sizeof(src_modid_egress_entry_t) /
  14969                     sizeof(uint32);
  14970 
  14971                 rv = soc_profile_mem_create(unit, &mem, &mem_words, 1,
  14972                                             PORT_SRC_MOD_EGR_PROFILE(unit));
  14973                 if (rv < 0) {
  14974                     sal_free(PORT_SRC_MOD_EGR_PROFILE(unit));
  14975                     PORT_SRC_MOD_EGR_PROFILE(unit) = NULL;
  14976                     return rv;
  14977                 }
  14978             }
  14979         }
  14980     }
  14981 #endif /* BCM_TRIUMPH2_SUPPORT */
  14982 
  14983 #if defined(BCM_KATANA2_SUPPORT)
  14984     if (SOC_IS_KATANA2(unit)) {
  14985         /* Enable EGR_ENABLEm:PRT_ENABLEf for cpu port */
  14986         LOG_VERBOSE(BSL_LS_BCM_PORT,
  14987                     (BSL_META_U(unit,
  14988                                 "\nEnable EGR_ENABLEm:PRT_ENABLEf for cpu port \n")));
  14989         sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  14990         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  14991         SOC_IF_ERROR_RETURN(
  14992             WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, CMIC_PORT(unit), entry));
  14993         SOC_IF_ERROR_RETURN(
  14994             WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, LB_PORT(unit), entry));
  14995     }
  14996 #endif /* BCM_KATANA_SUPPORT */
  14997 
  14998     if (!soc_feature(unit, soc_feature_no_sw_rx_los)){
  14999     /* Get Initial SW RX LOS configuration from PHY driver */
  15000     PBMP_ITER(all_pbmp, p) {
  15001         if (IS_E_PORT(unit, p)) {
  15002             rv = bcm_esw_port_phy_control_get(unit, p,
  15003                                  BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS,
  15004                                  &rx_los);
  15005             if (BCM_SUCCESS(rv)) {
  15006                 PORT(unit, p).rx_los = rx_los;
  15007             }
  15008         }
  15009     }
  15010     }
  15011 
  15012     /* set link delay offset */
  15013     PBMP_ITER(all_pbmp, p) {
  15014         PORT(unit, p).link_delay_offset = 0;
  15015         if (SOC_WARM_BOOT(unit)) {
  15016             rv = bcm_esw_port_speed_get(unit, p, &p_speed);
  15017             if (BCM_FAILURE(rv)) {
  15018                 continue;
  15019             }
  15020             BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_recover(unit, p, p_speed));
  15021         }
  15022     }
  15023 
  15024     /* set port dscp map set to zero */
  15025     PBMP_ITER(all_pbmp, p) {
  15026         PORT(unit, p).port_dscp_map_set = 0;
  15027     }
  15028 
  15029 #ifdef BCM_TRIDENT2_SUPPORT
  15030     if (SOC_IS_TD2_TT2(unit)) {
  15031         /* Get Initial SW port enable status from HW */
  15032         PBMP_ITER(all_pbmp, p) {
  15033             if (IS_E_PORT(unit, p)) {
  15034                 rv = bcm_esw_port_enable_get(unit, p, &enable);
  15035                 if (BCM_SUCCESS(rv)) {
  15036                     PORT(unit, p).enable = enable;
  15037                 }
  15038             }
  15039         }
  15040     }
  15041 #endif /* BCM_TRIDENT2_SUPPORT */
  15042 
  15043     PBMP_PORT_ITER(unit, p) {
  15044         rv = bcm_esw_port_speed_get(unit, p, &p_speed);
  15045         if (BCM_FAILURE(rv)) {
  15046             continue;
  15047         }
  15048         _bcm_esw_port_link_delay_update(unit, p, p_speed);
  15049     }
  15050 
  15051 #if defined(BCM_TRIUMPH3_SUPPORT)
  15052     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  15053         rv = _bcm_port_force_forward_init(unit);
  15054         if (BCM_FAILURE(rv)) {
  15055             return rv;
  15056         }
  15057     }
  15058 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  15059 
  15060 #if defined(BCM_TOMAHAWK_SUPPORT)
  15061     /* TH ASF */
  15062     if (soc_feature(unit, soc_feature_asf_multimode)
  15063 #ifdef BCM_WARM_BOOT_SUPPORT
  15064         && !SOC_WARM_BOOT(unit)
  15065         /* WB recovery happens in _bcm_esw_port_wb_recover context */
  15066 #endif /* BCM_WARM_BOOT_SUPPORT */
  15067        ) {
  15068 #ifdef BCM_MAVERICK2_SUPPORT
  15069         if (SOC_IS_MAVERICK2(unit)) {
  15070             BCM_IF_ERROR_RETURN(
  15071                 _bcm_esw_mv2_asf_init(unit, _SOC_MV2_ASF_MODE_INIT));
  15072         } else
  15073 #endif
  15074 #ifdef BCM_TRIDENT3_SUPPORT
  15075         if (SOC_IS_TRIDENT3X(unit)) {
  15076             BCM_IF_ERROR_RETURN(
  15077                 _bcm_esw_td3_asf_init(unit, _SOC_TD3_ASF_MODE_INIT));
  15078         } else
  15079 #endif
  15080         {
  15081             BCM_IF_ERROR_RETURN(
  15082                 _bcm_esw_asf_init(unit, _SOC_TH_ASF_MODE_INIT));
  15083         }
  15084     }
  15085 #endif
  15086 
  15087 #if defined (BCM_EP_REDIRECT_VERSION_2)
  15088     /* Mark the RDB port as loopback mode */
  15089     if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  15090         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, PORT_TABm,
  15091                                        BCMI_EP_REDIRECT_PORT, PORT_TYPEf, 2));
  15092     }
  15093 #endif
  15094 
  15095 #ifdef BCM_PREEMPTION_SUPPORT
  15096     if (soc_feature(unit, soc_feature_preemption_cnt)) {
  15097         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_init(unit));
  15098     }
  15099 #endif
  15100 
  15101 #if defined(BCM_GREYHOUND_SUPPORT)
  15102     if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  15103         /*
  15104          * The ref_cnt of system-wise treat packet priority as dot1p priority
  15105          * for different packet types or port controls.
  15106          */
  15107         BCM_IF_ERROR_RETURN(
  15108             bcmi_esw_port_treat_pktpri_as_dot1p_init(unit));
  15109     }
  15110 #endif /* BCM_GREYHOUND_SUPPORT */
  15111 
  15112     if (SOC_WARM_BOOT(unit)) {
  15113         return (_bcm_esw_port_wb_recover(unit));
  15114     }
  15115 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
  15116     defined(BCM_APACHE_SUPPORT)
  15117     else {
  15118         if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2(unit) || SOC_IS_APACHE(unit)) {
  15119             /*
  15120              * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the
  15121              * congestion data is written as it is
  15122              * in FC_ST_TABLE, This we are doing so that
  15123              * congestion data is updated as it is how
  15124              * it recevied
  15125              */
  15126             for (index=0 ; index < soc_mem_index_count(unit,
  15127                         MMU_INTFI_ST_TRANS_TBLm); index++) {
  15128                 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  15129                             unit, MEM_BLOCK_ALL,index,
  15130                             &st_trans_entry));
  15131                 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  15132                         &st_trans_entry, FC_ST_XLATEf,
  15133                         index % (SOC_IS_KATANA2(unit) ? 256 : 16));
  15134                 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  15135                             unit, MEM_BLOCK_ALL, index,
  15136                             &st_trans_entry));
  15137             }
  15138         }
  15139     }
  15140 #endif
  15141 #if defined(BCM_GREYHOUND2_SUPPORT)
  15142     if (SOC_IS_GREYHOUND2(unit)) {
  15143         if (soc_feature(unit, soc_feature_e2efc)) {
  15144             bcmi_gh2_port_e2efc_remote_port_init(unit);
  15145         }
  15146     }
  15147 #endif /* BCM_GHREYHOUND2 */
  15148     return (_bcm_esw_port_wb_alloc(unit));
  15149 }
  15150 
  15151 /*
  15152  * Function:
  15153  *      bcm_port_clear
  15154  * Purpose:
  15155  *      Initialize the PORT interface layer for the specified SOC device
  15156  *      without resetting stacking ports.
  15157  * Parameters:
  15158  *      unit - StrataSwitch unit number.
  15159  * Returns:
  15160  *      BCM_E_NONE - success (or already initialized)
  15161  *      BCM_E_INTERNAL- failed to write PTABLE entries
  15162  *      BCM_E_MEMORY - failed to allocate required memory.
  15163  * Notes:
  15164  *      By default ports come up enabled. They can be made to come up disabled
  15165  *      at startup by a compile-time application policy flag in your Make.local
  15166  *      A call to bcm_port_clear should exhibit similar behavior for
  15167  *      non-stacking ethernet ports
  15168  *      PTABLE initialized.
  15169  */
  15170 
  15171 int
  15172 bcm_esw_port_clear(int unit)
  15173 {
  15174     bcm_port_config_t port_config;
  15175     bcm_pbmp_t reset_ports;
  15176     bcm_port_t port;
  15177     int rv, port_enable;
  15178 
  15179     PORT_INIT(unit);
  15180 
  15181     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config));
  15182 
  15183     /* Clear all non-stacking ethernet ports */
  15184     BCM_PBMP_ASSIGN(reset_ports, port_config.e);
  15185     BCM_PBMP_REMOVE(reset_ports, SOC_PBMP_STACK_CURRENT(unit));
  15186 
  15187     PBMP_ITER(reset_ports, port) {
  15188         LOG_VERBOSE(BSL_LS_BCM_PORT,
  15189                     (BSL_META_U(unit,
  15190                                 "bcm_port_clear: unit %d port %s\n"),
  15191                      unit, SOC_PORT_NAME(unit, port)));
  15192 
  15193         PORT_LOCK(unit);
  15194         if ((rv = _bcm_port_mode_setup(unit, port, TRUE)) < 0) {
  15195             LOG_WARN(BSL_LS_BCM_PORT,
  15196                      (BSL_META_U(unit,
  15197                                  "Warning: Port %s: "
  15198                                  "Failed to set initial mode: %s\n"),
  15199                       SOC_PORT_NAME(unit, port), bcm_errmsg(rv)));
  15200         }
  15201         PORT_UNLOCK(unit);
  15202 
  15203 #ifdef BCM_RCPU_SUPPORT
  15204         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  15205             /* Do not enable/disable rcpu port. */
  15206             continue;
  15207         }
  15208 #endif /* BCM_RCPU_SUPPORT */
  15209 
  15210         /*
  15211          * A compile-time application policy may prefer to disable
  15212          * ports at startup. The same behavior should be observed
  15213          * when bcm_port_clear gets called.
  15214          */
  15215 
  15216 #ifdef BCM_PORT_DEFAULT_DISABLE
  15217             port_enable = FALSE;
  15218 #else
  15219             port_enable = TRUE;
  15220 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  15221 
  15222 
  15223         if ((rv = bcm_esw_port_enable_set(unit, port, port_enable)) < 0) {
  15224             LOG_WARN(BSL_LS_BCM_PORT,
  15225                      (BSL_META_U(unit,
  15226                                  "Warning: Port %s: "
  15227                                  "Failed to %s port: %s\n"),
  15228                       SOC_PORT_NAME(unit, port),(port_enable) ?\
  15229                       "enable" : "disable" ,bcm_errmsg(rv)));
  15230         }
  15231 
  15232     }
  15233 
  15234     return BCM_E_NONE;
  15235 }
  15236 
  15237 /*
  15238  * Function:
  15239  *      _bcm_port_phy_probe
  15240  * Purpose:
  15241  *      Probe the phy and set up the phy of the indicated port
  15242  * Parameters:
  15243  *      unit - StrataSwitch unit number.
  15244  *      port - Port to probe
  15245  *      okay - Output parameter indicates port can be enabled.
  15246  * Returns:
  15247  *      BCM_E_NONE
  15248  *      BCM_E_INTERNAL - internal error.
  15249  * Notes:
  15250  *      If error is returned, the port should not be enabled.
  15251  */
  15252 int
  15253 _bcm_port_phy_probe(int unit, bcm_port_t port, int *okay)
  15254 {
  15255     int                 rv;
  15256     bcm_pbmp_t pbmp;
  15257     bcm_pbmp_t okay_pbmp;
  15258 
  15259     /* Check for PortMod */
  15260     if(SOC_PORT_USE_PORTCTRL(unit, port)) {
  15261         return BCM_E_UNAVAIL;
  15262     }
  15263 
  15264     *okay = FALSE;
  15265 
  15266     LOG_VERBOSE(BSL_LS_BCM_PORT,
  15267                 (BSL_META_U(unit,
  15268                             "Init port %d PHY...\n"), port));
  15269 
  15270     BCM_PBMP_CLEAR(okay_pbmp);
  15271     BCM_PBMP_CLEAR(pbmp);
  15272     BCM_PBMP_PORT_SET(pbmp, port);
  15273 
  15274     rv = soc_phyctrl_pbm_probe_init(unit,pbmp,&okay_pbmp);
  15275     if (rv  != BCM_E_NONE) {
  15276         LOG_ERROR(BSL_LS_BCM_PORT, \
  15277                   (BSL_META_U(unit, \
  15278                               "Error unit %d:\
  15279                               Failed port init probe: %s\n"),
  15280                    unit, bcm_errmsg(rv)));
  15281         return rv;
  15282     }
  15283 
  15284     if (!SOC_WARM_BOOT(unit)) {
  15285         /* Probe function should leave port disabled */
  15286         if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) {
  15287             return rv;
  15288         }
  15289     }
  15290 
  15291     *okay = TRUE;
  15292 
  15293     return BCM_E_NONE;
  15294 }
  15295 
  15296 /*
  15297  * Function:
  15298  *      _bcm_port_mac_init
  15299  * Purpose:
  15300  *      Set up the mac of the indicated port
  15301  * Parameters:
  15302  *      unit - StrataSwitch unit number.
  15303  *      port - Port to setup
  15304  *      okay - Output parameter indicates port can be enabled.
  15305  * Returns:
  15306  *      BCM_E_NONE
  15307  *      BCM_E_INTERNAL - internal error.
  15308  * Notes:
  15309  *      If error is returned, the port should not be enabled.
  15310  */
  15311 int
  15312 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay)
  15313 {
  15314     int                 rv;
  15315     mac_driver_t        *macd;
  15316 
  15317     /* Check for PortMod */
  15318     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  15319         return BCM_E_UNAVAIL;
  15320     }
  15321 
  15322     *okay = FALSE;
  15323 
  15324     LOG_VERBOSE(BSL_LS_BCM_PORT,
  15325                 (BSL_META_U(unit,
  15326                             "Init port %d MAC...\n"), port));
  15327 
  15328     if ((rv = soc_mac_probe(unit, port, &macd)) < 0) {
  15329         LOG_WARN(BSL_LS_BCM_PORT,
  15330                  (BSL_META_U(unit,
  15331                              "Port %s: Failed to probe MAC: %s\n"),
  15332                   SOC_PORT_NAME(unit, port), soc_errmsg(rv)));
  15333         return rv;
  15334     }
  15335 
  15336     PORT(unit, port).p_mac = macd;
  15337 
  15338     if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) {
  15339 
  15340 #ifdef BCM_RCPU_SUPPORT
  15341         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  15342             *okay = TRUE;
  15343             return BCM_E_NONE;
  15344         }
  15345 #endif /* BCM_RCPU_SUPPORT */
  15346 
  15347         if ((rv = MAC_INIT(PORT(unit, port).p_mac, unit, port)) < 0) {
  15348             LOG_WARN(BSL_LS_BCM_PORT,
  15349                      (BSL_META_U(unit,
  15350                                  "Port %s: Failed to initialize MAC: %s\n"),
  15351                       SOC_PORT_NAME(unit, port), soc_errmsg(rv)));
  15352             return rv;
  15353         }
  15354 
  15355         /* Probe function should leave port disabled */
  15356         if ((rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, 0)) < 0) {
  15357             return rv;
  15358         }
  15359     }
  15360 
  15361     *okay = TRUE;
  15362 
  15363     return BCM_E_NONE;
  15364 }
  15365 
  15366 /*
  15367  * Function:
  15368  *      _bcm_port_probe
  15369  * Purpose:
  15370  *      Probe the phy and set up the phy and mac of the indicated port
  15371  * Parameters:
  15372  *      unit - StrataSwitch unit number.
  15373  *      port - Port to probe
  15374  *      okay - Output parameter indicates port can be enabled.
  15375  * Returns:
  15376  *      BCM_E_NONE
  15377  *      BCM_E_INTERNAL - internal error.
  15378  * Notes:
  15379  *      If error is returned, the port should not be enabled.
  15380  */
  15381 
  15382 int
  15383 _bcm_port_probe(int unit, bcm_port_t port, int *okay)
  15384 {
  15385     /* Check for PortMod */
  15386     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  15387         return bcmi_esw_portctrl_probe(unit, port, 0, NULL, okay);
  15388     }
  15389 
  15390     BCM_IF_ERROR_RETURN(_bcm_port_phy_probe(unit, port, okay));
  15391 
  15392     /*
  15393      * Currently initializing MAC after PHY is required because of
  15394      * phy_5690_notify_init().
  15395      */
  15396     BCM_IF_ERROR_RETURN(_bcm_port_mac_init(unit, port, okay));
  15397 
  15398     return BCM_E_NONE;
  15399 }
  15400 
  15401 /*
  15402  * Function:
  15403  *      bcm_port_probe
  15404  * Purpose:
  15405  *      Probe the PHY and set up the PHY and MAC for the specified ports.
  15406  *      This is purely a discovery routine and does no configuration.
  15407  * Parameters:
  15408  *      unit - StrataSwitch unit number.
  15409  *      pbmp - Bitmap of ports to probe.
  15410  *      okay_pbmp (OUT) - Ports which were successfully probed.
  15411  * Returns:
  15412  *      BCM_E_NONE
  15413  *      BCM_E_INTERNAL - internal error.
  15414  * Notes:
  15415  *      If error is returned, the port should not be enabled.
  15416  *      Assumes port_init done.
  15417  *      Note that if a PHY is not present, the port will still probe
  15418  *      successfully.  The default driver will be installed.
  15419  */
  15420 int
  15421 bcm_esw_port_probe(int unit, pbmp_t pbmp, pbmp_t *okay_pbmp)
  15422 {
  15423     int rv = BCM_E_NONE;
  15424     bcm_port_t port;
  15425     int okay;
  15426     int skip_mac_reset = 0;
  15427     soc_persist_t      *sop;
  15428 #ifdef BCM_TRIDENT_SUPPORT
  15429     int port_speed;
  15430     soc_port_ability_t mac_ability;
  15431 #endif
  15432     pbmp_t pbmp_portmod;
  15433     pbmp_t pbmp_legacy;
  15434     pbmp_t okay_pbmp_portmod;
  15435     pbmp_t okay_pbmp_legacy;
  15436 
  15437     SOC_PBMP_CLEAR(*okay_pbmp);
  15438 
  15439     PORT_INIT(unit);
  15440     PORT_LOCK(unit);
  15441 
  15442     SOC_PBMP_CLEAR(pbmp_portmod);
  15443     SOC_PBMP_CLEAR(pbmp_legacy);
  15444     SOC_PBMP_CLEAR(okay_pbmp_portmod);
  15445     SOC_PBMP_CLEAR(okay_pbmp_legacy);
  15446     if (SOC_USE_PORTCTRL(unit)) {
  15447 #ifdef BCM_HURRICANE4_SUPPORT
  15448         if (SOC_IS_HURRICANE4(unit)) {
  15449             PBMP_ITER(pbmp, port) {
  15450                 if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  15451                     SOC_PBMP_PORT_ADD(pbmp_portmod, port);
  15452                 } else {
  15453                     SOC_PBMP_PORT_ADD(pbmp_legacy, port);
  15454                 }
  15455             }
  15456         } else
  15457 #endif
  15458         {
  15459             SOC_PBMP_ASSIGN(pbmp_portmod, pbmp);
  15460         }
  15461     } else {
  15462         SOC_PBMP_ASSIGN(pbmp_legacy, pbmp);
  15463     }
  15464 
  15465 #ifdef BCM_TOMAHAWK2_SUPPORT
  15466     if (SOC_IS_TOMAHAWK2(unit)) {
  15467         rv = bcmi_th2_tsc_xgxs_reset(unit, pbmp);
  15468         if (SOC_FAILURE(rv)) {
  15469             PORT_UNLOCK(unit);
  15470             return (rv);
  15471         }
  15472     } else
  15473 #endif /* BCM_TOMAHAWK2_SUPPORT */
  15474     {
  15475 #ifdef BCM_TRIDENT2_SUPPORT
  15476         if (SOC_IS_TD2_TT2(unit)) {
  15477             soc_info_t *si;
  15478             uint32 tsc_map, reset_tsc_map;
  15479             int tsc, ports[32];
  15480 
  15481             si = &SOC_INFO(unit);
  15482             /* Construct tsc_map covered by the specified pbmp */
  15483             tsc_map = 0;
  15484             PBMP_ITER(pbmp, port) {
  15485                 tsc = si->port_serdes[port];
  15486                 if (tsc != -1) {
  15487                     tsc_map |= 1 << tsc;
  15488                 }
  15489             }
  15490 
  15491             reset_tsc_map = 0;
  15492             PBMP_PORT_ITER(unit, port) {
  15493                 tsc = si->port_serdes[port];
  15494 #ifdef BCM_HURRICANE4_SUPPORT
  15495                 /* No TSC for EGPHY */
  15496                 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  15497                     continue;
  15498                 }
  15499 #endif
  15500                 if (tsc_map & (1 << tsc)) {
  15501                     if (PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES) {
  15502                         PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES;
  15503                         reset_tsc_map |= 1 << tsc;
  15504                         ports[tsc] = port;
  15505                     }
  15506                 }
  15507             }
  15508         for (tsc = 0; tsc < 32; tsc++) {
  15509             if (reset_tsc_map & (1 << tsc)) {
  15510                 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0);
  15511                 if (SOC_FAILURE(rv)) {
  15512                     PORT_UNLOCK(unit);
  15513                     return (rv);
  15514                 }
  15515             }
  15516         }
  15517     }
  15518 #endif /* BCM_TRIDENT2_SUPPORT */
  15519     }
  15520 #if defined(BCM_SABER2_SUPPORT)
  15521     /* If OAMP is enabled by default, skip the port init for oamp port */
  15522     if(SOC_IS_SABER2(unit)) {
  15523         int oamp_enable;
  15524         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  15525 
  15526         if (soc_feature(unit, soc_feature_sat) &&
  15527             ((!SOC_WARM_BOOT(unit) &&
  15528                 soc_property_get(unit, spn_SAT_ENABLE, 0)) ||
  15529              (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) {
  15530             SOC_PBMP_PORT_REMOVE(pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  15531             SOC_PBMP_PORT_REMOVE(*okay_pbmp,
  15532                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  15533         }
  15534     }
  15535 #endif
  15536     /* Check for PortMod */
  15537     if (SOC_USE_PORTCTRL(unit) && SOC_PBMP_NOT_NULL(pbmp_portmod)) {
  15538         rv = bcmi_esw_portctrl_probe_pbmp(unit, pbmp_portmod, &okay_pbmp_portmod);
  15539         SOC_PBMP_OR((*okay_pbmp), okay_pbmp_portmod);
  15540         if (SOC_FAILURE(rv) || SOC_PBMP_IS_NULL(pbmp_legacy)) {
  15541             PORT_UNLOCK(unit);
  15542             return (rv);
  15543         }
  15544     }
  15545 
  15546     rv = soc_phyctrl_pbm_probe_init(unit,pbmp_legacy,&okay_pbmp_legacy);
  15547     if (!SOC_WARM_BOOT(unit)) {
  15548         PBMP_ITER(okay_pbmp_legacy, port) {
  15549             /* Probe function should leave port disabled */
  15550             if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) {
  15551                 break;
  15552             }
  15553         }
  15554     }
  15555     if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE,
  15556                          (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) {
  15557         PBMP_ITER(okay_pbmp_legacy, port) {
  15558             if ((rv = bcm_esw_port_interface_get(unit, port, &(PORT(unit, port).intf))) < 0) {
  15559                 PORT(unit, port).intf = 0;
  15560                 continue;
  15561             }
  15562         }
  15563     }
  15564 
  15565     if (SOC_IS_GREYHOUND(unit) || SOC_IS_SABER2(unit) ||
  15566         SOC_IS_TOMAHAWKX(unit) || SOC_IS_APACHE(unit) ||
  15567         SOC_IS_HURRICANE4(unit)) {
  15568         /* XLPORT_MAC_CONTROLr.XMAC0_RESETf has been toggled duirng soc_reset */
  15569         skip_mac_reset = 1;
  15570     }
  15571 
  15572     if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) {
  15573         int blk;
  15574         uint32 rval;
  15575         pbmp_t block_pbmp;
  15576         int port_blk_index;
  15577         int i;
  15578 
  15579         SOC_BLOCK_ITER(unit, blk, SOC_BLK_GPORT) {
  15580             rval = 0;
  15581             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  15582             BCM_PBMP_AND(block_pbmp, pbmp);
  15583             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  15584                 continue;
  15585             }
  15586 
  15587             /* get the port number */
  15588             SOC_PBMP_ITER(block_pbmp, i)
  15589             {
  15590                /* get the index of the port in blk*/
  15591                port_blk_index = SOC_PORT_BLOCK_INDEX(unit, i);
  15592                rval |= 1 << port_blk_index;
  15593             }
  15594 
  15595             port = SOC_BLOCK_PORT(unit, blk);
  15596             /* just Write.. No need for RMW as no other field is there.. */
  15597             /* (void)READ_GPORT_UMAC_CONTROLr(unit, port, &rval); */
  15598             /* Set UMAC0_RESETf..UMAC7_RESETf */
  15599 #ifdef BCM_RCPU_SUPPORT
  15600             if (SOC_IS_RCPU_ONLY(unit) &&
  15601                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15602                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  15603                 rval &= ~ (1 << SOC_PORT_BLOCK_INDEX(unit, RCPU_PORT(unit)));
  15604             }
  15605 #endif /* BCM_RCPU_SUPPORT */
  15606             (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval);
  15607             sal_udelay(10);
  15608             rval = 0; /* Reset UMAC0_RESETf..UMAC7_RESETf */
  15609             (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval);
  15610         }
  15611     }
  15612 
  15613     if (SOC_REG_IS_VALID(unit, XLPORT_MAC_CONTROLr) && !skip_mac_reset) {
  15614         int blk, port;
  15615 
  15616         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  15617             port = SOC_BLOCK_PORT(unit, blk);
  15618             if (port == -1) {
  15619                 continue;
  15620             }
  15621 
  15622             if (SOC_INFO(unit).port_speed_max[port] >= 100000) {
  15623                 continue;
  15624             }
  15625 
  15626             /* Reset the entire block only if it is called from port init */
  15627             if (PORT(unit, port).p_mac != NULL) {
  15628                 continue;
  15629             }
  15630 
  15631 #ifdef BCM_RCPU_SUPPORT
  15632             if (SOC_IS_RCPU_ONLY(unit) &&
  15633                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15634                 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) {
  15635                 continue;
  15636             }
  15637 #endif /* BCM_RCPU_SUPPORT */
  15638 
  15639             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15640                 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  15641                                         XMAC0_RESETf, 1));
  15642             sal_udelay(10);
  15643             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15644                 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  15645                                         XMAC0_RESETf, 0));
  15646             if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  15647                 if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
  15648                     /* Disable MAC timestamp by default */
  15649                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15650                         (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  15651                                                 XLMAC_TS_DISABLEf, 1));
  15652                 }
  15653             }
  15654         }
  15655     }
  15656 
  15657     if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) {
  15658         int blk, port;
  15659 
  15660         SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) {
  15661             port = SOC_BLOCK_PORT(unit, blk);
  15662             if (port == -1) {
  15663                 continue;
  15664             }
  15665 
  15666             if (SOC_INFO(unit).port_speed_max[port] < 100000) {
  15667                 continue;
  15668             }
  15669 
  15670             /* Reset the entire block only if it is called from port init */
  15671             if (PORT(unit, port).p_mac != NULL) {
  15672                 continue;
  15673             }
  15674 
  15675 #ifdef BCM_RCPU_SUPPORT
  15676             if (SOC_IS_RCPU_ONLY(unit) &&
  15677                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15678                 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) {
  15679                 continue;
  15680             }
  15681 #endif /* BCM_RCPU_SUPPORT */
  15682 
  15683             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15684                 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port,
  15685                                         CMAC_RESETf, 1));
  15686             if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) {
  15687                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15688                  (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port,
  15689                                         CPORT_COREf, 1));
  15690             }
  15691             sal_udelay(10);
  15692             if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) {
  15693                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15694                  (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port,
  15695                                         CPORT_COREf, 0));
  15696             }
  15697             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15698                 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port,
  15699                                         CMAC_RESETf, 0));
  15700         }
  15701     }
  15702 
  15703     if (SOC_REG_IS_VALID(unit, XLPORT_XMAC_CONTROLr)) {
  15704         int blk;
  15705         uint32 rval;
  15706         pbmp_t block_pbmp;
  15707 
  15708         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  15709             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  15710             BCM_PBMP_AND(block_pbmp, pbmp);
  15711             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  15712                 continue;
  15713             }
  15714 
  15715             port = SOC_BLOCK_PORT(unit, blk);
  15716 
  15717             /* Reset the entire block only if it is called from port init */
  15718             if (PORT(unit, port).p_mac != NULL) {
  15719                 continue;
  15720             }
  15721 
  15722 #ifdef BCM_RCPU_SUPPORT
  15723             if (SOC_IS_RCPU_ONLY(unit) &&
  15724                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15725                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  15726                 continue;
  15727             }
  15728 #endif /* BCM_RCPU_SUPPORT */
  15729 
  15730             (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval);
  15731             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15732                               1);
  15733             (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15734             sal_udelay(10);
  15735 
  15736             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15737                               0);
  15738             (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15739         }
  15740     }
  15741 #ifdef BCM_SHADOW_SUPPORT
  15742     /* Interlaken need to be taken out of reset after PHY is initialized */
  15743     if (SOC_IS_SHADOW(unit)) {
  15744         int active_il = 0;
  15745         uint32 rval;
  15746 
  15747         if (soc_property_get(unit, spn_BCM88732_2X40_1X40, 0) ||
  15748             soc_property_get(unit, spn_BCM88732_8X10_1X40, 0)) {
  15749             active_il = 1;
  15750         } else {
  15751             if (soc_property_get(unit, spn_BCM88732_1X40_4X10, 0) ||
  15752                 soc_property_get(unit, spn_BCM88732_4X10_4X10, 0) ||
  15753                 soc_property_get(unit, spn_BCM88732_2X40_2X40, 0) ||
  15754                 soc_property_get(unit, spn_BCM88732_2X40_8X12, 0) ||
  15755                 soc_property_get(unit, spn_BCM88732_8X10_8X12, 0) ||
  15756                 soc_property_get(unit, spn_BCM88732_2X40_8X10, 0) ||
  15757                 soc_property_get(unit, spn_BCM88732_8X10_8X10, 0) ||
  15758                 soc_property_get(unit, spn_BCM88732_8X10_4X12, 0) ||
  15759                 soc_property_get(unit, spn_BCM88732_8X10_2X12, 0) ||
  15760                 soc_property_get(unit, spn_BCM88732_1X40_4X10_8X12, 0) ||
  15761                 soc_property_get(unit, spn_BCM88732_4X10_1X40_8X12, 0) ||
  15762                 soc_property_get(unit, spn_BCM88732_6X10_2X12, 0)) {
  15763                 active_il = 0;
  15764             } else {
  15765                 active_il = 2;
  15766             }
  15767         }
  15768         if (active_il) {
  15769             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15770                 (READ_IL_GLOBAL_CONTROLr(unit, 9, &rval));
  15771             soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0);
  15772             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15773                 (WRITE_IL_GLOBAL_CONTROLr(unit, 9, rval));
  15774         }
  15775         if (active_il == 2) {
  15776             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15777                 (READ_IL_GLOBAL_CONTROLr(unit, 13, &rval));
  15778             soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0);
  15779             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15780                 (WRITE_IL_GLOBAL_CONTROLr(unit, 13, rval));
  15781         }
  15782     }
  15783 #endif /* BCM_SHADOW_SUPPORT */
  15784 
  15785     if (SOC_REG_IS_VALID(unit, XPORT_XMAC_CONTROLr)) {
  15786         int blk;
  15787         uint32 rval;
  15788         pbmp_t block_pbmp;
  15789 
  15790         SOC_BLOCK_ITER(unit, blk, SOC_BLK_MXQPORT) {
  15791             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  15792             BCM_PBMP_AND(block_pbmp, pbmp);
  15793             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  15794                 continue;
  15795             }
  15796 
  15797             port = SOC_BLOCK_PORT(unit, blk);
  15798 
  15799             /* Reset the entire block only if it is called from port init */
  15800             if (PORT(unit, port).p_mac != NULL) {
  15801                 continue;
  15802             }
  15803 
  15804 #ifdef BCM_RCPU_SUPPORT
  15805             if (SOC_IS_RCPU_ONLY(unit) &&
  15806                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15807                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  15808                 continue;
  15809             }
  15810 #endif /* BCM_RCPU_SUPPORT */
  15811 
  15812             (void)READ_XPORT_XMAC_CONTROLr(unit, port, &rval);
  15813             soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15814                               1);
  15815             (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval);
  15816             sal_udelay(10);
  15817 
  15818             soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15819                               0);
  15820             (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval);
  15821         }
  15822     }
  15823 
  15824 #ifdef BCM_TRIUMPH3_SUPPORT
  15825     if (SOC_IS_TRIUMPH3(unit)) {
  15826         uint8 rev_id;
  15827         uint16 dev_id;
  15828         soc_info_t *si;
  15829         soc_port_t port;
  15830         int phy, lane, blk, block_has_ports, high_speed_port;
  15831         uint32 rval;
  15832 
  15833         si = &SOC_INFO(unit);
  15834         soc_cm_get_id(unit, &dev_id, &rev_id);
  15835         SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
  15836             block_has_ports = FALSE;
  15837             high_speed_port = -1;
  15838             for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) {
  15839                 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15840                     port = si->port_p2l_mapping[si->blk_fpp[blk] +
  15841                                ((phy * _SOC_TR3_LANES_PER_PHY) + lane)];
  15842                     /* coverity[overrun-local : FALSE] */
  15843                     if (SOC_PORT_VALID(unit, port) &&
  15844                         si->port_speed_max[port] >= 100000) {
  15845                         /* Save the 100G+ speed port becuase we must
  15846                          * init the other two PHYs, even though they don't
  15847                          * match a valid port. */
  15848                         high_speed_port = port;
  15849                     } else if (high_speed_port >= 0) {
  15850                         port = high_speed_port;
  15851                     }
  15852                     if (SOC_PORT_VALID(unit, port)) {
  15853                         block_has_ports |= 1 << phy;
  15854                         break; /* Only need to reset PHY once */
  15855                     }
  15856                 }
  15857             }
  15858             if (!block_has_ports) {
  15859                 continue; /* All ports disabled */
  15860             }
  15861             port = SOC_BLOCK_PORT(unit, blk);
  15862 
  15863             /* Reset only when called from port init */
  15864             if (PORT(unit, port).p_mac != NULL) {
  15865                 continue;
  15866             }
  15867 
  15868             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15869             if (SOC_FAILURE(rv)) {
  15870                 PORT_UNLOCK(unit);
  15871                 return (rv);
  15872             }
  15873             if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) {
  15874                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15875                                   CMAC_RESETf, 1);
  15876             }
  15877             if (block_has_ports & 1) {
  15878                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15879                                   XMAC0_RESETf, 1);
  15880             }
  15881             if (block_has_ports & 2) {
  15882                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15883                                   XMAC1_RESETf, 1);
  15884             }
  15885             if (block_has_ports & 4) {
  15886                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15887                                   XMAC2_RESETf, 1);
  15888             }
  15889             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15890             if (SOC_FAILURE(rv)) {
  15891                 PORT_UNLOCK(unit);
  15892                 return (rv);
  15893             }
  15894 
  15895             sal_udelay(10);
  15896             if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) {
  15897                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15898                                   CMAC_RESETf, 0);
  15899             }
  15900             if (block_has_ports & 1) {
  15901                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15902                                   XMAC0_RESETf, 0);
  15903             }
  15904             if (block_has_ports & 2) {
  15905                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15906                                   XMAC1_RESETf, 0);
  15907             }
  15908             if (block_has_ports & 4) {
  15909                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15910                                   XMAC2_RESETf, 0);
  15911             }
  15912             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15913             if (SOC_FAILURE(rv)) {
  15914                 PORT_UNLOCK(unit);
  15915                 return (rv);
  15916             }
  15917         }
  15918         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XTPORT) {
  15919             block_has_ports = FALSE;
  15920             for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) {
  15921                 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15922                     port = si->port_p2l_mapping[si->blk_fpp[blk] +
  15923                                ((phy * _SOC_TR3_LANES_PER_PHY) + lane)];
  15924                     if (SOC_PORT_VALID(unit, port)) {
  15925                         block_has_ports |= 1 << phy;
  15926                         break; /* Only need to reset PHY once */
  15927                     }
  15928                 }
  15929             }
  15930             if (!block_has_ports) {
  15931                 continue; /* All ports disabled */
  15932             }
  15933             port = SOC_BLOCK_PORT(unit, blk);
  15934 
  15935             /* Reset only when called from port init */
  15936             if (PORT(unit, port).p_mac != NULL) {
  15937                 continue;
  15938             }
  15939 
  15940             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15941             if (SOC_FAILURE(rv)) {
  15942                 PORT_UNLOCK(unit);
  15943                 return (rv);
  15944             }
  15945             if (block_has_ports & 1) {
  15946                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15947                                   XMAC0_RESETf, 1);
  15948             }
  15949             if (block_has_ports & 2) {
  15950                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15951                                   XMAC1_RESETf, 1);
  15952             }
  15953             if (block_has_ports & 4) {
  15954                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15955                                   XMAC2_RESETf, 1);
  15956             }
  15957             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15958             if (SOC_FAILURE(rv)) {
  15959                 PORT_UNLOCK(unit);
  15960                 return (rv);
  15961             }
  15962             sal_udelay(10);
  15963             if (block_has_ports & 1) {
  15964                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15965                                   XMAC0_RESETf, 0);
  15966             }
  15967             if (block_has_ports & 2) {
  15968                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15969                                   XMAC1_RESETf, 0);
  15970             }
  15971             if (block_has_ports & 4) {
  15972                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15973                                   XMAC2_RESETf, 0);
  15974             }
  15975             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15976             if (SOC_FAILURE(rv)) {
  15977                 PORT_UNLOCK(unit);
  15978                 return (rv);
  15979             }
  15980         }
  15981         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  15982             block_has_ports = FALSE;
  15983             /* Only one PHY per XLPORT */
  15984             for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15985                 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane];
  15986                 if (SOC_PORT_VALID(unit, port)) {
  15987                     block_has_ports = TRUE;
  15988                     break;
  15989                 }
  15990             }
  15991             if (!block_has_ports) {
  15992                 continue; /* All ports disabled */
  15993             }
  15994             port = SOC_BLOCK_PORT(unit, blk);
  15995 
  15996             /* Reset only when called from port init */
  15997             if (PORT(unit, port).p_mac != NULL) {
  15998                 continue;
  15999             }
  16000 
  16001             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  16002             if (SOC_FAILURE(rv)) {
  16003                 PORT_UNLOCK(unit);
  16004                 return (rv);
  16005             }
  16006             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  16007                               XMAC0_RESETf, 1);
  16008             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  16009             if (SOC_FAILURE(rv)) {
  16010                 PORT_UNLOCK(unit);
  16011                 return (rv);
  16012             }
  16013             sal_udelay(10);
  16014             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  16015                               XMAC0_RESETf, 0);
  16016             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  16017             if (SOC_FAILURE(rv)) {
  16018                 PORT_UNLOCK(unit);
  16019                 return (rv);
  16020             }
  16021         }
  16022 #ifdef BCM_HELIX4_SUPPORT
  16023         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XWPORT) {
  16024             block_has_ports = FALSE;
  16025             /* Only one PHY per XWPORT */
  16026             for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  16027                 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane];
  16028                 if (SOC_PORT_VALID(unit, port)) {
  16029                     block_has_ports = TRUE;
  16030                     break;
  16031                 }
  16032             }
  16033             if (!block_has_ports) {
  16034                 continue; /* All ports disabled */
  16035             }
  16036             port = SOC_BLOCK_PORT(unit, blk);
  16037 
  16038             /* Reset only when called from port init */
  16039             if (PORT(unit, port).p_mac != NULL) {
  16040                 continue;
  16041             }
  16042 
  16043             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  16044             if (SOC_FAILURE(rv)) {
  16045                 PORT_UNLOCK(unit);
  16046                 return (rv);
  16047             }
  16048             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  16049                               XMAC0_RESETf, 1);
  16050             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  16051             if (SOC_FAILURE(rv)) {
  16052                 PORT_UNLOCK(unit);
  16053                 return (rv);
  16054             }
  16055             sal_udelay(10);
  16056             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  16057                               XMAC0_RESETf, 0);
  16058             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  16059             if (SOC_FAILURE(rv)) {
  16060                 PORT_UNLOCK(unit);
  16061                 return (rv);
  16062             }
  16063         }
  16064 #endif /* BCM_HELIX4_SUPPORT */
  16065     }
  16066 #endif /* BCM_TRIUMPH3_SUPPORT */
  16067 
  16068     PBMP_ITER(pbmp_legacy, port) {
  16069         if (!(IS_TDM_PORT(unit, port)) &&
  16070             !SOC_PORT_USE_PORTCTRL(unit, port)) {
  16071             rv = _bcm_port_mac_init(unit, port, &okay);
  16072 
  16073             if (!okay) {
  16074                 SOC_PBMP_PORT_REMOVE(okay_pbmp_legacy, port);
  16075 #if defined(BCM_ESW_SUPPORT)
  16076                 soc_counter_port_pbmp_remove(unit, port);
  16077 #endif
  16078             }
  16079             if (rv < 0) {
  16080                 LOG_WARN(BSL_LS_BCM_PORT,
  16081                         (BSL_META_U(unit,
  16082                                     "MAC init failed on port %s\n"),
  16083                          SOC_PORT_NAME(unit, port)));
  16084                 break;
  16085             }
  16086 
  16087 #ifdef BCM_TRIDENT_SUPPORT
  16088             if (SOC_IS_TD_TT(unit) &&
  16089                (!SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) &&
  16090                (!(SOC_IS_HURRICANE4(unit) && SOC_WARM_BOOT(unit)))) {
  16091                 soc_ipg_t *si;
  16092                 int ifg, duplex;
  16093 
  16094                 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex);
  16095                 if (rv < 0) {
  16096                     LOG_WARN(BSL_LS_BCM_PORT,
  16097                             (BSL_META_U(unit,
  16098                                         "MAC_DUPLEX_GET failed on port %s\n"),
  16099                              SOC_PORT_NAME(unit, port)));
  16100                     break;
  16101                 }
  16102 
  16103                 si = &SOC_PERSIST(unit)->ipg[port];
  16104                 if (IS_HG_PORT(unit, port)) {
  16105                     ifg = si->fd_hg = SOC_AVERAGE_IPG_HG;
  16106                 } else {
  16107                     ifg = si->fd_xe = SOC_AVERAGE_IPG_IEEE;
  16108                 }
  16109 
  16110                 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_HURRICANE4(unit)) {
  16111                     port_speed = (0 != SOC_INFO(unit).port_init_speed[port]) ?
  16112                         SOC_INFO(unit).port_init_speed[port] : SOC_INFO(unit).port_speed_max[port];
  16113                 } else if (SOC_IS_TRIDENT2(unit)) {
  16114                     sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t));
  16115                     rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port,
  16116                             &mac_ability);
  16117                     if (rv < 0) {
  16118                         LOG_WARN(BSL_LS_BCM_PORT,
  16119                                 (BSL_META_U(unit,
  16120                                             "MAC_ABILITY_LOCAL_GET failed on port %s\n"),
  16121                                  SOC_PORT_NAME(unit, port)));
  16122                         break;
  16123                     }
  16124                     port_speed = BCM_PORT_ABILITY_SPEED_MAX(mac_ability.speed_full_duplex);
  16125                 } else {
  16126                     port_speed = SOC_INFO(unit).port_speed_max[port];
  16127                 }
  16128 
  16129                 rv = MAC_IFG_SET(PORT(unit, port).p_mac, unit, port,
  16130                         port_speed, duplex, ifg);
  16131                 if (rv < 0) {
  16132                     LOG_WARN(BSL_LS_BCM_PORT,
  16133                             (BSL_META_U(unit,
  16134                                         "MAC_IFG_SET failed on port %s\n"),
  16135                              SOC_PORT_NAME(unit, port)));
  16136                     break;
  16137                 }
  16138             }
  16139 #endif
  16140 #ifdef BCM_HURRICANE4_SUPPORT
  16141             if (SOC_IS_HURRICANE4(unit) && (!SOC_WARM_BOOT(unit))) {
  16142                 rv = MAC_FRAME_MAX_SET(PORT(unit, port).p_mac,
  16143                                        unit, port, SOC_INFO(unit).max_mtu);
  16144                 if (rv < 0) {
  16145                     LOG_WARN(BSL_LS_BCM_PORT,
  16146                              (BSL_META_U(unit,
  16147                                          "MAC_FRAME_MAX_SET failed on port %s\n"),
  16148                               SOC_PORT_NAME(unit, port)));
  16149                     break;
  16150                 }
  16151             }
  16152 #endif
  16153         }
  16154 
  16155         /* This is needed for run-time probing */
  16156         sop = SOC_PERSIST(unit);
  16157         if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  16158             SOC_PBMP_PORT_ADD(sop->lc_pbm_fc, port);
  16159         } else {
  16160             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port);
  16161         }
  16162 
  16163         /* Check if the external phy is set in EBE/EtherRAM buffer mode */
  16164         if (soc_property_port_get(unit, port, spn_PHY_OPERATIONAL_MODE, 0) == 3) {
  16165             SOC_PBMP_PORT_ADD(sop->lc_pbm_eth_buffer_mode, port);
  16166         } else {
  16167             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_eth_buffer_mode, port);
  16168         }
  16169 
  16170     }
  16171 
  16172     SOC_PBMP_OR((*okay_pbmp), okay_pbmp_legacy);
  16173 
  16174     PORT_UNLOCK(unit);
  16175 
  16176     return rv;
  16177 }
  16178 
  16179 /*
  16180  * Function:
  16181  *      _bcm_port_detach
  16182  * Purpose:
  16183  *      Main part of bcm_port_detach
  16184  */
  16185 
  16186 int
  16187 _bcm_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached)
  16188 {
  16189     bcm_port_t          port;
  16190     int                 rv;
  16191     soc_persist_t       *sop = SOC_PERSIST(unit);
  16192 
  16193     SOC_PBMP_CLEAR(*detached);
  16194 
  16195     PBMP_ITER(pbmp, port) {
  16196         BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, BCM_STG_STP_DISABLE));
  16197         PORT_LOCK(unit);
  16198         rv = _bcm_port_mode_setup(unit, port, FALSE);
  16199         PORT_UNLOCK(unit);
  16200         BCM_IF_ERROR_RETURN(rv);
  16201         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  16202         SOC_PBMP_PORT_ADD(*detached, port);
  16203 
  16204         if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) {
  16205             /* Bring down the internal PHY */
  16206             rv = bcm_esw_port_update(unit, port, FALSE);
  16207             BCM_IF_ERROR_RETURN(rv);
  16208             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port);
  16209         }
  16210     }
  16211 #ifdef BCM_TRIUMPH2_SUPPORT
  16212     if (soc_feature(unit, soc_feature_vpd_profile)) {
  16213         _bcm_tr2_port_vpd_bitmap_free(unit);
  16214     }
  16215 #endif
  16216     return BCM_E_NONE;
  16217 }
  16218 
  16219 /*
  16220  * Function:
  16221  *      bcm_port_detach
  16222  * Purpose:
  16223  *      Detach a port.  Set phy driver to no connection.
  16224  * Parameters:
  16225  *      unit - StrataSwitch unit number.
  16226  *      pbmp - Bitmap of ports to detach.
  16227  *      detached (OUT) - Bitmap of ports successfully detached.
  16228  * Returns:
  16229  *      BCM_E_NONE
  16230  *      BCM_E_INTERNAL - internal error.
  16231  * Notes:
  16232  *      If a port to be detached does not appear in detached, its
  16233  *      state is not defined.
  16234  */
  16235 
  16236 int
  16237 bcm_esw_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached)
  16238 {
  16239     int         rv;
  16240 #ifdef  BROADCOM_DEBUG
  16241     char        pfmtp[SOC_PBMP_FMT_LEN],
  16242                 pfmtd[SOC_PBMP_FMT_LEN];
  16243 #endif  /* BROADCOM_DEBUG */
  16244     pbmp_t pbmp_portmod;
  16245     pbmp_t pbmp_legacy;
  16246     pbmp_t detached_portmod;
  16247     pbmp_t detached_legacy;
  16248 
  16249     PORT_INIT(unit);
  16250 
  16251     if (detached == NULL) {
  16252         return BCM_E_PARAM;
  16253     }
  16254 
  16255     SOC_PBMP_CLEAR(pbmp_portmod);
  16256     SOC_PBMP_CLEAR(pbmp_legacy);
  16257     SOC_PBMP_CLEAR(detached_portmod);
  16258     SOC_PBMP_CLEAR(detached_legacy);
  16259     SOC_PBMP_CLEAR(*detached);
  16260 
  16261     if (SOC_USE_PORTCTRL(unit)) {
  16262 #ifdef BCM_HURRICANE4_SUPPORT
  16263         if (SOC_IS_HURRICANE4(unit)) {
  16264             bcm_port_t port;
  16265             PBMP_ITER(pbmp, port) {
  16266                 if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  16267                     SOC_PBMP_PORT_ADD(pbmp_portmod, port);
  16268                 } else {
  16269                     SOC_PBMP_PORT_ADD(pbmp_legacy, port);
  16270                 }
  16271             }
  16272         } else
  16273 #endif
  16274         {
  16275             SOC_PBMP_ASSIGN(pbmp_portmod, pbmp);
  16276         }
  16277     } else {
  16278         SOC_PBMP_ASSIGN(pbmp_legacy, pbmp);
  16279     }
  16280 
  16281     if (SOC_USE_PORTCTRL(unit) && SOC_PBMP_NOT_NULL(pbmp_portmod)) {
  16282         rv = bcmi_esw_portctrl_detach(unit, pbmp_portmod, &detached_portmod);
  16283         SOC_PBMP_OR((*detached), detached_portmod);
  16284         if (SOC_FAILURE(rv) || SOC_PBMP_IS_NULL(pbmp_legacy)) {
  16285             return (rv);
  16286         }
  16287     }
  16288 
  16289     PORT_LOCK(unit);
  16290     rv = _bcm_port_detach(unit, pbmp_legacy, &detached_legacy);
  16291     PORT_UNLOCK(unit);
  16292     SOC_PBMP_OR((*detached), detached_legacy);
  16293 #ifdef  BROADCOM_DEBUG
  16294     LOG_INFO(BSL_LS_BCM_PORT,
  16295              (BSL_META_U(unit,
  16296                          "bcm_port_detach: u=%d pbmp=%s det=%s rv=%d\n"),
  16297                          unit,
  16298               SOC_PBMP_FMT(pbmp, pfmtp),
  16299               SOC_PBMP_FMT(*detached, pfmtd),
  16300               rv));
  16301 #endif
  16302     return rv;
  16303 }
  16304 
  16305 /*
  16306  * Function:
  16307  *      bcm_port_config_get
  16308  * Purpose:
  16309  *      Get port configuration of a device
  16310  * Parameters:
  16311  *      unit - StrataSwitch Unit #.
  16312  *      config - (OUT) Structure returning configuration
  16313  * Returns:
  16314  *      BCM_E_XXX
  16315  */
  16316 
  16317 int
  16318 bcm_esw_port_config_get(int unit, bcm_port_config_t *config)
  16319 {
  16320     int i;
  16321 
  16322     PORT_INIT(unit);
  16323     PORT_LOCK(unit);
  16324 
  16325     config->fe          = PBMP_FE_ALL(unit);
  16326     config->ge          = PBMP_GE_ALL(unit);
  16327     config->xe          = PBMP_XE_ALL(unit);
  16328     config->ce          = PBMP_CE_ALL(unit);
  16329     config->cd          = PBMP_CDE_ALL(unit);
  16330     config->e           = PBMP_E_ALL(unit);
  16331     config->hg          = PBMP_HG_ALL(unit);
  16332     config->tdm         = PBMP_TDM_ALL(unit);
  16333     config->port        = PBMP_PORT_ALL(unit);
  16334     config->cpu         = PBMP_CMIC(unit);
  16335     config->roe         = PBMP_ROE_ALL(unit);
  16336     config->all         = PBMP_ALL(unit);
  16337     /* Remove LB and RDB port from the PBMP_ALL bitmap for backward compatibility */
  16338     SOC_PBMP_REMOVE(config->all, PBMP_LB(unit));
  16339     SOC_PBMP_REMOVE(config->all, PBMP_RDB_ALL(unit));
  16340     SOC_PBMP_REMOVE(config->all, PBMP_FAE_ALL(unit));
  16341 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_HURRICANE4_SUPPORT)
  16342     if (SOC_IS_MONTEREY(unit) || SOC_IS_HURRICANE4(unit)) {
  16343         SOC_PBMP_REMOVE(config->all, PBMP_MACSEC_ALL(unit));
  16344     }
  16345 #endif
  16346     config->stack_ext   = PBMP_ST_ALL(unit);
  16347 
  16348 
  16349     BCM_PBMP_CLEAR(config->stack_int);
  16350     BCM_PBMP_CLEAR(config->sci);
  16351     BCM_PBMP_CLEAR(config->sfi);
  16352     BCM_PBMP_CLEAR(config->spi);
  16353     BCM_PBMP_CLEAR(config->spi_subport);
  16354 
  16355     for (i = 0; i < NUM_PIPE(unit); i++) {
  16356         config->per_pipe[i] = PBMP_PIPE(unit, i);
  16357         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_LB(unit));
  16358         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_RDB_ALL(unit));
  16359         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_FAE_ALL(unit));
  16360 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_HURRICANE4_SUPPORT)
  16361         if (SOC_IS_MONTEREY(unit) || SOC_IS_HURRICANE4(unit)) {
  16362             SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_MACSEC_ALL(unit));
  16363         }
  16364 #endif
  16365     }
  16366 
  16367 #if defined(BCM_SABER2_SUPPORT)
  16368     /* Remove OAMP port from port config list */
  16369     if(SOC_IS_SABER2(unit)) {
  16370         soc_info_t *si = &SOC_INFO(unit);
  16371         bcm_port_t oamp_port = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER;
  16372 
  16373         if(bcm_common_oamp_port_enable_get(unit, oamp_port)) {
  16374             SOC_PBMP_PORT_REMOVE(config->port, oamp_port);
  16375             SOC_PBMP_PORT_REMOVE(config->e, oamp_port);
  16376 
  16377             if(si->port_speed_max[oamp_port] < 10000) {
  16378                 SOC_PBMP_PORT_REMOVE(config->ge, oamp_port);
  16379             } else {
  16380                 SOC_PBMP_PORT_REMOVE(config->xe, oamp_port);
  16381             }
  16382         }
  16383     }
  16384 #endif
  16385 
  16386 #if defined(BCM_TRIUMPH3_SUPPORT)
  16387     if (SOC_IS_TRIUMPH3(unit)) {
  16388         config->control = soc_tr3_get_control_port_bitmap(unit);
  16389     }
  16390 #endif
  16391 
  16392 #if defined(BCM_KATANA2_SUPPORT)
  16393     if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) ||
  16394         soc_feature(unit, soc_feature_subtag_coe))) {
  16395         _bcm_kt2_subport_pbmp_update(unit, &(config->all));
  16396     }
  16397 #endif
  16398 
  16399     PORT_UNLOCK(unit);
  16400     return BCM_E_NONE;
  16401 }
  16402 
  16403 STATIC int
  16404 _bcm_td_port_mode_update(int unit, bcm_port_t port, int speed)
  16405 {
  16406     soc_info_t *si;
  16407     int enable[2], duplex[2], loopback[2], pause_tx[2], pause_rx[2];
  16408     int frame_max[2], encap[2];
  16409     sal_mac_addr_t address[2];
  16410     bcm_port_t port_list[2], phy_port, cur_port;
  16411     uint32 rval;
  16412     int core_mode, phy_mode, old_phy_mode;
  16413     int i;
  16414 
  16415     /* Get the original phy_mode */
  16416     SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval));
  16417     core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  16418                                   CORE_PORT_MODEf);
  16419     old_phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  16420                                      PHY_PORT_MODEf);
  16421 
  16422     si = &SOC_INFO(unit);
  16423     /* speed is the only factor to determine phy_mode */
  16424     if ((speed > 20000) && si->port_speed_max[port] > 20000){
  16425         phy_mode = 0;
  16426     } else if (speed > 10000) {
  16427         if ((si->port_num_lanes[port] == 1) && (speed == 11000) &&
  16428             IS_HG_PORT(unit, port)) {
  16429             phy_mode = 2;
  16430         } else {
  16431             phy_mode = 1;
  16432         }
  16433     } else {
  16434         if ((si->port_num_lanes[port] == 2) && (speed == 10000) &&
  16435             IS_HG_PORT(unit, port)) {
  16436             phy_mode = 1; /* Warpcore uses DXGXS 10.5G in HG mode */
  16437         } else if ((si->port_num_lanes[port] == 4) && (speed == 10000)) {
  16438             phy_mode = 2;
  16439             core_mode = 0;
  16440         } else {
  16441             phy_mode = 2;
  16442         }
  16443     }
  16444 
  16445     if (phy_mode == old_phy_mode) {
  16446         return BCM_E_NONE;
  16447     }
  16448 
  16449     port_list[0] = port;
  16450     port_list[1] = -1;
  16451     if (core_mode == 1) { /* dual mode */
  16452         si = &SOC_INFO(unit);
  16453         phy_port = si->port_l2p_mapping[port];
  16454         port_list[1] = si->port_p2l_mapping[((phy_port - 1) ^ 2) + 1];
  16455     }
  16456     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode);
  16457     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode);
  16458     SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  16459 
  16460     /* Retain MAC setting */
  16461     for (i = 0; i < 2; i++) {
  16462         if (port_list[i] == -1) {
  16463             continue;
  16464         }
  16465         cur_port = port_list[i];
  16466 
  16467         /* no need to save speed since speed change trigger this, in addition,
  16468          * mac may not be able to tell you exact speed in many cases */
  16469         SOC_IF_ERROR_RETURN
  16470             (MAC_DUPLEX_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16471                             &duplex[i]));
  16472         SOC_IF_ERROR_RETURN
  16473             (MAC_PAUSE_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16474                            &pause_tx[i], &pause_rx[i]));
  16475         SOC_IF_ERROR_RETURN
  16476             (MAC_PAUSE_ADDR_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16477                                 address[i]));
  16478         SOC_IF_ERROR_RETURN
  16479             (MAC_FRAME_MAX_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16480                                &frame_max[i]));
  16481         /* not saving ifg setting */
  16482         SOC_IF_ERROR_RETURN
  16483             (MAC_ENCAP_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16484                            &encap[i]));
  16485         SOC_IF_ERROR_RETURN
  16486             (MAC_LOOPBACK_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16487                               &loopback[i]));
  16488         SOC_IF_ERROR_RETURN
  16489             (MAC_ENABLE_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16490                             &enable[i]));
  16491     }
  16492 
  16493     /* Do XMAC hard reset when phy_mode changed */
  16494     (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval);
  16495     soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
  16496     (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  16497     sal_udelay(10);
  16498     soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
  16499     (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  16500 
  16501     for (i = 0; i < 2; i++) {
  16502         if (port_list[i] == -1) {
  16503             continue;
  16504         }
  16505         cur_port = port_list[i];
  16506 
  16507         /* mac init */
  16508         SOC_IF_ERROR_RETURN
  16509             (MAC_INIT(PORT(unit, cur_port).p_mac, unit, cur_port));
  16510 
  16511         /* Restore MAC setting */
  16512         /* no need to save speed since speed change trigger this, in addition,
  16513          * mac may not be able to tell you exact speed in many cases */
  16514         /* coverity[uninit_use_in_call] : FALSE */
  16515         SOC_IF_ERROR_RETURN
  16516             (MAC_DUPLEX_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16517                             duplex[i]));
  16518         /* coverity[uninit_use_in_call] : FALSE */
  16519         SOC_IF_ERROR_RETURN
  16520             (MAC_PAUSE_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16521                            pause_tx[i], pause_rx[i]));
  16522         SOC_IF_ERROR_RETURN
  16523             (MAC_PAUSE_ADDR_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16524                                 address[i]));
  16525         /* coverity[uninit_use_in_call] : FALSE */
  16526         SOC_IF_ERROR_RETURN
  16527             (MAC_FRAME_MAX_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16528                                frame_max[i]));
  16529         /* not saving ifg setting */
  16530         /* coverity[uninit_use_in_call] : FALSE */
  16531         SOC_IF_ERROR_RETURN
  16532             (MAC_ENCAP_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16533                            encap[i]));
  16534         /* coverity[uninit_use_in_call] : FALSE */
  16535         SOC_IF_ERROR_RETURN
  16536             (MAC_LOOPBACK_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16537                               loopback[i]));
  16538         /* coverity[uninit_use_in_call] : FALSE */
  16539         SOC_IF_ERROR_RETURN
  16540             (MAC_ENABLE_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  16541                             enable[i]));
  16542     }
  16543 
  16544     return BCM_E_NONE;
  16545 }
  16546 
  16547 STATIC int
  16548 _bcm_tx_roe_port_update(int unit, bcm_port_t port, int link)
  16549 {
  16550 
  16551     /* Call Port Control module */
  16552     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  16553         return bcmi_esw_tx_roe_portctrl_update(unit, port, link);
  16554     }
  16555     return BCM_E_NONE;
  16556 }
  16557 
  16558 STATIC int
  16559 _bcm_rx_roe_port_update(int unit, bcm_port_t port, int link)
  16560 {
  16561 
  16562     /* Call Port Control module */
  16563     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  16564         return bcmi_esw_rx_roe_portctrl_update(unit, port, link);
  16565     }
  16566     return BCM_E_NONE;
  16567 }
  16568 /*
  16569  * Function:
  16570  *      _bcm_port_update
  16571  * Purpose:
  16572  *      Get port characteristics from PHY and program MAC to match.
  16573  * Parameters:
  16574  *      unit - StrataSwitch Unit #.
  16575  *      port - StrataSwitch port #.
  16576  *      link -  True if link is active, false if link is inactive.
  16577  * Returns:
  16578  *      BCM_E_NONE
  16579  *      BCM_E_XXX
  16580  */
  16581 
  16582 STATIC int
  16583 _bcm_port_update(int unit, bcm_port_t port, int link)
  16584 {
  16585     int                 rv;
  16586     int                 duplex, speed, an, an_done;
  16587     soc_port_if_t       pif;
  16588     int                 cur_mac_speed;
  16589     int                 enable;
  16590 #ifdef INCLUDE_MACSEC
  16591     int                 policy = 0;
  16592     int                 duplex_old = 0;
  16593 #endif
  16594 #ifdef INCLUDE_FCMAP
  16595     phy_ctrl_t *pc;
  16596 #endif
  16597 
  16598     /* Call Port Control module */
  16599     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  16600         return bcmi_esw_portctrl_update(unit, port, link);
  16601     }
  16602     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16603         LOG_ERROR(BSL_LS_BCM_PORT,
  16604                   (BSL_META("Error: Not permitted on OAMP port %d.update.\n"),
  16605                    port));
  16606         return BCM_E_PARAM;
  16607     }
  16608 
  16609     if (PORT(unit, port).p_mac == NULL) {
  16610         return BCM_E_INIT;
  16611     }
  16612 
  16613     if (!link) {
  16614         /* PHY is down.  Disable the MAC. */
  16615 #ifdef SW_AUTONEG_SUPPORT
  16616         rv = _bcm_esw_port_notify_link_down_evt(unit, port);
  16617         if (BCM_FAILURE(rv)) {
  16618             LOG_WARN(BSL_LS_BCM_PORT,
  16619                      (BSL_META_U(unit,
  16620                                  "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"),
  16621                       unit, port, rv));
  16622             return rv;
  16623         }
  16624 #endif
  16625 
  16626         rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE));
  16627         if (BCM_FAILURE(rv)) {
  16628             LOG_WARN(BSL_LS_BCM_PORT,
  16629                      (BSL_META_U(unit,
  16630                                  "u=%d p=%d MAC_ENABLE_SET FALSE rv=%d\n"),
  16631                       unit, port, rv));
  16632             return rv;
  16633         }
  16634         /* PHY link down event */
  16635         rv = (soc_phyctrl_linkdn_evt(unit, port));
  16636         if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  16637             LOG_WARN(BSL_LS_BCM_PORT,
  16638                      (BSL_META_U(unit,
  16639                                  "u=%d p=%d soc_phyctrl_linkdn_evt rv=%d\n"),unit, port, rv));
  16640             return rv;
  16641         }
  16642         return BCM_E_NONE;
  16643     }
  16644 
  16645     /* PHY link up event may not be support by all PHY driver.
  16646      * Just ignore it if not supported */
  16647     rv = (soc_phyctrl_linkup_evt(unit, port));
  16648     if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  16649         LOG_WARN(BSL_LS_BCM_PORT,
  16650                  (BSL_META_U(unit,
  16651                              "u=%d p=%d soc_phyctrl_linkup_evt rv=%d\n"),unit, port, rv));
  16652         return rv;
  16653     }
  16654 
  16655     if (soc_feature(unit, soc_feature_internal_phy_link_check)) {
  16656         int up = 0;
  16657 
  16658         SOC_IF_ERROR_RETURN
  16659             (soc_phyctrl_link_get(unit, port, &up));
  16660 
  16661         /* Wait internal PHY link when external PHY is link up */
  16662         if (up) {
  16663             (void)soc_phyctrl_notify(unit, port, phyEventLinkWait, 0);
  16664         }
  16665     }
  16666 
  16667     /*
  16668      * Set MAC speed first, since for GTH ports, this will switch
  16669      * between the 1000Mb/s or 10/100Mb/s MACs.
  16670      */
  16671 
  16672     if (!IS_HG_PORT(unit, port) || IS_GX_PORT(unit, port)) {
  16673         rv = (soc_phyctrl_speed_get(unit, port, &speed));
  16674         if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  16675             LOG_WARN(BSL_LS_BCM_PORT,
  16676                      (BSL_META_U(unit,
  16677                                  "u=%d p=%d phyctrl_speed_get rv=%d\n"),unit, port, rv));
  16678             return rv;
  16679         }
  16680         if (IS_HG_PORT(unit, port) && speed < 5000) {
  16681             speed = 0;
  16682         }
  16683         LOG_INFO(BSL_LS_BCM_PORT,
  16684                  (BSL_META_U(unit,
  16685                              "u=%d p=%d phyctrl_speed_get speed=%d\n"),unit, port, speed));
  16686 
  16687         if (BCM_E_UNAVAIL == rv ) {
  16688             /* If PHY driver doesn't support speed_get, don't change
  16689              * MAC speed. E.g, Null PHY driver
  16690              */
  16691             rv = BCM_E_NONE;
  16692         } else {
  16693             if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  16694                 BCM_IF_ERROR_RETURN
  16695                     (_bcm_td_port_mode_update(unit, port, speed));
  16696             }
  16697 #ifdef INCLUDE_FCMAP
  16698             /* FOR MONTREAL-1 ONLY
  16699              *
  16700              * In FCMAP mode, the port is operating in FC-Mode. The switch and the
  16701              * system side of the PHY operates in 10G, FullDuplex and Pause enabled
  16702              * mode
  16703              * For MT1, the phy max speed will always be 10G (never 25G which MT2 supports)
  16704              */
  16705             if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  16706 
  16707                 pc = EXT_PHY_SW_STATE(unit, port);
  16708 
  16709                 if ((pc != NULL) &&  !PHY_IS_BCM8806X(pc)) {
  16710                      speed = 10000;
  16711                 }
  16712                 LOG_WARN(BSL_LS_BCM_PORT,
  16713                          (BSL_META_U(unit,
  16714                                      "u=%d p=%d speed_max=%d speed=%d\n"),unit, port,
  16715                                       pc->speed_max, speed));
  16716             }
  16717 #endif
  16718             rv =  (MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &cur_mac_speed));
  16719             if (BCM_FAILURE(rv)) {
  16720                 LOG_WARN(BSL_LS_BCM_PORT,
  16721                          (BSL_META_U(unit,
  16722                                      "u=%d p=%d MAC_SPEED_GET rv=%d\n"),unit, port, rv));
  16723                 return rv;
  16724             }
  16725 
  16726             rv =  (MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &enable));
  16727             if (BCM_FAILURE(rv)) {
  16728                 LOG_WARN(BSL_LS_BCM_PORT,
  16729                             (BSL_META_U(unit,
  16730                                       "u=%d p=%d MAC_ENABLE_GET rv=%d\n"),unit, port, rv));
  16731                 return rv;
  16732             }
  16733 
  16734             /* If current MAC speed is the same as PHY speed, no need set it again */
  16735             if (cur_mac_speed != speed || enable != TRUE) {
  16736                  rv =  (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed));
  16737             }
  16738         }
  16739         if (BCM_FAILURE(rv)) {
  16740             LOG_WARN(BSL_LS_BCM_PORT,
  16741                      (BSL_META_U(unit,
  16742                                  "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"),
  16743                       unit, port, speed, rv));
  16744             return rv;
  16745         }
  16746 
  16747         rv =   (soc_phyctrl_duplex_get(unit, port, &duplex));
  16748         if (BCM_FAILURE(rv)) {
  16749             LOG_WARN(BSL_LS_BCM_PORT,
  16750                      (BSL_META_U(unit,
  16751                                  "u=%d p=%d phyctrl_duplex_get rv=%d\n"),
  16752                                  unit, port, rv));
  16753             return rv;
  16754         }
  16755 
  16756 #ifdef INCLUDE_MACSEC
  16757         /* When macsec is enabled, the switch and system side of the PHY
  16758          * operate in full-duplex mode.
  16759  */
  16760         duplex_old = duplex;
  16761         if ( soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0) ) {
  16762             duplex = 1;
  16763         }
  16764 
  16765         policy = soc_property_port_get(unit, port, spn_MACSEC_SWITCH_SIDE_POLICY, 1);
  16766         if ( (policy == 2) && (! duplex_old) ) {
  16767             /* if line-side linked up at half-duplex under Duplex Gateway mode */
  16768             duplex = 1;        /* force to full-duplex */
  16769         }
  16770 #endif
  16771 
  16772 #ifdef INCLUDE_FCMAP
  16773             /*
  16774              * In FCMAP mode, the port is operating in FC-Mode. The switch and the
  16775              * system side of the PHY operates in 10G, FullDuplex and Pause enabled
  16776              * mode
  16777              */
  16778             if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  16779                 duplex = 1;
  16780             }
  16781 #endif
  16782         rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex));
  16783         if (BCM_FAILURE(rv)) {
  16784             LOG_WARN(BSL_LS_BCM_PORT,
  16785                      (BSL_META_U(unit,
  16786                                  "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"),
  16787                                  unit, port,
  16788                       duplex ? "FULL" : "HALF", speed, rv));
  16789             return rv;
  16790         }
  16791     } else {
  16792 
  16793         duplex = 1;
  16794     }
  16795 
  16796     rv = (soc_phyctrl_interface_get(unit, port, &pif));
  16797     if (BCM_FAILURE(rv)) {
  16798         LOG_WARN(BSL_LS_BCM_PORT,
  16799                  (BSL_META_U(unit,
  16800                              "u=%d p=%d phyctrl_interface_get rv=%d\n"),
  16801                   unit, port, rv));
  16802         return rv;
  16803     }
  16804     rv = (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif));
  16805     if (BCM_FAILURE(rv)) {
  16806         LOG_WARN(BSL_LS_BCM_PORT,
  16807                  (BSL_META_U(unit,
  16808                              "u=%d p=%d MAC_INTERFACE_GET rv=%d\n"),
  16809                   unit, port,rv));
  16810         return rv;
  16811     }
  16812 
  16813     SOC_IF_ERROR_RETURN
  16814         (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  16815 
  16816     /*
  16817      * If autonegotiating, check the negotiated PAUSE values, and program
  16818      * MACs accordingly. Link can also be achieved thru parallel detect.
  16819      * In this case, it should be treated as in the forced mode.
  16820      */
  16821     if (an && an_done) {
  16822         bcm_port_ability_t      remote_advert, local_advert;
  16823         int                     tx_pause, rx_pause;
  16824 
  16825     sal_memset(&local_advert,  0, sizeof(bcm_port_ability_t));
  16826     sal_memset(&remote_advert, 0, sizeof(bcm_port_ability_t));
  16827 
  16828     rv = soc_phyctrl_ability_advert_get(unit, port, &local_advert);
  16829         if (BCM_FAILURE(rv)) {
  16830             LOG_WARN(BSL_LS_BCM_PORT,
  16831                      (BSL_META_U(unit,
  16832                                  "u=%d p=%d soc_phyctrl_adv_local_get rv=%d\n"),
  16833                       unit, port, rv));
  16834             return rv;
  16835         }
  16836         rv = soc_phyctrl_ability_remote_get(unit, port, &remote_advert);
  16837         if (BCM_FAILURE(rv)) {
  16838             LOG_WARN(BSL_LS_BCM_PORT,
  16839                      (BSL_META_U(unit,
  16840                                  "u=%d p=%d soc_phyctrl_adv_remote_get rv=%d\n"),
  16841                       unit, port, rv));
  16842             return rv;
  16843         }
  16844 
  16845         /*
  16846          * IEEE 802.3 Flow Control Resolution.
  16847          * Please see $SDK/doc/pause-resolution.txt for more information.
  16848          */
  16849 
  16850         if (duplex) {
  16851             tx_pause =
  16852                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16853                       (local_advert.pause & SOC_PA_PAUSE_RX)) ||
  16854                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16855                       !(remote_advert.pause & SOC_PA_PAUSE_TX) &&
  16856                       (local_advert.pause & SOC_PA_PAUSE_TX));
  16857 
  16858             rx_pause =
  16859                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16860                       (local_advert.pause & SOC_PA_PAUSE_RX)) ||
  16861                      ((local_advert.pause & SOC_PA_PAUSE_RX) &&
  16862                       (remote_advert.pause & SOC_PA_PAUSE_TX) &&
  16863                       !(local_advert.pause & SOC_PA_PAUSE_TX));
  16864         } else {
  16865             rx_pause = tx_pause = 0;
  16866         }
  16867 #ifdef INCLUDE_MACSEC
  16868         if ( (policy == 2) && (! duplex_old) ) {
  16869             /* if line-side linked up at half-duplex under Duplex Gateway mode */
  16870             rx_pause = 1;              /* turn on flow control Rx pause frames */
  16871         }
  16872 #endif
  16873         rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac,
  16874                            unit, port, tx_pause, rx_pause));
  16875         if (BCM_FAILURE(rv)) {
  16876             LOG_WARN(BSL_LS_BCM_PORT,
  16877                      (BSL_META_U(unit,
  16878                                  "u=%d p=%d MAC_PAUSE_SET rv=%d\n"),
  16879                       unit, port, rv));
  16880             return rv;
  16881         }
  16882     }
  16883 
  16884 #ifdef INCLUDE_MACSEC
  16885     {
  16886     /*
  16887      * In MACSEC based PHYs the switch side could be operating with
  16888      * different speed,duplex and pause compared to line speed, duplex and
  16889      * pause settings. The above setting will be overridden if the switch side
  16890      * of the PHY is set to operate in fixed mode
  16891      */
  16892     uint32 value;
  16893     rv = (soc_phyctrl_control_get(unit, port,
  16894                                   BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED,
  16895                                   &value));
  16896 
  16897     if (BCM_E_UNAVAIL != rv) { /* Switch fixed speed is supported */
  16898 
  16899         if (value == 1) {
  16900             /* Get and Set Speed */
  16901             rv = (soc_phyctrl_control_get(unit, port,
  16902                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED,
  16903                               &value));
  16904             if (BCM_FAILURE(rv)) {
  16905                 LOG_WARN(BSL_LS_BCM_PORT,
  16906                          (BSL_META_U(unit,
  16907                                      "u=%d p=%d phyctrl_control_get(speed) rv=%d\n"),
  16908                           unit, port, rv));
  16909                 return rv;
  16910             }
  16911 
  16912             rv =  (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, value));
  16913             if (BCM_FAILURE(rv)) {
  16914                 LOG_WARN(BSL_LS_BCM_PORT,
  16915                          (BSL_META_U(unit,
  16916                                      "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"),
  16917                           unit, port, value, rv));
  16918                 return rv;
  16919             }
  16920 
  16921             /* Get and Set Duplex */
  16922             rv = (soc_phyctrl_control_get(unit, port,
  16923                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX,
  16924                               &value));
  16925             if (BCM_FAILURE(rv)) {
  16926                 LOG_WARN(BSL_LS_BCM_PORT,
  16927                          (BSL_META_U(unit,
  16928                                      "u=%d p=%d phyctrl_control_get(duplex) rv=%d\n"),
  16929                           unit, port, rv));
  16930                 return rv;
  16931             }
  16932             rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, value));
  16933             if (BCM_FAILURE(rv)) {
  16934                 LOG_WARN(BSL_LS_BCM_PORT,
  16935                          (BSL_META_U(unit,
  16936                                      "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"),
  16937                                      unit, port,
  16938                           value ? "FULL" : "HALF", value, rv));
  16939                 return rv;
  16940             }
  16941 
  16942             /* Get and Set PAUSE */
  16943             rv = (soc_phyctrl_control_get(unit, port,
  16944                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE,
  16945                               &value));
  16946             if (BCM_FAILURE(rv)) {
  16947                 LOG_WARN(BSL_LS_BCM_PORT,
  16948                          (BSL_META_U(unit,
  16949                                      "u=%d p=%d phyctrl_control_get(Pause) rv=%d\n"),
  16950                           unit, port, rv));
  16951                 return rv;
  16952             }
  16953             if (value == 1) {
  16954                 /*
  16955                  * Flow control domain is between switch MAC and PHY MAC.
  16956                  * If the flow control domain is not between switch and PHY's
  16957                  * switch MAC, then the flow control domain is extended to that
  16958                  * of GPHY.
  16959                  */
  16960                 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac,
  16961                                unit, port, value, value));
  16962                 if (BCM_FAILURE(rv)) {
  16963                     LOG_WARN(BSL_LS_BCM_PORT,
  16964                              (BSL_META_U(unit,
  16965                                          "u=%d p=%d MAC_PAUSE_SET rv=%d\n"),
  16966                               unit, port, rv));
  16967                     return rv;
  16968                 }
  16969             }
  16970 
  16971         }
  16972     }
  16973     }
  16974 #endif
  16975 
  16976     /* Enable the MAC. */
  16977     rv =  (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE));
  16978     if (BCM_FAILURE(rv)) {
  16979         LOG_WARN(BSL_LS_BCM_PORT,
  16980                  (BSL_META_U(unit,
  16981                              "u=%d p=%d MAC_ENABLE_SET TRUE rv=%d\n"),
  16982                   unit, port, rv));
  16983         return rv;
  16984     }
  16985 
  16986 #ifdef BCM_BRADLEY_SUPPORT
  16987     /* When a link comes up, hardware will not update the
  16988      * LINK_STATUS register until software has toggled the
  16989      * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field.
  16990      * When a link goes down, hardware will update the
  16991      * LINK_STATUS register without software intervention.
  16992      */
  16993     if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) &&
  16994          IS_GX_PORT(unit, port)) ||
  16995         (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) ||
  16996         (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) &&
  16997          (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port) )) ||
  16998         (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) &&
  16999           IS_CL_PORT(unit, port))) {
  17000         soc_reg_t reg;
  17001         uint32 rval;
  17002 
  17003         if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) {
  17004             reg = XLPORT_LAG_FAILOVER_CONFIGr;
  17005         } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) {
  17006             reg = LAG_FAILOVER_CONFIGr;
  17007         } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) {
  17008             reg = GXPORT_LAG_FAILOVER_CONFIGr;
  17009         } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) &&
  17010                    (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) {
  17011             reg = CLPORT_LAG_FAILOVER_CONFIGr;
  17012         } else {
  17013             reg = XLPORT_LAG_FAILOVER_CONFIGr;
  17014         }
  17015 
  17016         /* Toggle link bit to notify IPIPE on link up */
  17017         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  17018         soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1);
  17019         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  17020         soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0);
  17021         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  17022     }
  17023 #endif /* BCM_BRADLEY_SUPPORT */
  17024 
  17025     return BCM_E_NONE;
  17026 }
  17027 
  17028 
  17029 
  17030 /*
  17031  * Function:
  17032  *      bcm_port_update
  17033  * Purpose:
  17034  *      Get port characteristics from PHY and program MAC to match.
  17035  * Parameters:
  17036  *      unit - StrataSwitch Unit #.
  17037  *      port - StrataSwitch port #.
  17038  *      link - TRUE - process as link up.
  17039  *             FALSE - process as link down.
  17040  * Returns:
  17041  *      BCM_E_NONE
  17042  *      BCM_E_XXX
  17043  */
  17044 
  17045 int
  17046 bcm_esw_port_update(int unit, bcm_port_t port, int link)
  17047 {
  17048     int         rv = BCM_E_NONE;
  17049 #if defined(BCM_KATANA2_SUPPORT)
  17050     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17051 #endif
  17052 
  17053     /* Make sure port module is initialized. */
  17054     PORT_INIT(unit);
  17055 
  17056 #if defined(BCM_KATANA2_SUPPORT)
  17057 #if defined(BCM_SABER2_SUPPORT)
  17058     if(SOC_IS_SABER2(unit)) {
  17059         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17060     }
  17061 #endif
  17062     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17063         (!((port >= 1) && (port <= max_phy_port)))) {
  17064          return BCM_E_PORT;
  17065     }
  17066 #endif
  17067     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17068 
  17069 #if defined(BCM_RCPU_SUPPORT)
  17070     if (SOC_IS_RCPU_ONLY(unit) && link) {
  17071         /* Can not do this unless real phy driver is used for RCPU device. */
  17072         return BCM_E_NONE;
  17073     }
  17074 #endif /* BCM_RCPU_SUPPORT */
  17075     PORT_LOCK(unit);
  17076     rv = _bcm_port_update(unit, port, link);
  17077     if (BCM_FAILURE(rv)) {
  17078         PORT_UNLOCK(unit);
  17079         return (rv);
  17080     }
  17081 #if defined(BCM_BRADLEY_SUPPORT)
  17082     if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) {
  17083         rv = _bcm_port_mmu_update(unit, port, link);
  17084     }
  17085 #endif /* BCM_BRADLEY_SUPPORT */
  17086 
  17087 #if defined(BCM_KATANA2_SUPPORT)
  17088     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  17089         rv = soc_katana2_mmu_port_enable_set(unit, port, link);
  17090     }
  17091 #endif
  17092 
  17093     PORT_UNLOCK(unit);
  17094 
  17095     LOG_INFO(BSL_LS_BCM_PORT,
  17096              (BSL_META_U(unit,
  17097                          "bcm_port_update: u=%d p=%d link=%d rv=%d\n"),
  17098               unit, port, link, rv));
  17099 
  17100     return(rv);
  17101 }
  17102 
  17103 /*
  17104  * Function:
  17105  *      bcm_esw_roe_tx_port_update
  17106  * Parameters:
  17107  *      unit - StrataSwitch Unit #.
  17108  *      port - StrataSwitch port #.
  17109  *      link - TRUE - process as link up.
  17110  *             FALSE - process as link down.
  17111  * Returns:
  17112  *      BCM_E_NONE
  17113  *      BCM_E_XXX
  17114  */
  17115 
  17116 int
  17117 bcm_esw_roe_tx_port_update(int unit, bcm_port_t port, int link)
  17118 {
  17119     int         rv = BCM_E_NONE;
  17120     PORT_INIT(unit);
  17121     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17122 
  17123     PORT_LOCK(unit);
  17124     rv = _bcm_tx_roe_port_update(unit, port, link);
  17125     if (BCM_FAILURE(rv)) {
  17126         PORT_UNLOCK(unit);
  17127         return (rv);
  17128     }
  17129     PORT_UNLOCK(unit);
  17130 
  17131     LOG_INFO(BSL_LS_BCM_PORT,
  17132              (BSL_META_U(unit,
  17133                          "bcm_tx_roe_port_update: u=%d p=%d link=%d rv=%d\n"),
  17134               unit, port, link, rv));
  17135 
  17136     return(rv);
  17137 }
  17138 
  17139 /*
  17140  * Function:
  17141  *      bcm_esw_roe_rx_port_update
  17142  * Parameters:
  17143  *      unit - StrataSwitch Unit #.
  17144  *      port - StrataSwitch port #.
  17145  *      link - TRUE - process as link up.
  17146  *             FALSE - process as link down.
  17147  * Returns:
  17148  *      BCM_E_NONE
  17149  *      BCM_E_XXX
  17150  */
  17151 
  17152 int
  17153 bcm_esw_roe_rx_port_update(int unit, bcm_port_t port, int link)
  17154 {
  17155     int         rv = BCM_E_NONE;
  17156     PORT_INIT(unit);
  17157     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17158 
  17159     PORT_LOCK(unit);
  17160     rv = _bcm_rx_roe_port_update(unit, port, link);
  17161     if (BCM_FAILURE(rv)) {
  17162         PORT_UNLOCK(unit);
  17163         return (rv);
  17164     }
  17165     PORT_UNLOCK(unit);
  17166 
  17167     LOG_INFO(BSL_LS_BCM_PORT,
  17168              (BSL_META_U(unit,
  17169                          "bcm_rx_roe_port_update: u=%d p=%d link=%d rv=%d\n"),
  17170               unit, port, link, rv));
  17171 
  17172     return(rv);
  17173 }
  17174 
  17175 
  17176 /*
  17177  * Function:
  17178  *      bcm_port_stp_set
  17179  * Purpose:
  17180  *      Set the spanning tree state for a port.
  17181  *      All STGs containing all VLANs containing the port are updated.
  17182  * Parameters:
  17183  *      unit - StrataSwitch unit number.
  17184  *      port - StrataSwitch port number.
  17185  *      stp_state - State to place port in, one of BCM_PORT_STP_xxx.
  17186  * Returns:
  17187  *      BCM_E_NONE
  17188  *      BCM_E_INTERNAL
  17189  * Notes:
  17190  *      BCM_LOCK is taken so that the current list of VLANs
  17191  *      can't change during the operation.
  17192  */
  17193 
  17194 int
  17195 bcm_esw_port_stp_set(int unit, bcm_port_t port, int stp_state)
  17196 {
  17197     bcm_stg_t           *list = NULL;
  17198     int                 count = 0, i;
  17199     int                 rv = BCM_E_NONE;
  17200 
  17201     /* Make sure port module is initialized. */
  17202     PORT_INIT(unit);
  17203     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17204 
  17205 #ifdef BCM_RCPU_SUPPORT
  17206     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port) &&
  17207         !(stp_state == BCM_STG_STP_FORWARD)) {
  17208         return BCM_E_PORT;
  17209     }
  17210 #endif /* BCM_RCPU_SUPPORT */
  17211 
  17212     BCM_LOCK(unit);
  17213 
  17214     rv = bcm_esw_stg_list(unit, &list, &count);
  17215 
  17216     if (rv == BCM_E_UNAVAIL) {
  17217         if (stp_state == BCM_STG_STP_FORWARD) {
  17218             rv = BCM_E_NONE;
  17219         } else {
  17220             rv = BCM_E_PARAM;
  17221         }
  17222     } else if (BCM_SUCCESS(rv)) {
  17223         for (i = 0; i < count; i++) {
  17224             if ((rv = bcm_esw_stg_stp_set(unit, list[i],
  17225                                           port, stp_state)) < 0) {
  17226                 break;
  17227             }
  17228         }
  17229 
  17230         bcm_esw_stg_list_destroy(unit, list, count);
  17231     }
  17232 
  17233     BCM_UNLOCK(unit);
  17234 
  17235     LOG_INFO(BSL_LS_BCM_PORT,
  17236              (BSL_META_U(unit,
  17237                          "bcm_port_stp_set: u=%d p=%d state=%d rv=%d\n"),
  17238               unit, port, stp_state, rv));
  17239 
  17240     return rv;
  17241 }
  17242 
  17243 /*
  17244  * Function:
  17245  *      bcm_port_stp_get
  17246  * Purpose:
  17247  *      Get the spanning tree state for a port in the default STG.
  17248  * Parameters:
  17249  *      unit - StrataSwitch unit number.
  17250  *      port - StrataSwitch port number.
  17251  *      stp_state - Pointer where state stored.
  17252  * Returns:
  17253  *      BCM_E_NONE
  17254  *      BCM_E_INTERNAL
  17255  */
  17256 
  17257 int
  17258 bcm_esw_port_stp_get(int unit, bcm_port_t port, int *stp_state)
  17259 {
  17260     int                 stg_defl, rv;
  17261 
  17262     /* Make sure port module is initialized. */
  17263     PORT_INIT(unit);
  17264 
  17265     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17266 
  17267     rv = bcm_esw_stg_default_get(unit, &stg_defl);
  17268     if (rv >= 0) {
  17269         rv = bcm_esw_stg_stp_get(unit, stg_defl, port, stp_state);
  17270     } else if (rv == BCM_E_UNAVAIL) {   /* FABRIC switches, etc */
  17271         *stp_state = BCM_STG_STP_FORWARD;
  17272         rv = BCM_E_NONE;
  17273     }
  17274 
  17275     LOG_INFO(BSL_LS_BCM_PORT,
  17276              (BSL_META_U(unit,
  17277                          "bcm_port_stp_get: u=%d p=%d state=%d rv=%d\n"),
  17278               unit, port, *stp_state, rv));
  17279 
  17280     return rv;
  17281 }
  17282 
  17283 /*
  17284  * Function:
  17285  *      bcm_port_bpdu_enable_set
  17286  * Purpose:
  17287  *      Enable/Disable BPDU reception on the specified port.
  17288  * Parameters:
  17289  *      unit - SOC unit #
  17290  *      port - Port number (0 based)
  17291  *      enable - TRUE to enable, FALSE to disable (reject bpdu).
  17292  * Returns:
  17293  *      BCM_E_NONE
  17294  *      BCM_E_INTERNAL
  17295  */
  17296 
  17297 int
  17298 bcm_esw_port_bpdu_enable_set(int unit, bcm_port_t port, int enable)
  17299 {
  17300     bcm_port_cfg_t      pcfg;
  17301     int                 rv;
  17302 
  17303     /* Make sure port module is initialized. */
  17304     PORT_INIT(unit);
  17305 
  17306     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17307         LOG_ERROR(BSL_LS_BCM_PORT,
  17308                   (BSL_META("Error: Cannot enable pbdu on OAMP Port %d.\n"),
  17309                    port));
  17310         return BCM_E_PARAM;
  17311     }
  17312 
  17313     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17314 
  17315     PORT_LOCK(unit);
  17316 
  17317     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17318 
  17319     if (BCM_SUCCESS(rv)) {
  17320         pcfg.pc_bpdu_disable = !enable;
  17321         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  17322     }
  17323 
  17324     PORT_UNLOCK(unit);
  17325 
  17326     return rv;
  17327 }
  17328 
  17329 /*
  17330  * Function:
  17331  *      bcm_port_bpdu_enable_get
  17332  * Purpose:
  17333  *      Return whether BPDU reception is enabled on the specified port.
  17334  * Parameters:
  17335  *      unit - SOC unit #
  17336  *      port - Port number (0 based)
  17337  *      enable - (OUT) TRUE if enabled, FALSE if disabled
  17338  * Returns:
  17339  *      BCM_E_NONE
  17340  *      BCM_E_INTERNAL
  17341  */
  17342 
  17343 int
  17344 bcm_esw_port_bpdu_enable_get(int unit, bcm_port_t port, int *enable)
  17345 {
  17346     bcm_port_cfg_t      pcfg;
  17347     int                 rv;
  17348 
  17349     /* Make sure port module is initialized. */
  17350     PORT_INIT(unit);
  17351 
  17352     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17353         LOG_ERROR(BSL_LS_BCM_PORT,
  17354                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17355                    port));
  17356         return BCM_E_PARAM;
  17357     }
  17358 
  17359     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17360 
  17361     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17362 
  17363     if (BCM_SUCCESS(rv)) {
  17364         *enable = !pcfg.pc_bpdu_disable;
  17365     }
  17366 
  17367     return rv;
  17368 }
  17369 
  17370 /*
  17371  * Function:
  17372  *      bcm_port_l3_enable_set
  17373  * Purpose:
  17374  *      Enable/Disable L3 switching on the specified port.
  17375  * Parameters:
  17376  *      unit -          device number
  17377  *      port -          port number
  17378  *      enable -        TRUE to enable, FALSE to disable.
  17379  * Returns:
  17380  *      BCM_E_XXX
  17381  */
  17382 
  17383 int
  17384 bcm_esw_port_l3_enable_set(int unit, bcm_port_t port, int enable)
  17385 {
  17386     int  rv = BCM_E_UNAVAIL;
  17387 #if defined(INCLUDE_L3)
  17388     bcm_port_cfg_t      pcfg;
  17389 
  17390     /* Make sure port module is initialized. */
  17391     PORT_INIT(unit);
  17392 
  17393     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17394         LOG_ERROR(BSL_LS_BCM_PORT,
  17395                   (BSL_META("Error: Cannot enable l3 on OAMP Port %d.\n"),
  17396                    port));
  17397         return BCM_E_PARAM;
  17398     }
  17399 
  17400     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17401 
  17402     PORT_LOCK(unit);
  17403 
  17404     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17405 
  17406     if (BCM_SUCCESS(rv)) {
  17407         if (enable) {
  17408             pcfg.pc_l3_flags |= (BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE);
  17409         } else {
  17410             pcfg.pc_l3_flags &=
  17411                 ~(BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE);
  17412         }
  17413         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  17414     }
  17415 
  17416     PORT_UNLOCK(unit);
  17417 #endif /* INCLUDE_L3 */
  17418     return rv;
  17419 }
  17420 
  17421 /*
  17422  * Function:
  17423  *      bcm_port_l3_enable_get
  17424  * Purpose:
  17425  *      Return whether L3 switching is enabled on the specified port.
  17426  * Parameters:
  17427  *      unit -          device number
  17428  *      port -          port number
  17429  *      enable -        (OUT) TRUE if enabled, FALSE if disabled
  17430  * Returns:
  17431  *      BCM_E_XXX
  17432  */
  17433 
  17434 int
  17435 bcm_esw_port_l3_enable_get(int unit, bcm_port_t port, int *enable)
  17436 {
  17437     int  rv = BCM_E_UNAVAIL;
  17438 #if defined(INCLUDE_L3)
  17439     bcm_port_cfg_t      pcfg;
  17440 
  17441     /* Make sure port module is initialized. */
  17442     PORT_INIT(unit);
  17443 
  17444     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17445         LOG_ERROR(BSL_LS_BCM_PORT,
  17446                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17447                    port));
  17448         return BCM_E_PARAM;
  17449     }
  17450 
  17451     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17452 
  17453     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17454 
  17455     if (BCM_SUCCESS(rv)) {
  17456         *enable = ((pcfg.pc_l3_flags & BCM_PORT_L3_V4_ENABLE) ||
  17457                    (pcfg.pc_l3_flags & BCM_PORT_L3_V6_ENABLE));
  17458     }
  17459 #endif /* INCLUDE_L3 */
  17460 
  17461     return rv;
  17462 }
  17463 
  17464 /*
  17465  * Function:
  17466  *      bcm_port_tgid_get
  17467  * Purpose:
  17468  *      Get the trunk group for a given port.
  17469  * Parameters:
  17470  *      unit - SOC unit #
  17471  *      port - Port number (0 based)
  17472  *      tid - trunk ID
  17473  *      psc - trunk selection criterion
  17474  * Returns:
  17475  *      BCM_E_NONE
  17476  *      BCM_E_INTERNAL
  17477  */
  17478 
  17479 int
  17480 bcm_esw_port_tgid_get(int unit, bcm_port_t port, int *tid, int *psc)
  17481 {
  17482     bcm_port_cfg_t      pcfg;
  17483     int                 rv;
  17484 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  17485     soc_field_t tgid_fld = TGIDf;
  17486     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) {
  17487         tgid_fld = SRC_TGIDf;
  17488     }
  17489 #endif
  17490 
  17491     /* Make sure port module is initialized. */
  17492     PORT_INIT(unit);
  17493 
  17494     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17495         LOG_ERROR(BSL_LS_BCM_PORT,
  17496                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17497                    port));
  17498         return BCM_E_PARAM;
  17499     }
  17500 
  17501     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17502 
  17503 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  17504     if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) {
  17505 #if defined(BCM_KATANA2_SUPPORT)
  17506         if (SOC_IS_KATANA2(unit)) {
  17507             rv = _bcm_kt2_trunk_table_read(unit, port, tid);
  17508         } else
  17509 #endif
  17510         {
  17511             rv = _bcm_xgs3_trunk_table_read(unit, port, tid);
  17512         }
  17513         if (BCM_SUCCESS(rv)) {
  17514             *psc = 0;
  17515         }
  17516         return rv;
  17517     }
  17518 #endif /* BCM_FIREBOLT_SUPPORT */
  17519 
  17520     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17521 
  17522     if (BCM_SUCCESS(rv)) {
  17523         *tid = pcfg.pc_tgid;
  17524         *psc = 0;
  17525     }
  17526 
  17527     return rv;
  17528 
  17529 }
  17530 
  17531 /*
  17532  * Function:
  17533  *      bcm_port_tgid_set
  17534  * Purpose:
  17535  *      Set the trunk group for a given port.
  17536  * Parameters:
  17537  *      unit - SOC unit #
  17538  *      port - Port number (0 based)
  17539  *      tid - trunk ID
  17540  *      psc - trunk selection criterion
  17541  * Returns:
  17542  *      BCM_E_NONE
  17543  *      BCM_E_INTERNAL
  17544  */
  17545 
  17546 int
  17547 bcm_esw_port_tgid_set(int unit, bcm_port_t port, int tid, int psc)
  17548 {
  17549     bcm_port_cfg_t      pcfg;
  17550     int                 rv;
  17551 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  17552     soc_field_t tgid_fld = TGIDf;
  17553     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) {
  17554         tgid_fld = SRC_TGIDf;
  17555     }
  17556 #endif
  17557 
  17558     /* Make sure port module is initialized. */
  17559     PORT_INIT(unit);
  17560 
  17561     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17562         LOG_ERROR(BSL_LS_BCM_PORT,
  17563                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17564                    port));
  17565         return BCM_E_PARAM;
  17566     }
  17567 
  17568     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17569 
  17570 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  17571     if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) {
  17572 #if defined(BCM_KATANA2_SUPPORT)
  17573         if (SOC_IS_KATANA2(unit)) {
  17574             return _bcm_kt2_trunk_table_write(unit, port, tid);
  17575         } else
  17576 #endif
  17577         {
  17578             return _bcm_xgs3_trunk_table_write(unit, port, tid);
  17579         }
  17580     }
  17581 #endif /* BCM_FIREBOLT_SUPPORT */
  17582 
  17583     PORT_LOCK(unit);
  17584 
  17585     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17586 
  17587     if (BCM_SUCCESS(rv)) {
  17588         if (tid != BCM_TRUNK_INVALID) {
  17589             pcfg.pc_tgid = tid;
  17590             pcfg.pc_trunk = 1;
  17591         } else {
  17592             pcfg.pc_tgid = 0;
  17593             pcfg.pc_trunk = 0;
  17594         }
  17595         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  17596     }
  17597 
  17598     PORT_UNLOCK(unit);
  17599 
  17600     return rv;
  17601 }
  17602 
  17603 /*
  17604  * Function:
  17605  *      _bcm_port_mirror_enable_get (internal)
  17606  * Purpose:
  17607  *       Return whether mirroring is enabled on the specified port.
  17608  * Parameters:
  17609  *      unit   - (IN) BCM device number.
  17610  *      port   - (IN) Port number (0 based).
  17611  *      enable - (OUT) Bitmap of ingress mirror enabled.
  17612  * Returns:
  17613  *      BCM_E_NONE
  17614  *      BCM_E_INTERNAL
  17615  */
  17616 
  17617 int
  17618 _bcm_port_mirror_enable_get(int unit, bcm_port_t port, int *enable)
  17619 {
  17620     bcm_port_cfg_t      pcfg;
  17621     int                 rv;
  17622 
  17623     /* Input parameters check. */
  17624     if (NULL == enable) {
  17625         return (BCM_E_PARAM);
  17626     }
  17627 
  17628     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17629 
  17630     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17631 
  17632     if (BCM_SUCCESS(rv)) {
  17633         *enable = pcfg.pc_mirror_ing;
  17634     }
  17635 
  17636     return rv;
  17637 }
  17638 
  17639 /*
  17640  * Function:
  17641  *      _bcm_port_mirror_enable_set (internal)
  17642  * Purpose:
  17643  *       Enable/Disable mirroring for a given port.
  17644  * Parameters:
  17645  *      unit -   (IN) BCM unit #
  17646  *      port -   (IN) Port number (0 based)
  17647  *      enable - (IN) Bitmap of ingress mirror enabled.
  17648  * Returns:
  17649  *      BCM_E_NONE
  17650  *      BCM_E_INTERNAL
  17651  */
  17652 
  17653 int
  17654 _bcm_port_mirror_enable_set(int unit, bcm_port_t port, int enable)
  17655 {
  17656     bcm_port_cfg_t      pcfg;
  17657     int                 rv;
  17658 
  17659     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17660 
  17661     PORT_LOCK(unit);
  17662 
  17663     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  17664 
  17665     if (BCM_SUCCESS(rv)) {
  17666         pcfg.pc_mirror_ing = enable;
  17667         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  17668     }
  17669 
  17670     PORT_UNLOCK(unit);
  17671 
  17672     return rv;
  17673 }
  17674 
  17675 #ifdef BCM_TRIUMPH2_SUPPORT
  17676 /*
  17677  * Function:
  17678  *      _bcm_port_mirror_egress_true_enable_get (internal)
  17679  * Purpose:
  17680  *       Return whether true egress mirroring is enabled on the
  17681  *       specified port.
  17682  * Parameters:
  17683  *      unit   - (IN) BCM device number.
  17684  *      port   - (IN) Port number (0 based).
  17685  *      enable - (OUT) Bitmap of true egress mirrors enabled.
  17686  * Returns:
  17687  *      BCM_E_NONE
  17688  *      BCM_E_INTERNAL
  17689  */
  17690 
  17691 int
  17692 _bcm_port_mirror_egress_true_enable_get(int unit, bcm_port_t port,
  17693                                         int *enable)
  17694 {
  17695     int     rv;
  17696 
  17697     /* Input parameters check. */
  17698     if (NULL == enable) {
  17699         return (BCM_E_PARAM);
  17700     }
  17701 
  17702 #if defined(BCM_TRIUMPH3_SUPPORT)
  17703     if (soc_feature(unit, soc_feature_ep_redirect) ||
  17704         soc_feature(unit, soc_feature_ep_redirect_v2)) {
  17705         egr_port_entry_t egr_port_entry;
  17706         int              ep_redirect_v2 = FALSE;
  17707 
  17708         rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port,
  17709                             &egr_port_entry);
  17710 
  17711         /* Check if this device supports version 2 of redirect,
  17712            based on which we will access different fields below */
  17713         ep_redirect_v2 = soc_feature(unit, soc_feature_ep_redirect_v2);
  17714 
  17715         if (BCM_SUCCESS(rv)) {
  17716             if (SOC_EPT_REDIRECT_MIRROR ==
  17717                 soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry,
  17718                                     (ep_redirect_v2 ? ER_REDIR_DEST_TYPEf :
  17719                                      REDIRECTION_TYPEf))) {
  17720                 *enable = soc_mem_field32_get(unit, EGR_PORTm,
  17721                                              &egr_port_entry,
  17722                                              (ep_redirect_v2 ? ER_REDIR_DESTINATIONf :
  17723                                              REDIRECTION_DESTINATIONf));
  17724             } else {
  17725                 *enable = 0;
  17726             }
  17727         }
  17728     } else
  17729 #endif /* BCM_TRIUMPH3_SUPPORT */
  17730 
  17731     {
  17732         uint64 egr_val64;
  17733 
  17734         rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  17735         if (BCM_SUCCESS(rv)) {
  17736             *enable = soc_reg64_field32_get(unit, EGR_PORT_64r,
  17737                                             egr_val64, MIRRORf);
  17738         }
  17739     }
  17740 
  17741     return rv;
  17742 }
  17743 
  17744 /*
  17745  * Function:
  17746  *      _bcm_port_mirror_egress_true_enable_set (internal)
  17747  * Purpose:
  17748  *       Enable/Disable true egress mirroring for a given port.
  17749  * Parameters:
  17750  *      unit -   (IN) BCM unit #
  17751  *      port -   (IN) Port number (0 based)
  17752  *      enable - (IN) Bitmap of true egress mirrors enabled.
  17753  * Returns:
  17754  *      BCM_E_NONE
  17755  *      BCM_E_INTERNAL
  17756  */
  17757 
  17758 int
  17759 _bcm_port_mirror_egress_true_enable_set(int unit, bcm_port_t port,
  17760                                         int enable)
  17761 {
  17762     int  rv = BCM_E_NONE;
  17763 
  17764     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17765 
  17766     PORT_LOCK(unit);
  17767 
  17768 #if defined(BCM_TRIUMPH3_SUPPORT)
  17769     if (soc_feature(unit, soc_feature_ep_redirect) ||
  17770         soc_feature(unit, soc_feature_ep_redirect_v2)) {
  17771 
  17772         uint32 egr_port_vals[2];
  17773         soc_field_t egr_port_fields[2];
  17774 
  17775         /* Based on if the device support version 2 of redirect,
  17776            select the appropriate fields */
  17777         if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  17778             egr_port_fields[0] = ER_REDIR_DEST_TYPEf;
  17779             egr_port_fields[1] = ER_REDIR_DESTINATIONf;
  17780         } else {
  17781             egr_port_fields[0] = REDIRECTION_TYPEf;
  17782             egr_port_fields[1] = REDIRECTION_DESTINATIONf;
  17783         }
  17784 
  17785         egr_port_vals[0] =
  17786             (0 != enable) ? SOC_EPT_REDIRECT_MIRROR : SOC_EPT_REDIRECT_NOOP;
  17787         egr_port_vals[1] = enable;
  17788 
  17789         /* Egress port table */
  17790         rv = soc_mem_fields32_modify(unit, EGR_PORTm, port, 2,
  17791                                      egr_port_fields, egr_port_vals);
  17792 
  17793         /* If ep-redirect-v2 also set the action, always-redirect vs do-not-redirect */
  17794         if(rv == BCM_E_NONE) {
  17795             if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  17796                 rv = soc_mem_field32_modify(unit, EGR_PORTm,
  17797                        port, ER_REDIR_ACTIONf,
  17798                        (enable ? _BCM_REDIRECT_ALWAYS : _BCM_REDIRECT_NONE));
  17799             }
  17800         }
  17801 
  17802     } else
  17803 #endif /* BCM_TRIUMPH3_SUPPORT */
  17804 
  17805     {
  17806         rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port,
  17807                                     MIRRORf, enable);
  17808         if (BCM_SUCCESS(rv) && IS_HG_PORT(unit, port)) {
  17809             rv = soc_reg_field32_modify(unit, IEGR_PORT_64r, port,
  17810                                         MIRRORf, enable);
  17811         }
  17812     }
  17813 
  17814     PORT_UNLOCK(unit);
  17815     return rv;
  17816 }
  17817 #endif /* BCM_TRIUMPH2_SUPPORT */
  17818 
  17819 /*
  17820  * Function:
  17821  *      bcm_port_linkscan_get
  17822  * Purpose:
  17823  *      Get the link scan state of the port
  17824  * Parameters:
  17825  *      unit - StrataSwitch Unit #.
  17826  *      port - StrataSwitch port #.
  17827  *      linkscan - (OUT) Linkscan value (None, S/W, H/W)
  17828  * Returns:
  17829  *      BCM_E_NONE
  17830  *      BCM_E_XXX
  17831  */
  17832 
  17833 int
  17834 bcm_esw_port_linkscan_get(int unit, bcm_port_t port, int *linkscan)
  17835 {
  17836     /* Make sure port module is initialized. */
  17837     PORT_INIT(unit);
  17838 
  17839     return bcm_esw_linkscan_mode_get(unit, port, linkscan);
  17840 }
  17841 
  17842 /*
  17843  * Function:
  17844  *      bcm_port_linkscan_set
  17845  * Purpose:
  17846  *      Set the linkscan state for a given port
  17847  * Parameters:
  17848  *      unit - StrataSwitch Unit #.
  17849  *      port - StrataSwitch port #.
  17850  *      linkscan - Linkscan value (None, S/W, H/W)
  17851  * Returns:
  17852  *      BCM_E_NONE
  17853  *      BCM_E_XXX
  17854  */
  17855 
  17856 int
  17857 bcm_esw_port_linkscan_set(int unit, bcm_port_t port, int linkscan)
  17858 {
  17859     /* Make sure port module is initialized. */
  17860     PORT_INIT(unit);
  17861 
  17862     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17863         LOG_ERROR(BSL_LS_BCM_PORT,
  17864                   (BSL_META("Error: Cannot enable linkscan on OAMP Port %d.\n"),
  17865                    port));
  17866         return BCM_E_PARAM;
  17867     }
  17868 
  17869     return bcm_esw_linkscan_mode_set(unit, port, linkscan);
  17870 }
  17871 
  17872 /*
  17873  * Function:
  17874  *      bcm_port_autoneg_get
  17875  * Purpose:
  17876  *      Get the autonegotiation state of the port
  17877  * Parameters:
  17878  *      unit - StrataSwitch Unit #.
  17879  *      port - StrataSwitch port #.
  17880  *      autoneg - (OUT) Boolean value
  17881  * Returns:
  17882  *      BCM_E_NONE
  17883  *      BCM_E_XXX
  17884  */
  17885 
  17886 int
  17887 bcm_esw_port_autoneg_get(int unit, bcm_port_t port, int *autoneg)
  17888 {
  17889     int           done=0, rv=BCM_E_NONE;
  17890     int           phy_lane = -1;
  17891     int           phyn = 0, sys_side = 0;
  17892     bcm_port_t    local_port = -1;
  17893 #if defined(BCM_KATANA2_SUPPORT)
  17894     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17895 #endif
  17896 
  17897     /* Make sure port module is initialized. */
  17898     PORT_INIT(unit);
  17899 
  17900     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  17901         return bcmi_esw_portctrl_autoneg_get(unit, port, autoneg);
  17902     }
  17903 
  17904 #if defined(BCM_KATANA2_SUPPORT)
  17905 #if defined(BCM_SABER2_SUPPORT)
  17906     if(SOC_IS_SABER2(unit)) {
  17907         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17908     }
  17909 #endif
  17910     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17911         (!((port >= 1) && (port <= max_phy_port)))) {
  17912          return BCM_E_PORT;
  17913     }
  17914 #endif
  17915 
  17916     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  17917                          &local_port, &phyn, &phy_lane, &sys_side));
  17918 
  17919     if (local_port == -1) {
  17920        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17921     }
  17922 
  17923     PORT_LOCK(unit);
  17924     if (local_port == -1) {
  17925         rv = soc_phyctrl_auto_negotiate_get(unit, port, autoneg, &done);
  17926     } else {
  17927         rv = soc_phyctrl_redirect_auto_negotiate_get(unit, local_port, phyn,
  17928                                                      phy_lane, sys_side,
  17929                                                      autoneg, &done);
  17930     }
  17931     PORT_UNLOCK(unit);
  17932     LOG_INFO(BSL_LS_BCM_PORT,
  17933              (BSL_META_U(unit,
  17934                          "bcm_port_autoneg_get: u=%d p=%d an=%d done=%d rv=%d\n"),
  17935               unit, port, *autoneg, done, rv));
  17936 
  17937     return rv;
  17938 }
  17939 
  17940 /*
  17941  * Function:
  17942  *      bcm_port_autoneg_set
  17943  * Purpose:
  17944  *      Set the autonegotiation state for a given port
  17945  * Parameters:
  17946  *      unit - StrataSwitch Unit #.
  17947  *      port - StrataSwitch port #.
  17948  *      autoneg - Boolean value
  17949  * Returns:
  17950  *      BCM_E_NONE
  17951  *      BCM_E_XXX
  17952  */
  17953 
  17954 int
  17955 bcm_esw_port_autoneg_set(int unit, bcm_port_t port, int autoneg)
  17956 {
  17957     int           rv=BCM_E_NONE;
  17958     int           phy_lane = -1;
  17959     int           phyn = 0, sys_side = 0;
  17960     bcm_port_t    local_port = -1;
  17961 
  17962 #if defined(BCM_SABER2_SUPPORT)
  17963     int             phy_status;
  17964 #endif
  17965 #if defined(BCM_KATANA2_SUPPORT)
  17966     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17967 #endif
  17968 
  17969     /* Make sure port module is initialized. */
  17970     PORT_INIT(unit);
  17971 
  17972     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  17973         return bcmi_esw_portctrl_autoneg_set(unit, port, autoneg);
  17974     }
  17975 
  17976     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17977         LOG_ERROR(BSL_LS_BCM_PORT,
  17978                   (BSL_META("Error: Cannot set autoneg on OAMP Port %d.\n"),
  17979                    port));
  17980         return BCM_E_PARAM;
  17981     }
  17982 
  17983 #if defined(BCM_KATANA2_SUPPORT)
  17984 #if defined(BCM_SABER2_SUPPORT)
  17985     if(SOC_IS_SABER2(unit)) {
  17986         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17987     }
  17988 #endif
  17989     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17990         (!((port >= 1) && (port <= max_phy_port)))) {
  17991          return BCM_E_PORT;
  17992     }
  17993 #endif
  17994 #ifdef BCM_RCPU_SUPPORT
  17995     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  17996         return BCM_E_PORT;
  17997     }
  17998 #endif /* BCM_RCPU_SUPPORT */
  17999 
  18000     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  18001                          &local_port, &phyn, &phy_lane, &sys_side));
  18002 
  18003     if (local_port == -1) {
  18004        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18005     }
  18006 
  18007     PORT_LOCK(unit);
  18008 
  18009 #if defined(BCM_SABER2_SUPPORT)
  18010     if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  18011         rv = soc_phyctrl_enable_get(unit, port, &phy_status);
  18012         if (BCM_FAILURE(rv)) {
  18013             PORT_UNLOCK(unit);
  18014             return (rv);
  18015         }
  18016         if(phy_status == TRUE) {
  18017             rv = soc_phyctrl_enable_set(unit, port, FALSE);
  18018             if (BCM_FAILURE(rv)) {
  18019                 PORT_UNLOCK(unit);
  18020                 return (rv);
  18021             }
  18022         }
  18023     }
  18024 #endif
  18025 
  18026 #ifdef SW_AUTONEG_SUPPORT
  18027     if (soc_feature(unit, soc_feature_sw_autoneg)) {
  18028 
  18029         int           an_mode = 0;
  18030 
  18031         an_mode = soc_property_port_get(unit, port,
  18032                           spn_PHY_AN_C73, an_mode);
  18033 
  18034         /* phy_an_c73 value of 3 indicated MSA AN mode */
  18035         if ((an_mode == SW_AN_MODE_CL73_MSA) ||
  18036             (an_mode == SW_AN_MODE_MSA_ONLY)) {
  18037             if (autoneg) {
  18038                 rv = bcm_sw_an_port_register(unit, port);
  18039                 if (rv == BCM_E_NONE) {
  18040                     PORT_UNLOCK(unit);
  18041                     return rv;
  18042                 } else if (rv == BCM_E_PORT) {
  18043                     /* when an_set is called during the init
  18044                      * ports wouldn't have been added to SW AN
  18045                      */
  18046                     rv = BCM_E_NONE;
  18047                     PORT_UNLOCK(unit);
  18048                     return rv;
  18049                 } else {
  18050                     /* add bsl log */
  18051                     PORT_UNLOCK(unit);
  18052                     return rv;
  18053                 }
  18054 
  18055             } else {
  18056                 rv = bcm_sw_an_port_unregister(unit, port);
  18057                 if (rv == BCM_E_NONE) {
  18058                     PORT_UNLOCK(unit);
  18059                     return rv;
  18060                 } else if (rv == BCM_E_PORT) {
  18061                     /* when an_set is called during the init
  18062                      * ports wouldn't have been added to SW AN
  18063                      */
  18064                     rv = BCM_E_NONE;
  18065                     PORT_UNLOCK(unit);
  18066                     return rv;
  18067                 } else {
  18068                     /* add bsl log */
  18069                     PORT_UNLOCK(unit);
  18070                     return rv;
  18071                 }
  18072             }
  18073         }
  18074     }
  18075 #endif
  18076 
  18077     if (local_port == -1) {
  18078        rv = soc_phyctrl_auto_negotiate_set(unit, port, autoneg);
  18079     } else {
  18080        rv = soc_phyctrl_redirect_auto_negotiate_set(unit, local_port, phyn,
  18081                                                     phy_lane, sys_side, autoneg);
  18082     }
  18083 
  18084 #if defined(BCM_SABER2_SUPPORT)
  18085     if(SOC_IS_SABER2(unit) &&
  18086             IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  18087         /* Enable phy in tsc only if already enabled before config change */
  18088         rv = soc_phyctrl_enable_set(unit, port, TRUE);
  18089         if (BCM_FAILURE(rv)) {
  18090             PORT_UNLOCK(unit);
  18091             return (rv);
  18092         }
  18093     }
  18094 #endif
  18095 
  18096 #if defined(BCM_XMAC_SUPPORT)
  18097    if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  18098       SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18099       uint32 vco_disturbed = 0;
  18100       phy_ctrl_t *int_pc;
  18101        if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  18102                    IS_XE_PORT(unit, port))) {
  18103            int_pc = INT_PHY_SW_STATE(unit, port);
  18104            rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  18105            if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  18106                PORT_UNLOCK(unit);
  18107                return rv;
  18108            }
  18109            if (vco_disturbed) {
  18110                rv = _mac_x_reinit(unit, port);
  18111                if (BCM_FAILURE(rv)) {
  18112                    PORT_UNLOCK(unit);
  18113                    return rv;
  18114                }
  18115            }
  18116        }
  18117    }
  18118 #endif
  18119     PORT_UNLOCK(unit);
  18120 
  18121     LOG_INFO(BSL_LS_BCM_PORT,
  18122              (BSL_META_U(unit,
  18123                          "bcm_port_autoneg_set: u=%d p=%d an=%d rv=%d\n"),
  18124               unit, port, autoneg, rv));
  18125 
  18126     return rv;
  18127 }
  18128 
  18129 /*
  18130  * Function:
  18131  *      bcm_port_speed_get
  18132  * Purpose:
  18133  *      Getting the speed of the port
  18134  * Parameters:
  18135  *      unit - StrataSwitch Unit #.
  18136  *      port - StrataSwitch port #.
  18137  *      speed - (OUT) Value in megabits/sec (10, 100, etc)
  18138  * Returns:
  18139  *      BCM_E_NONE
  18140  *      BCM_E_XXX
  18141  * Notes:
  18142  *      If port is in MAC loopback, the speed of the loopback is returned.
  18143  */
  18144 
  18145 int
  18146 bcm_esw_port_speed_get(int unit, bcm_port_t port, int *speed)
  18147 {
  18148     int         rv = BCM_E_NONE;
  18149     int         mac_lb;
  18150     int         max_speed;
  18151 #if defined(BCM_KATANA2_SUPPORT)
  18152     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18153 #endif
  18154 
  18155     /* Make sure port module is initialized. */
  18156     PORT_INIT(unit);
  18157 
  18158     /* Check for PortMod */
  18159     if (SOC_PORT_USE_PORTCTRL(unit, port) && (port != CMIC_PORT(unit))) {
  18160         return bcmi_esw_portctrl_speed_get(unit, port, speed);
  18161     }
  18162 
  18163 #if defined(BCM_KATANA2_SUPPORT)
  18164 #if defined(BCM_SABER2_SUPPORT)
  18165     if(SOC_IS_SABER2(unit)) {
  18166         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18167     }
  18168 #endif
  18169     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18170         (!((port >= 1) && (port <= max_phy_port) &&
  18171          SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)))) {
  18172           return BCM_E_PORT;
  18173     }
  18174 #endif
  18175 
  18176     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18177         LOG_ERROR(BSL_LS_BCM_PORT,
  18178                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18179                    port));
  18180         return BCM_E_PARAM;
  18181     }
  18182 
  18183     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18184 
  18185     PORT_LOCK(unit);
  18186 
  18187     rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  18188 
  18189     if (BCM_SUCCESS(rv)) {
  18190         if (mac_lb) {
  18191             rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed);
  18192         } else {
  18193             rv = soc_phyctrl_speed_get(unit, port, speed);
  18194 
  18195             if (BCM_E_UNAVAIL == rv) {
  18196                 /* PHY driver doesn't support speed_get. Get the speed from
  18197                  * MAC.
  18198                  */
  18199                 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed);
  18200             }
  18201             if ((IS_HG_PORT(unit, port) && *speed < 5000) && !(IS_HL_PORT(unit,port))) {
  18202                 *speed = 0;
  18203             }
  18204             if (soc_feature(unit, soc_feature_port_encap_speed_max_config)) {
  18205                 rv = bcm_esw_port_speed_max(unit, port, &max_speed);
  18206                 if (BCM_FAILURE(rv)) {
  18207                     PORT_UNLOCK(unit);
  18208                     return (rv);
  18209                 }
  18210                 if (*speed > max_speed) {
  18211                     *speed = max_speed;
  18212                 }
  18213             }
  18214         }
  18215     }
  18216 
  18217     PORT_UNLOCK(unit);
  18218 
  18219     LOG_INFO(BSL_LS_BCM_PORT,
  18220              (BSL_META_U(unit,
  18221                          "bcm_port_speed_get: u=%d p=%d speed=%d rv=%d\n"),
  18222               unit, port, BCM_SUCCESS(rv) ? *speed : 0, rv));
  18223 
  18224     return rv;
  18225 }
  18226 
  18227 /*
  18228  * Function:
  18229  *      bcm_port_speed_max
  18230  * Purpose:
  18231  *      Getting the maximum speed of the port
  18232  * Parameters:
  18233  *      unit - StrataSwitch Unit #.
  18234  *      port - StrataSwitch port #.
  18235  *      speed - (OUT) Value in megabits/sec (10, 100, etc)
  18236  * Returns:
  18237  *      BCM_E_NONE
  18238  *      BCM_E_XXX
  18239  */
  18240 
  18241 int
  18242 bcm_esw_port_speed_max(int unit, bcm_port_t port, int *speed)
  18243 {
  18244     bcm_port_ability_t  ability, phy_ability;
  18245     int                 rv;
  18246     int                 phy_speed;
  18247 #if defined(BCM_KATANA2_SUPPORT)
  18248     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18249 #endif
  18250 
  18251     if (NULL == speed) {
  18252         return (BCM_E_PARAM);
  18253     }
  18254 
  18255     /* Make sure port module is initialized. */
  18256     PORT_INIT(unit);
  18257 
  18258 
  18259     /* Check for PortMod */
  18260     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  18261         return bcmi_esw_portctrl_speed_max(unit, port, speed);
  18262     }
  18263 
  18264 #if defined(BCM_KATANA2_SUPPORT)
  18265 #if defined(BCM_SABER2_SUPPORT)
  18266     if(SOC_IS_SABER2(unit)) {
  18267         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18268     }
  18269 #endif
  18270     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18271         (!((port >= 1) && (port <= max_phy_port)))) {
  18272          return BCM_E_PORT;
  18273     }
  18274 #endif
  18275 
  18276     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18277         LOG_ERROR(BSL_LS_BCM_PORT,
  18278                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18279                    port));
  18280         return BCM_E_PARAM;
  18281     }
  18282 
  18283 
  18284     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18285     rv = bcm_esw_port_ability_local_get(unit, port, &ability);
  18286 
  18287     if (BCM_SUCCESS(rv)) {
  18288 
  18289         *speed = BCM_PORT_ABILITY_SPEED_MAX(ability.speed_full_duplex |
  18290                                             ability.speed_half_duplex);
  18291 
  18292         if (10000 == *speed) {
  18293             if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) {
  18294                 *speed = SOC_INFO(unit).port_speed_max[port];
  18295                 /* Retrieving the internal PHY ability */
  18296                 rv = soc_phyctrl_ability_local_get(unit, port, &phy_ability);
  18297                 if (BCM_SUCCESS(rv)) {
  18298                     /* considering the common supported speed among phy and mac */
  18299                     phy_speed = BCM_PORT_ABILITY_SPEED_MAX(
  18300                                              phy_ability.speed_full_duplex |
  18301                                              phy_ability.speed_half_duplex);
  18302                     *speed = (*speed > phy_speed) ? phy_speed : *speed;
  18303                 } else {
  18304                     *speed = 0;
  18305                 }
  18306             }
  18307         }
  18308     } else {
  18309         *speed = 0;
  18310     }
  18311 
  18312     LOG_INFO(BSL_LS_BCM_PORT,
  18313              (BSL_META_U(unit,
  18314                          "bcm_port_speed_max: u=%d p=%d speed=%d rv=%d\n"),
  18315               unit, port, *speed, rv));
  18316 
  18317     return rv;
  18318 }
  18319 
  18320 /*
  18321  * Function    : _bcm_port_speed_supported
  18322  * Description : Determine whether port speed is supported based on
  18323  *               number of lanes configured
  18324  * Parameters  : unit  (IN)
  18325  *               port  (IN)
  18326  *               speed (IN)
  18327  * Returns     : BCM_E_XXX
  18328  * Note        : Caller needs to ensure soc_feature_flexport_based_speed_set
  18329  *               is defined
  18330  */
  18331 STATIC bcm_error_t
  18332 _bcm_port_speed_supported(int unit, bcm_port_t port, int speed)
  18333 {
  18334 #ifdef BCM_TOMAHAWK_SUPPORT
  18335     if (SOC_IS_TOMAHAWKX(unit)) {
  18336         BCM_IF_ERROR_RETURN(_bcm_th_port_speed_supported(unit, port, speed));
  18337     }
  18338 #endif
  18339     return BCM_E_NONE;
  18340 }
  18341 
  18342 /*
  18343  * Function:
  18344  *      _bcm_port_speed_set
  18345  * Purpose:
  18346  *      Main part of bcm_port_speed_set.
  18347  */
  18348 
  18349 STATIC int
  18350 _bcm_port_speed_set(int unit, bcm_port_t port, int speed)
  18351 {
  18352     int             phy_lb, rv, enable;
  18353     int             mac_lb;
  18354     int             ignore_ability_check = FALSE;
  18355     bcm_port_ability_t mac_ability, phy_ability, requested_ability;
  18356 #if defined(BCM_SABER2_SUPPORT)
  18357     int             phy_status;
  18358 #endif
  18359 
  18360 #if defined(BCM_TOMAHAWK_SUPPORT)
  18361     int             cur_speed;
  18362 #endif
  18363 #if defined(BCM_KATANA2_SUPPORT)
  18364     bcmMxqPhyPortMode_t phy_mode = bcmMxqPhyPortModeQuad;
  18365 #endif
  18366 
  18367 
  18368     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  18369         return bcmi_esw_portctrl_speed_set(unit, port, speed);
  18370     }
  18371 
  18372     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18373         LOG_ERROR(BSL_LS_BCM_PORT,
  18374                   (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"),
  18375                    port));
  18376         return BCM_E_PARAM;
  18377     }
  18378 
  18379     sal_memset(&mac_ability, 0, sizeof(bcm_port_ability_t));
  18380     sal_memset(&phy_ability, 0, sizeof(bcm_port_ability_t));
  18381     sal_memset(&requested_ability, 0, sizeof(bcm_port_ability_t));
  18382 
  18383     /*
  18384      * If port is in MAC loopback mode, do not try setting the PHY
  18385      * speed.  This allows MAC loopback at 10/100 even if the PHY is
  18386      * 1000 only.  Loopback diagnostic tests should enable loopback
  18387      * before setting the speed, and vice versa when cleaning up.
  18388      */
  18389 
  18390     SOC_IF_ERROR_RETURN
  18391         (MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb));
  18392 
  18393     if (speed == 0) {
  18394         /* if speed is 0, set the port speed to max */
  18395         SOC_IF_ERROR_RETURN
  18396             (bcm_esw_port_speed_max(unit, port, &speed));
  18397     }
  18398 
  18399     /* Make sure MAC can handle the requested speed. */
  18400     SOC_IF_ERROR_RETURN
  18401         (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port,
  18402                                &mac_ability));
  18403     requested_ability.speed_full_duplex = SOC_PA_SPEED(speed);
  18404     requested_ability.speed_half_duplex = SOC_PA_SPEED(speed);
  18405     LOG_INFO(BSL_LS_BCM_PHY,
  18406              (BSL_META_U(unit,
  18407                          "_bcm_port_speed_set: u=%u p=%d "
  18408                          "MAC FD speed %08X MAC HD speed %08X "
  18409                          "Requested FD Speed %08X Requested HD Speed %08X\n"),
  18410               unit,
  18411               port,
  18412               mac_ability.speed_full_duplex,
  18413               mac_ability.speed_half_duplex,
  18414               requested_ability.speed_full_duplex,
  18415               requested_ability.speed_half_duplex));
  18416     /*
  18417      * On certain devices such as TH speed set is a flexport operation,
  18418      * due to changes needed to the calendar. This is not applicable to
  18419      * mgmt ports on TH as they are guranteed a fixed amount of BW in the
  18420      * calendar.
  18421      */
  18422     if ((soc_feature(unit, soc_feature_flexport_based_speed_set)) &&
  18423         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) {
  18424             rv = _bcm_port_speed_supported(unit, port, speed);
  18425             if (BCM_SUCCESS(rv)) {
  18426                 ignore_ability_check = TRUE;
  18427             }
  18428     }
  18429 
  18430 #if defined(BCM_TOMAHAWK_SUPPORT)
  18431     if (SOC_IS_TOMAHAWK(unit)) {
  18432         int encap;
  18433         BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap));
  18434 
  18435         if (IS_HG2_SPEED(speed) && (encap == BCM_PORT_ENCAP_IEEE)) {
  18436             LOG_ERROR(BSL_LS_BCM_PORT,
  18437                   (BSL_META_U(unit,
  18438                               "Speed and encapsulation configuration unmatch "
  18439                               "for port=%d, speed=%d, encap=%d\n"),
  18440                    port, speed, encap));
  18441             return BCM_E_CONFIG;
  18442         }
  18443     }
  18444 #endif
  18445 
  18446     if (((mac_ability.speed_full_duplex &
  18447           requested_ability.speed_full_duplex) == 0) &&
  18448         ((mac_ability.speed_half_duplex &
  18449           requested_ability.speed_half_duplex) == 0) &&
  18450         !ignore_ability_check) {
  18451         LOG_ERROR(BSL_LS_BCM_PORT,
  18452                     (BSL_META_U(unit,
  18453                                 "u=%d p=%d MAC doesn't support %d Mbps speed.\n"),
  18454                      unit, port, speed));
  18455         return SOC_E_CONFIG;
  18456     }
  18457     SOC_IF_ERROR_RETURN
  18458         (soc_phyctrl_ability_local_get(unit, port, &phy_ability));
  18459 
  18460     if (((phy_ability.speed_full_duplex &
  18461           requested_ability.speed_full_duplex) == 0) &&
  18462         ((phy_ability.speed_half_duplex &
  18463           requested_ability.speed_half_duplex) == 0) &&
  18464         !ignore_ability_check) {
  18465             LOG_VERBOSE(BSL_LS_BCM_PORT,
  18466                         (BSL_META_U(unit,
  18467                                     "u=%d p=%d PHY doesn't support %d Mbps speed.\n"),
  18468                          unit, port, speed));
  18469             return SOC_E_CONFIG;
  18470     } else {
  18471 
  18472 #if defined(BCM_SABER2_SUPPORT)
  18473         if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  18474             BCM_IF_ERROR_RETURN(soc_phyctrl_enable_get(unit, port, &phy_status));
  18475             if(phy_status == TRUE) {
  18476                 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, FALSE));
  18477             }
  18478         }
  18479 #endif
  18480 
  18481 #if defined(BCM_TOMAHAWK_SUPPORT)
  18482         if (SOC_IS_TOMAHAWKX(unit)) {
  18483             SOC_IF_ERROR_RETURN
  18484                 (soc_phyctrl_speed_get(unit, port, &cur_speed));
  18485         }
  18486 #endif
  18487 #if defined(BCM_KATANA2_SUPPORT)
  18488         if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  18489             SOC_IF_ERROR_RETURN
  18490                 (soc_katana2_get_phy_port_mode(unit, port, speed, &phy_mode));
  18491         }
  18492 #endif
  18493         SOC_IF_ERROR_RETURN
  18494             (soc_phyctrl_auto_negotiate_set(unit, port, FALSE));
  18495         SOC_IF_ERROR_RETURN
  18496             (soc_phyctrl_speed_set(unit, port, speed));
  18497 
  18498 #if defined(BCM_SABER2_SUPPORT)
  18499         if(SOC_IS_SABER2(unit) &&
  18500                 IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  18501             /* Enable phy in tsc only if already enabled before config change */
  18502             BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, TRUE));
  18503         }
  18504 #endif
  18505 
  18506 #if defined(BCM_XMAC_SUPPORT)
  18507         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  18508             SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18509             uint32 vco_disturbed = 0;
  18510             phy_ctrl_t *int_pc;
  18511             if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  18512                         IS_XE_PORT(unit, port))) {
  18513 
  18514                 int_pc = INT_PHY_SW_STATE(unit, port);
  18515                 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  18516                 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  18517                     return rv;
  18518                 }
  18519                 if (vco_disturbed) {
  18520                     BCM_IF_ERROR_RETURN(_mac_x_reinit(unit, port));
  18521                 }
  18522             }
  18523         }
  18524 #endif
  18525     }
  18526 
  18527     /* TSC needs no legacy war */
  18528     if (!SOC_IS_TD2_TT2(unit)) {
  18529        /* Prevent PHY register access while resetting BigMAC and Fusion core */
  18530        if (IS_HG_PORT(unit, port)) {
  18531           soc_phyctrl_enable_get(unit, port, &enable);
  18532           soc_phyctrl_enable_set(unit, port, 0);
  18533           soc_phyctrl_loopback_get(unit, port, &phy_lb);
  18534        }
  18535     }
  18536     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18537         BCM_IF_ERROR_RETURN(_bcm_td_port_mode_update(unit, port, speed));
  18538     }
  18539 
  18540 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  18541     /* Reconfigure chip(PGW/TDM/IP/EP/MMU) for speed set change */
  18542     if (BCM_ESW_PORT_DRV(unit)!= NULL &&
  18543         !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))) {
  18544         if (BCM_ESW_PORT_DRV(unit)->resource_speed_set != NULL) {
  18545             rv = BCM_ESW_PORT_DRV(unit)->resource_speed_set(unit, port, speed);
  18546             if (BCM_FAILURE(rv)) {
  18547                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  18548                             (BSL_META_UP(unit, port,
  18549                                          "resource_speed_set failed: %s\n"),
  18550                                          bcm_errmsg(rv)));
  18551                 return rv;
  18552             }
  18553         }
  18554     }
  18555 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT*/
  18556 
  18557     rv = MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed);
  18558     if (BCM_FAILURE(rv)) {
  18559 #if defined(BCM_TOMAHAWK_SUPPORT)
  18560         if (SOC_IS_TOMAHAWKX(unit)) {
  18561             /* Restore phy's speed state based on what was read periously */
  18562             SOC_IF_ERROR_RETURN
  18563                 (soc_phyctrl_speed_set(unit, port, cur_speed));
  18564         }
  18565 #endif
  18566 
  18567         LOG_VERBOSE(BSL_LS_BCM_PORT,
  18568                     (BSL_META_U(unit,
  18569                                 "MAC_SPEED_SET failed: %s\n"), bcm_errmsg(rv)));
  18570     }
  18571 
  18572 if (!SOC_IS_MONTEREY(unit)) {
  18573     /* TSC needs no legacy war */
  18574     if (!SOC_IS_TD2_TT2(unit)) {
  18575        /* Restore PHY register access */
  18576        if (IS_HG_PORT(unit, port)) {
  18577           soc_phyctrl_enable_set(unit, port, enable);
  18578           soc_phyctrl_loopback_set(unit, port, phy_lb, TRUE);
  18579        }
  18580     }
  18581 }
  18582 
  18583     return rv;
  18584 }
  18585 
  18586 /*
  18587  * Function:
  18588  *      bcm_port_speed_set
  18589  * Purpose:
  18590  *      Setting the speed for a given port
  18591  * Parameters:
  18592  *      unit - StrataSwitch Unit #.
  18593  *      port - StrataSwitch port #.
  18594  *      speed - Value in megabits/sec (10, 100, etc)
  18595  * Returns:
  18596  *      BCM_E_NONE
  18597  *      BCM_E_XXX
  18598  * Notes:
  18599  *      Turns off autonegotiation.  Caller must make sure other forced
  18600  *      parameters (such as duplex) are set.
  18601  */
  18602 
  18603 int
  18604 bcm_esw_port_speed_set(int unit, bcm_port_t port, int speed)
  18605 {
  18606     int    rv=BCM_E_NONE, max_speed, enable, rv1 = BCM_E_NONE;
  18607     pbmp_t pbm;
  18608     int    curr_speed = 0;
  18609     bcm_port_if_t curr_intf = 0;
  18610 #if defined(BCM_KATANA2_SUPPORT)
  18611     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18612 #endif
  18613 
  18614 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  18615     sal_usecs_t time_start = 0;
  18616     sal_usecs_t time_end = 0;
  18617 #endif
  18618 
  18619     /* Make sure port module is initialized. */
  18620     PORT_INIT(unit);
  18621 
  18622 #if defined(BCM_TOMAHAWK3_SUPPORT)
  18623     /* Don't allow PM8x50 to do bcm_port_speed_set */
  18624     if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) {
  18625         return BCM_E_UNAVAIL;
  18626     }
  18627 #endif
  18628 
  18629     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18630         LOG_ERROR(BSL_LS_BCM_PORT,
  18631                   (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"),
  18632                    port));
  18633         return BCM_E_PARAM;
  18634     }
  18635 
  18636 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  18637     time_start = sal_time_usecs();
  18638 #endif
  18639 
  18640 #if defined(BCM_KATANA2_SUPPORT)
  18641 #if defined(BCM_SABER2_SUPPORT)
  18642     if(SOC_IS_SABER2(unit)) {
  18643         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18644     }
  18645 #endif
  18646     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18647         (!((port >= 1) && (port <= max_phy_port)))) {
  18648          return BCM_E_PORT;
  18649     }
  18650 #endif
  18651     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18652 
  18653 #if defined(BCM_FIREBOLT6_SUPPORT)
  18654     if (SOC_IS_FIREBOLT6(unit)) {
  18655         if (!(SAL_BOOT_SIMULATION)) {
  18656             /* Validate speeds based on OTP. */
  18657             if (_soc_fb6_port_speed_validate(unit, port, -1, -1, -1, speed)) {
  18658                 return BCM_E_CONFIG;
  18659             }
  18660         }
  18661     }
  18662 #endif
  18663 
  18664     if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE,
  18665                          (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) {
  18666         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &curr_speed));
  18667         BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &curr_intf));
  18668         if((speed == curr_speed) && (PORT(unit, port).intf == curr_intf)) {
  18669 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  18670             time_end = SAL_USECS_SUB(sal_time_usecs(), time_start);
  18671             LOG_INFO(BSL_LS_BCM_BENCHMARK,
  18672                     (BSL_META_U(unit,
  18673                                 "\nPort %d speed change to %d processing took %d usecs\n"),
  18674                                 port,
  18675                                 speed,
  18676                                 time_end));
  18677 #endif
  18678             return BCM_E_NONE;
  18679         }
  18680     }
  18681 
  18682 #ifdef BCM_RCPU_SUPPORT
  18683     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18684         return BCM_E_PORT;
  18685     }
  18686 #endif /* BCM_RCPU_SUPPORT */
  18687 
  18688     /*    coverity[uninit_use_in_call : FALSE]    */
  18689     BCM_IF_ERROR_RETURN
  18690         (bcm_esw_port_speed_max(unit,port, &max_speed));
  18691 
  18692     if (IS_XL_PORT(unit,port) && (speed == 12700)) {
  18693         speed = 13000;
  18694     }
  18695 
  18696     if ((speed < 0) || (speed > max_speed)) {
  18697         if ((speed > max_speed) &&
  18698             !soc_feature(unit, soc_feature_flexport_based_speed_set))
  18699         return BCM_E_CONFIG; 
  18700     }
  18701 
  18702 #if defined(BCM_TOMAHAWK_SUPPORT)
  18703     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) {
  18704         int cur_speed;
  18705 
  18706         BCM_IF_ERROR_RETURN
  18707             (bcm_esw_port_speed_get(unit, port, &cur_speed));
  18708         if ((speed == 0) && (max_speed == cur_speed)) {
  18709             /* no speed set is required */
  18710             return BCM_E_NONE;
  18711         }
  18712     }
  18713 #endif /* BCM_TOMAHAWK_SUPPORT */
  18714 
  18715     /*
  18716      * When performing flexport based speed changes, disable port
  18717      * first prior to affecting speed change
  18718      */
  18719     if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  18720         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) &&
  18721         !SOC_PORT_USE_PORTCTRL(unit, port)) {
  18722         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  18723         if (TRUE == enable) {
  18724             BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, FALSE));
  18725         }
  18726     }
  18727 
  18728     PORT_LOCK(unit);                    /* multiple operations operation */
  18729 
  18730     rv = _bcm_port_speed_set(unit, port, speed);
  18731     PORT_UNLOCK(unit);                  /* Unlock before link call */
  18732     /*
  18733      * Restore port's enable state based on what was read prior
  18734      * to setting speed
  18735      */
  18736     if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  18737         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) &&
  18738         !SOC_PORT_USE_PORTCTRL(unit, port)) {
  18739         if (TRUE == enable) {
  18740             BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, TRUE));
  18741         }
  18742     }
  18743 
  18744     if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  18745         SOC_PBMP_CLEAR(pbm);
  18746         SOC_PBMP_PORT_ADD(pbm, port);
  18747         (void)bcm_esw_link_change(unit, pbm);
  18748     }
  18749     PORT_LOCK(unit);                    /* multiple operations operation */
  18750     rv1 = _bcm_esw_port_link_delay_update(unit, port, speed);
  18751     PORT_UNLOCK(unit);                  /* Unlock before link call */
  18752     if (BCM_FAILURE(rv1)) {
  18753         if (BCM_SUCCESS(rv)) {
  18754             rv = rv1;
  18755         }
  18756     }
  18757 
  18758 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  18759     time_end = SAL_USECS_SUB(sal_time_usecs(), time_start);
  18760     LOG_INFO(BSL_LS_BCM_BENCHMARK,
  18761             (BSL_META_U(unit,
  18762                         "\nPort %d speed change to %d processing took %d usecs\n"),
  18763                         port,
  18764                         speed,
  18765                         time_end));
  18766 #endif
  18767 
  18768     LOG_INFO(BSL_LS_BCM_PORT,
  18769              (BSL_META_U(unit,
  18770                          "bcm_port_speed_set: u=%d p=%d speed=%d rv=%d\n"),
  18771               unit, port, speed, rv));
  18772 
  18773    return rv;
  18774 }
  18775 
  18776 /*
  18777  * Function:
  18778  *      bcm_port_master_get
  18779  * Purpose:
  18780  *      Getting the master status of the port
  18781  * Parameters:
  18782  *      unit - StrataSwitch Unit #.
  18783  *      port - StrataSwitch port #.
  18784  *      ms - (OUT) BCM_PORT_MS_*
  18785  * Returns:
  18786  *      BCM_E_NONE
  18787  *      BCM_E_XXX
  18788  * Notes:
  18789  *      WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_*
  18790  */
  18791 
  18792 int
  18793 bcm_esw_port_master_get(int unit, bcm_port_t port, int *ms)
  18794 {
  18795     int         rv=BCM_E_NONE;
  18796 #if defined(BCM_KATANA2_SUPPORT)
  18797     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18798 #endif
  18799 
  18800     /* Make sure port module is initialized. */
  18801     PORT_INIT(unit);
  18802 
  18803     /* Call Port Control module */
  18804     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  18805         return bcmi_esw_portctrl_master_get(unit, port, ms);
  18806     }
  18807 
  18808 #if defined(BCM_KATANA2_SUPPORT)
  18809 #if defined(BCM_SABER2_SUPPORT)
  18810     if(SOC_IS_SABER2(unit)) {
  18811         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18812     }
  18813 #endif
  18814     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18815         (!((port >= 1) && (port <= max_phy_port)))) {
  18816          return BCM_E_PORT;
  18817     }
  18818 #endif
  18819 
  18820     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18821     PORT_LOCK(unit);
  18822     rv = soc_phyctrl_master_get(unit, port, ms);
  18823     PORT_UNLOCK(unit);
  18824     return rv;
  18825 }
  18826 
  18827 /*
  18828  * Function:
  18829  *      bcm_port_master_set
  18830  * Purpose:
  18831  *      Setting the master status for a given port
  18832  * Parameters:
  18833  *      unit - StrataSwitch Unit #.
  18834  *      port - StrataSwitch port #.
  18835  *      ms - BCM_PORT_MS_*
  18836  * Returns:
  18837  *      BCM_E_NONE
  18838  *      BCM_E_XXX
  18839  * Notes:
  18840  *      Ignored if not supported on port.
  18841  *      WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_*
  18842  */
  18843 
  18844 int
  18845 bcm_esw_port_master_set(int unit, bcm_port_t port, int ms)
  18846 {
  18847     int         rv;
  18848     pbmp_t      pbm;
  18849 #if defined(BCM_KATANA2_SUPPORT)
  18850     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18851 #endif
  18852 
  18853     /* Make sure port module is initialized. */
  18854     PORT_INIT(unit);
  18855 
  18856     /* Call Port Control module */
  18857     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  18858         return bcmi_esw_portctrl_master_set(unit, port, ms);
  18859     }
  18860 
  18861     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18862         LOG_ERROR(BSL_LS_BCM_PORT,
  18863                   (BSL_META("Error: Cannot configure OAMP Port %d to be master.\n"),
  18864                    port));
  18865         return BCM_E_PARAM;
  18866     }
  18867 
  18868 #if defined(BCM_KATANA2_SUPPORT)
  18869 #if defined(BCM_SABER2_SUPPORT)
  18870     if(SOC_IS_SABER2(unit)) {
  18871         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18872     }
  18873 #endif
  18874     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18875         (!((port >= 1) && (port <= max_phy_port)))) {
  18876          return BCM_E_PORT;
  18877     }
  18878 #endif
  18879 
  18880     /* Make sure port module is initialized. */
  18881     PORT_INIT(unit);
  18882 
  18883     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18884 
  18885 #ifdef BCM_RCPU_SUPPORT
  18886     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18887         return BCM_E_PORT;
  18888     }
  18889 #endif /* BCM_RCPU_SUPPORT */
  18890 
  18891     PORT_LOCK(unit);                    /* multiple operations operation */
  18892 
  18893     rv = soc_phyctrl_master_set(unit, port, ms);
  18894     if (BCM_FAILURE(rv)) {
  18895         LOG_VERBOSE(BSL_LS_BCM_PORT,
  18896                     (BSL_META_U(unit,
  18897                                 "PHY_MASTER_SETfailed:%s\n"), bcm_errmsg(rv)));
  18898     }
  18899 
  18900 #if defined(BCM_XMAC_SUPPORT)
  18901     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  18902        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18903        uint32 vco_disturbed = 0;
  18904        phy_ctrl_t *int_pc;
  18905         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  18906                     IS_XE_PORT(unit, port))) {
  18907 
  18908             int_pc = INT_PHY_SW_STATE(unit, port);
  18909             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  18910             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  18911                 PORT_UNLOCK(unit);
  18912                 return rv;
  18913             }
  18914             if (vco_disturbed) {
  18915                 rv = _mac_x_reinit(unit, port);
  18916                 if (BCM_FAILURE(rv)) {
  18917                     PORT_UNLOCK(unit);
  18918                     return rv;
  18919                 }
  18920             }
  18921         }
  18922     }
  18923 #endif
  18924     PORT_UNLOCK(unit);                  /* Unlock before link call */
  18925 
  18926     if (BCM_SUCCESS(rv)) {
  18927         SOC_PBMP_CLEAR(pbm);
  18928         SOC_PBMP_PORT_ADD(pbm, port);
  18929         (void)bcm_esw_link_change(unit, pbm);
  18930     }
  18931 
  18932     return rv;
  18933 }
  18934 
  18935 /*
  18936  * Function:
  18937  *      bcm_port_interface_get
  18938  * Purpose:
  18939  *      Getting the interface type of a port
  18940  * Parameters:
  18941  *      unit - StrataSwitch Unit #.
  18942  *      port - StrataSwitch port #.
  18943  *      intf - (OUT) BCM_PORT_IF_*
  18944  * Returns:
  18945  *      BCM_E_NONE
  18946  *      BCM_E_XXX
  18947  * Notes:
  18948  *      WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_*
  18949  */
  18950 
  18951 int
  18952 bcm_esw_port_interface_get(int unit, bcm_port_t port, bcm_port_if_t *intf)
  18953 {
  18954     int         rv=BCM_E_NONE;
  18955 #if defined(BCM_KATANA2_SUPPORT)
  18956     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18957 #endif
  18958 
  18959     /* Make sure port module is initialized. */
  18960     PORT_INIT(unit);
  18961 
  18962     /* Call Port Control module */
  18963     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  18964         return bcmi_esw_portctrl_interface_get(unit, port, intf);
  18965     }
  18966 
  18967     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18968         LOG_ERROR(BSL_LS_BCM_PORT,
  18969                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18970                    port));
  18971         return BCM_E_PARAM;
  18972     }
  18973 
  18974 #if defined(BCM_KATANA2_SUPPORT)
  18975 #if defined(BCM_SABER2_SUPPORT)
  18976     if(SOC_IS_SABER2(unit)) {
  18977         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18978     }
  18979 #endif
  18980     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18981         (!((port >= 1) && (port <= max_phy_port)))) {
  18982          return BCM_E_PORT;
  18983     }
  18984 #endif
  18985 
  18986     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18987 
  18988     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  18989         return BCM_E_PORT;
  18990     }
  18991     PORT_LOCK(unit);
  18992     rv = soc_phyctrl_interface_get(unit, port, intf);
  18993     PORT_UNLOCK(unit);
  18994     return rv;
  18995 }
  18996 
  18997 /*
  18998  * Function:
  18999  *      bcm_port_interface_set
  19000  * Purpose:
  19001  *      Setting the interface type for a given port
  19002  * Parameters:
  19003  *      unit - StrataSwitch Unit #.
  19004  *      port - StrataSwitch port #.
  19005  *      if - BCM_PORT_IF_*
  19006  * Returns:
  19007  *      BCM_E_NONE
  19008  *      BCM_E_XXX
  19009  * Notes:
  19010  *      WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_*
  19011  */
  19012 
  19013 int
  19014 bcm_esw_port_interface_set(int unit, bcm_port_t port, bcm_port_if_t intf)
  19015 {
  19016     int         rv;
  19017     pbmp_t      pbm;
  19018 #if defined(BCM_KATANA2_SUPPORT)
  19019     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19020 #endif
  19021 
  19022     /* Make sure port module is initialized. */
  19023     PORT_INIT(unit);
  19024 
  19025     /* Call Port Control module */
  19026     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19027         return bcmi_esw_portctrl_interface_set(unit, port, intf);
  19028     }
  19029 
  19030     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19031         LOG_ERROR(BSL_LS_BCM_PORT,
  19032                   (BSL_META(
  19033 				   		"Error: Cannot set interface type on OAMP Port %d.\n"),
  19034                    port));
  19035         return BCM_E_PARAM;
  19036     }
  19037 
  19038 #if defined(BCM_KATANA2_SUPPORT)
  19039 #if defined(BCM_SABER2_SUPPORT)
  19040     if(SOC_IS_SABER2(unit)) {
  19041         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19042     }
  19043 #endif
  19044     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19045         (!((port >= 1) && (port <= max_phy_port)))) {
  19046          return BCM_E_PORT;
  19047     }
  19048 #endif
  19049 
  19050     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19051 
  19052     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  19053         return BCM_E_PORT;
  19054     }
  19055 
  19056 #ifdef BCM_RCPU_SUPPORT
  19057     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  19058         return BCM_E_PORT;
  19059     }
  19060 #endif /* BCM_RCPU_SUPPORT */
  19061 
  19062     PORT_LOCK(unit);                    /* multiple operations operation */
  19063 
  19064     rv = soc_phyctrl_interface_set(unit, port, intf);
  19065     if (BCM_FAILURE(rv)) {
  19066         LOG_VERBOSE(BSL_LS_BCM_PORT,
  19067                     (BSL_META_U(unit,
  19068                                 "PHY_INTERFACE_SETfailed:%s\n"), bcm_errmsg(rv)));
  19069     }
  19070 #if defined(BCM_XMAC_SUPPORT)
  19071     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  19072        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  19073        uint32 vco_disturbed = 0;
  19074        phy_ctrl_t *int_pc;
  19075         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  19076                     IS_XE_PORT(unit, port))) {
  19077 
  19078             int_pc = INT_PHY_SW_STATE(unit, port);
  19079             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  19080             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  19081                 PORT_UNLOCK(unit);
  19082                 return rv;
  19083             }
  19084             if (vco_disturbed) {
  19085                 rv = _mac_x_reinit(unit, port);
  19086                 if (BCM_FAILURE(rv)) {
  19087                     PORT_UNLOCK(unit);
  19088                     return rv;
  19089                 }
  19090             }
  19091         }
  19092     }
  19093 #endif
  19094 
  19095     PORT_UNLOCK(unit);                  /* Unlock before link call */
  19096 
  19097     if (BCM_SUCCESS(rv)) {
  19098         SOC_PBMP_CLEAR(pbm);
  19099         SOC_PBMP_PORT_ADD(pbm, port);
  19100         (void)bcm_esw_link_change(unit, pbm);
  19101         PORT(unit, port).intf = intf;
  19102     }
  19103 
  19104     return rv;
  19105 }
  19106 
  19107 /*
  19108  * Function:
  19109  *      bcm_port_loopback_set
  19110  * Purpose:
  19111  *      Setting the speed for a given port
  19112  * Parameters:
  19113  *      unit - StrataSwitch Unit #.
  19114  *      port - StrataSwitch port #.
  19115  *      loopback - one of:
  19116  *              BCM_PORT_LOOPBACK_NONE
  19117  *              BCM_PORT_LOOPBACK_MAC
  19118  *              BCM_PORT_LOOPBACK_PHY
  19119  * Returns:
  19120  *      BCM_E_NONE
  19121  *      BCM_E_XXX
  19122  */
  19123 
  19124 int
  19125 bcm_esw_port_loopback_set(int unit, bcm_port_t port, int loopback)
  19126 {
  19127     int             rv, link = TRUE;
  19128     int             phy_lane = -1;
  19129     int             phyn = 0, sys_side = 0;
  19130     bcm_port_t      local_port = -1;
  19131 #if defined(BCM_TOMAHAWK_SUPPORT)
  19132     uint32          link_st = 0;
  19133     soc_timeout_t   to;
  19134     int             phy_port;
  19135 #endif
  19136     soc_persist_t   *sop = SOC_PERSIST(unit);
  19137 
  19138 #ifdef BCM_TRIDENT2_SUPPORT
  19139     int             enable;
  19140 #endif /* BCM_TRIDENT2_SUPPORT */
  19141 #if defined(BCM_KATANA2_SUPPORT)
  19142     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19143 #endif
  19144 
  19145     /* Make sure port module is initialized. */
  19146     PORT_INIT(unit);
  19147 
  19148     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19149         /* Check if port have to force-loopback */
  19150         if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  19151             if (BCM_ESW_PORT_DRV(unit)->force_lb_check != NULL) {
  19152                 rv = BCM_ESW_PORT_DRV(unit)->force_lb_check(unit, port,
  19153                                                             loopback);
  19154                 if (rv != BCM_E_NONE) {
  19155                     LOG_ERROR(BSL_LS_BCM_PORT,
  19156                               (BSL_META("Error: Port %d allow PHY internal "
  19157                                         "loopback only.\n"),
  19158                                port));
  19159                     return BCM_E_PARAM;
  19160                 }
  19161             }
  19162         }
  19163 
  19164         return bcmi_esw_portctrl_loopback_set(unit, port, loopback);
  19165     }
  19166 
  19167     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19168         LOG_ERROR(BSL_LS_BCM_PORT,
  19169                   (BSL_META("Error: Cannot set loopback on OAMP Port %d.\n"),
  19170                    port));
  19171         return BCM_E_PARAM;
  19172     }
  19173 
  19174 #if defined(BCM_KATANA2_SUPPORT)
  19175 #if defined(BCM_SABER2_SUPPORT)
  19176     if(SOC_IS_SABER2(unit)) {
  19177         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19178     }
  19179 #endif
  19180     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19181         (!((port >= 1) && (port <= max_phy_port)))) {
  19182          return BCM_E_PORT;
  19183     }
  19184 #endif
  19185 
  19186     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  19187                                                         &local_port, &phyn,
  19188                                                         &phy_lane, &sys_side));
  19189 
  19190     if (local_port == -1) {
  19191        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19192     } else {
  19193        port = local_port;
  19194     }
  19195 
  19196 #if defined(BCM_TOMAHAWK_SUPPORT)
  19197     if (SOC_IS_TOMAHAWKX(unit)) {
  19198         BCM_IF_ERROR_RETURN(bcm_th_phy_lb_check(unit, port, loopback));
  19199     }
  19200 #endif
  19201 
  19202 #ifdef BCM_RCPU_SUPPORT
  19203     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  19204         return BCM_E_PORT;
  19205     }
  19206 #endif /* BCM_RCPU_SUPPORT */
  19207 
  19208     PORT_LOCK(unit);
  19209     soc_phyctrl_enable_get(unit, port, &link);
  19210     PORT_UNLOCK(unit);
  19211     if (TRUE == link) {
  19212         if (SOC_PBMP_MEMBER(sop->lc_pbm_override_ports, port)) {
  19213             if(!SOC_PBMP_MEMBER(sop->lc_pbm_override_link, port)) {
  19214                 link = FALSE;
  19215             }
  19216         }
  19217     }
  19218 
  19219     rv = BCM_E_NONE;
  19220     /*
  19221      * Always force link before changing hardware to avoid
  19222      * race with the linkscan thread.
  19223      */
  19224     if (!(loopback == BCM_PORT_LOOPBACK_NONE)) {
  19225         rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, FALSE);
  19226 
  19227         if(rv == BCM_E_NONE) {
  19228             /* Force the update function to be called so the state is
  19229                updated */
  19230             if (_soc_linkscan_phy_flags_test(unit, port, PHY_FLAGS_EXTERNAL_PHY)) {
  19231                 rv = bcm_esw_port_update(unit, port, TRUE);
  19232             }
  19233         }
  19234     }
  19235 
  19236     PORT_LOCK(unit);
  19237 
  19238     if (BCM_SUCCESS(rv)) {
  19239         rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port,
  19240                               (loopback == BCM_PORT_LOOPBACK_MAC));
  19241     }
  19242     if (BCM_SUCCESS(rv)) {
  19243         if (local_port == -1) {
  19244             if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) {
  19245                 rv = soc_phyctrl_control_set(unit, port,
  19246                                              SOC_PHY_CONTROL_LOOPBACK_REMOTE, 1);
  19247             } else {
  19248                 if (loopback == BCM_PORT_LOOPBACK_NONE) {
  19249                     rv = soc_phyctrl_control_set(unit, port,
  19250                                              SOC_PHY_CONTROL_LOOPBACK_REMOTE, 0);
  19251                 }
  19252 
  19253                 if (rv == SOC_E_NONE || rv == SOC_E_UNAVAIL) {
  19254                     rv = soc_phyctrl_loopback_set(unit, port,
  19255                                                   (loopback == BCM_PORT_LOOPBACK_PHY),
  19256                                                   TRUE);
  19257                 }
  19258             }
  19259 
  19260         } else {
  19261             rv = soc_phyctrl_redirect_loopback_set
  19262                                           (unit, port, phyn,
  19263                                            phy_lane, sys_side,
  19264                                            (loopback == BCM_PORT_LOOPBACK_PHY),
  19265                                            TRUE);
  19266         }
  19267     }
  19268     /* some mac loopback implementations require the phy to also be in loopback */
  19269     if (soc_feature(unit, soc_feature_phy_lb_needed_in_mac_lb) &&
  19270         (loopback == BCM_PORT_LOOPBACK_MAC)) {
  19271         if (local_port == -1) {
  19272             rv = soc_phyctrl_loopback_set(unit, port, 1, TRUE);
  19273         } else {
  19274             rv = soc_phyctrl_redirect_loopback_set(unit, port, phyn,
  19275                                                    phy_lane, sys_side,
  19276                                                    1, TRUE);
  19277         }
  19278      }
  19279 
  19280     PORT_UNLOCK(unit);                  /* unlock before link call */
  19281 
  19282     if ((loopback == BCM_PORT_LOOPBACK_NONE) || !BCM_SUCCESS(rv)) {
  19283         _bcm_esw_link_force(unit, 0 /*flags*/, port, FALSE, DONT_CARE);
  19284         PORT_LOCK(unit);
  19285 #ifdef BCM_TRIDENT2_SUPPORT
  19286         /* When the PHY is TSC, need to unsquelch TX LANE. */
  19287         if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)
  19288             && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))){
  19289             enable = PORT(unit, port).enable;
  19290             if ((FALSE == enable) && (loopback == BCM_PORT_LOOPBACK_NONE)) {
  19291                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE);
  19292                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
  19293                 if (SOC_FAILURE(rv)) {
  19294                     PORT_UNLOCK(unit);
  19295                     return (rv);
  19296                 }
  19297                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
  19298             }
  19299         } else
  19300 #endif /* BCM_TRIDENT2_SUPPORT */
  19301         {
  19302             if ((FALSE == link) && (loopback == BCM_PORT_LOOPBACK_NONE)) {
  19303                 /* Disable MAC RX to prevent traffic going into this port */
  19304                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  19305                                 SOC_MAC_CONTROL_RX_SET, FALSE);
  19306                 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */
  19307 
  19308                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
  19309             }
  19310         }
  19311         PORT_UNLOCK(unit);
  19312     } else {
  19313         /* Enable only MAC instead of calling bcm_port_enable_set so
  19314          * that this API doesn't silently enable the port if the
  19315          * port is disabled by application.
  19316          */
  19317         rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE);
  19318 
  19319 #ifdef BCM_TRIDENT2_SUPPORT
  19320         /* When the PHY is TSC, need to enable the PHY to support MAC loopback
  19321          * on a disabled port. In order to avoid link flap of link partner,
  19322          * need to squelch TX LANE before enabling PHY.
  19323          */
  19324         if (BCM_FAILURE(rv)) {
  19325             return (rv);
  19326         }
  19327         if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit))
  19328             && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))
  19329             && (FALSE == link)
  19330             && (loopback == BCM_PORT_LOOPBACK_MAC)) {
  19331             PORT_LOCK(unit);
  19332             (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE);
  19333             rv = soc_phyctrl_enable_set(unit, port, TRUE);
  19334             PORT_UNLOCK(unit);
  19335             if (SOC_FAILURE(rv)) {
  19336                 return (rv);
  19337             }
  19338         }
  19339 #endif /* BCM_TRIDENT2_SUPPORT */
  19340 
  19341         if (BCM_SUCCESS(rv)) {
  19342             /* Make sure that the link status is updated only after the
  19343              * MAC is enabled so that link_mask2 is set before the
  19344              * calling thread synchronizes with linkscan thread in
  19345              * _bcm_link_force call.
  19346              * If the link is forced before MAC is enabled, there could
  19347              * be a race condition in _soc_link_update where linkscan
  19348              * may use an old view of link_mask2 and override the
  19349              * EPC_LINK_BMAP after the mac_enable_set updates
  19350              * link_mask2 and EPC_LINK_BMAP.
  19351              */
  19352             if (loopback == BCM_PORT_LOOPBACK_MAC) {
  19353                 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE);
  19354             } else {
  19355                 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, link);
  19356             }
  19357         }
  19358         if (BCM_FAILURE(rv)) {
  19359             return (rv);
  19360         }
  19361 
  19362 #if defined(BCM_BRADLEY_SUPPORT)
  19363         /*
  19364          * Call _bcm_port_mmu_update explicitly because linkscan
  19365          * will not call bcm_port_update when the link is forced.
  19366          */
  19367         if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) {
  19368             rv = _bcm_port_mmu_update(unit, port, 1);
  19369         }
  19370 
  19371         /* When a link comes up, hardware will not update the
  19372          * LINK_STATUS register until software has toggled the
  19373          * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field.
  19374          * Normally, this is done by bcm_port_update. But since
  19375          * linkscan will not call bcm_port_update when a link is
  19376          * forced up, the toggling of LAG_FAILOVER_CONFIG.LINK_STATUS_UP
  19377          * is done here.
  19378          */
  19379         if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) &&
  19380              IS_GX_PORT(unit, port)) ||
  19381             (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) ||
  19382             (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) &&
  19383               (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port))) ||
  19384             (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) &&
  19385               IS_CL_PORT(unit, port))) {
  19386             soc_reg_t reg;
  19387             uint32 rval;
  19388 
  19389             if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) {
  19390                 reg = XLPORT_LAG_FAILOVER_CONFIGr;
  19391             } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) {
  19392                 reg = LAG_FAILOVER_CONFIGr;
  19393             } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) {
  19394                 reg = GXPORT_LAG_FAILOVER_CONFIGr;
  19395             } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) &&
  19396                        (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) {
  19397                 reg = CLPORT_LAG_FAILOVER_CONFIGr;
  19398             } else {
  19399                 reg = XLPORT_LAG_FAILOVER_CONFIGr;
  19400             }
  19401 
  19402 #if defined(BCM_TOMAHAWK_SUPPORT)
  19403            if (SOC_IS_TOMAHAWK(unit)) {
  19404                phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  19405                if((phy_port == TH_MGMT_PORT0_NUM) ||
  19406                   (phy_port == TH_MGMT_PORT1_NUM)) {
  19407                    reg = XLPORT_LAG_FAILOVER_CONFIGr;
  19408                }
  19409                /* Link status to IPIPE is updated by H/W and driven based on both the
  19410                * rising edge of XLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and
  19411                * actual link up status from Serdes.
  19412                * In some loopback scenarios it may take longer time to see Serdes link up status.
  19413                */
  19414                soc_timeout_init(&to, 10000, 0);
  19415                do {
  19416                       if (((phy_port != TH_MGMT_PORT0_NUM) &&
  19417                            (phy_port != TH_MGMT_PORT1_NUM)) ||
  19418                            (loopback == BCM_PORT_LOOPBACK_NONE)) {
  19419                           break;
  19420                       }
  19421 
  19422                       switch(phy_port) {
  19423                           case TH_MGMT_PORT0_NUM:
  19424                               BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, port, 0, &rval));
  19425                               link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, rval, LINK_STATUSf);
  19426                               break;
  19427                           case TH_MGMT_PORT1_NUM:
  19428                               BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, port, 0, &rval));
  19429                               link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, rval, LINK_STATUSf);
  19430                               break;
  19431                       }
  19432                       if(link_st) {
  19433                           break;
  19434                       }
  19435                } while (!soc_timeout_check(&to));
  19436            }
  19437 #endif
  19438            /* Toggle link bit to notify IPIPE on link up */
  19439            BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  19440            soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1);
  19441            BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  19442            soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0);
  19443            BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  19444         }
  19445 #endif /* BCM_BRADLEY_SUPPORT */
  19446     }
  19447 
  19448     LOG_INFO(BSL_LS_BCM_PORT,
  19449              (BSL_META_U(unit,
  19450                          "bcm_port_loopback_set: u=%d p=%d lb=%d rv=%d\n"),
  19451               unit, port, loopback, rv));
  19452 
  19453     return rv;
  19454 }
  19455 
  19456 /*
  19457  * Function:
  19458  *      bcm_port_loopback_get
  19459  * Purpose:
  19460  *      Recover the current loopback operation for the specified port.
  19461  * Parameters:
  19462  *      unit - StrataSwitch Unit #.
  19463  *      port - StrataSwitch port #.
  19464  *      loopback - (OUT) one of:
  19465  *              BCM_PORT_LOOPBACK_NONE
  19466  *              BCM_PORT_LOOPBACK_MAC
  19467  *              BCM_PORT_LOOPBACK_PHY
  19468  * Returns:
  19469  *      BCM_E_NONE
  19470  *      BCM_E_XXX
  19471  */
  19472 
  19473 int
  19474 bcm_esw_port_loopback_get(int unit, bcm_port_t port, int *loopback)
  19475 {
  19476     int         rv = BCM_E_NONE;
  19477     int         phy_lb = 0;
  19478     uint32      phy_rlb = 0;
  19479     int         mac_lb = 0;
  19480     int         phy_lane = -1;
  19481     int         phyn = 0, sys_side = 0;
  19482     bcm_port_t  local_port = -1;
  19483 #if defined(BCM_KATANA2_SUPPORT)
  19484     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19485 #endif
  19486 
  19487     /* Make sure port module is initialized. */
  19488     PORT_INIT(unit);
  19489 
  19490     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19491         return bcmi_esw_portctrl_loopback_get(unit, port, loopback);
  19492     }
  19493 
  19494     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19495         LOG_ERROR(BSL_LS_BCM_PORT,
  19496                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19497                    port));
  19498         return BCM_E_PARAM;
  19499     }
  19500 
  19501 #if defined(BCM_KATANA2_SUPPORT)
  19502 #if defined(BCM_SABER2_SUPPORT)
  19503     if(SOC_IS_SABER2(unit)) {
  19504         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19505     }
  19506 #endif
  19507     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19508         (!((port >= 1) && (port <= max_phy_port)))) {
  19509          return BCM_E_PORT;
  19510     }
  19511 #endif
  19512 
  19513     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  19514                                                         &local_port, &phyn,
  19515                                                         &phy_lane, &sys_side));
  19516 
  19517     if (local_port == -1) {
  19518        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19519     } else {
  19520        port = local_port;
  19521     }
  19522     PORT_LOCK(unit);                    /* multiple operations operation */
  19523 
  19524     if (local_port == -1) {
  19525         /* Most ext-phys don't support remote loopback and return SOC_E_UNAVAIL.
  19526          * When the return value is SOC_E_UNAVAIL, continue to get phy or mac
  19527          * loopback mode
  19528          */
  19529         rv = soc_phyctrl_control_get(unit, port,
  19530                                      SOC_PHY_CONTROL_LOOPBACK_REMOTE,
  19531                                      &phy_rlb);
  19532         if (rv >= 0 || rv == SOC_E_UNAVAIL) {
  19533             rv = soc_phyctrl_loopback_get(unit, port, &phy_lb);
  19534         }
  19535     } else {
  19536         rv = soc_phyctrl_redirect_loopback_get(unit, port, phyn,
  19537                                                phy_lane, sys_side,
  19538                                                &phy_lb);
  19539     }
  19540 
  19541         rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  19542 
  19543     PORT_UNLOCK(unit);
  19544     if (rv >= 0) {
  19545         if (mac_lb) {
  19546             *loopback = BCM_PORT_LOOPBACK_MAC;
  19547         } else if (phy_lb) {
  19548             *loopback = BCM_PORT_LOOPBACK_PHY;
  19549         } else if (phy_rlb) {
  19550             *loopback = BCM_PORT_LOOPBACK_PHY_REMOTE;
  19551         } else {
  19552             *loopback = BCM_PORT_LOOPBACK_NONE;
  19553         }
  19554     } else {
  19555         *loopback = BCM_PORT_LOOPBACK_NONE;
  19556     }
  19557 
  19558     LOG_INFO(BSL_LS_BCM_PORT,
  19559              (BSL_META_U(unit,
  19560                          "bcm_port_loopback_get: u=%d p=%d lb=%d rv=%d\n"),
  19561               unit, port, *loopback, rv));
  19562 
  19563     return rv;
  19564 }
  19565 
  19566 /*
  19567  * Function:
  19568  *      bcm_port_duplex_get
  19569  * Purpose:
  19570  *      Get the port duplex settings
  19571  * Parameters:
  19572  *      unit - StrataSwitch Unit #.
  19573  *      port - StrataSwitch port #.
  19574  *      duplex - (OUT) Duplex setting, one of SOC_PORT_DUPLEX_xxx
  19575  * Returns:
  19576  *      BCM_E_NONE
  19577  *      BCM_E_XXX
  19578  */
  19579 
  19580 int
  19581 bcm_esw_port_duplex_get(int unit, bcm_port_t port, int *duplex)
  19582 {
  19583     int         phy_duplex;
  19584     int         rv=BCM_E_NONE;
  19585 #if defined(BCM_KATANA2_SUPPORT)
  19586     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19587 #endif
  19588 
  19589     /* Make sure port module is initialized. */
  19590     PORT_INIT(unit);
  19591 
  19592     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19593         return bcmi_esw_portctrl_duplex_get(unit, port, duplex);
  19594     }
  19595 
  19596     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19597         LOG_ERROR(BSL_LS_BCM_PORT,
  19598                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19599                    port));
  19600         return BCM_E_PARAM;
  19601     }
  19602 
  19603 #if defined(BCM_KATANA2_SUPPORT)
  19604 #if defined(BCM_SABER2_SUPPORT)
  19605     if(SOC_IS_SABER2(unit)) {
  19606         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19607     }
  19608 #endif
  19609     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19610         (!((port >= 1) && (port <= max_phy_port)))) {
  19611          return BCM_E_PORT;
  19612     }
  19613 #endif
  19614     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19615     PORT_LOCK(unit);
  19616     rv = soc_phyctrl_duplex_get(unit, port, &phy_duplex);
  19617     PORT_UNLOCK(unit);
  19618 
  19619     if (BCM_SUCCESS(rv)) {
  19620         *duplex = phy_duplex ? SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF;
  19621     } else {
  19622         *duplex = SOC_PORT_DUPLEX_FULL;
  19623     }
  19624 
  19625     LOG_INFO(BSL_LS_BCM_PORT,
  19626              (BSL_META_U(unit,
  19627                          "bcm_port_duplex_get: u=%d p=%d dup=%d rv=%d\n"),
  19628               unit, port, *duplex, rv));
  19629 
  19630     return rv;
  19631 }
  19632 
  19633 /*
  19634  * Function:
  19635  *      _bcm_port_duplex_ability_check
  19636  * Purpose:
  19637  *      Check the port duplex ability.
  19638  * Parameters:
  19639  *      unit - StrataSwitch Unit #.
  19640  *      port - StrataSwitch port #.
  19641  *      duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx
  19642  * Returns:
  19643  *      BCM_E_NONE
  19644  *      BCM_E_XXX
  19645  */
  19646 STATIC int
  19647 _bcm_esw_port_duplex_ability_check(int unit, bcm_port_t port, int duplex)
  19648 {
  19649     bcm_port_ability_t ability_mask;
  19650     int         rv;
  19651     int         mac_lb;
  19652     int         speed = 0, full_duplex_speed, half_duplex_speed;
  19653     uint32      pa_speed = 0;
  19654     sal_memset(&ability_mask, 0, sizeof(bcm_port_ability_t));
  19655     rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  19656     if (BCM_SUCCESS(rv)) {
  19657         /* If the port is in mac loopback, we get mac_ability rather than port_ability. */
  19658         if(mac_lb) {
  19659            rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,port, &ability_mask);
  19660         } else {
  19661            rv = bcm_esw_port_ability_local_get(unit, port, &ability_mask);
  19662         }
  19663         if (rv < 0) {
  19664             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19665                         (BSL_META("Error: Could not get port %d ability: %s\n"),
  19666                          port, bcm_errmsg(rv)));
  19667             return rv;
  19668         }
  19669         if ((rv = bcm_esw_port_speed_get(unit, port, &speed)) < 0) {
  19670             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19671                         (BSL_META("Error: Could not get port %d speed: %s\n"),
  19672                          port, bcm_errmsg(rv)));
  19673             return rv;
  19674         }
  19675         pa_speed = SOC_PA_SPEED(speed);
  19676         full_duplex_speed = ability_mask.speed_full_duplex & pa_speed;
  19677         half_duplex_speed = ability_mask.speed_half_duplex & pa_speed;
  19678         if (!soc_feature(unit, soc_feature_flexport_based_speed_set) && (speed != 0)) {
  19679             if (duplex) {
  19680                 if (!full_duplex_speed) {
  19681                     LOG_WARN(BSL_LS_BCM_PORT,
  19682                              (BSL_META_U(unit, "Warning: port %d does not support %d mbps full duplex\n"),
  19683                               port, speed));
  19684                     return BCM_E_UNAVAIL;
  19685                 }
  19686             } else {
  19687                 if (!half_duplex_speed) {
  19688                     LOG_WARN(BSL_LS_BCM_PORT,
  19689                              (BSL_META_U(unit, "Warning: port %d does not support %d mbps half duplex\n"),
  19690                               port, speed));
  19691                     return BCM_E_UNAVAIL;
  19692                 }
  19693             }
  19694         }
  19695     }
  19696     return BCM_E_NONE;
  19697 }
  19698 
  19699 /*
  19700  * Function:
  19701  *      bcm_port_duplex_set
  19702  * Purpose:
  19703  *      Set the port duplex settings.
  19704  * Parameters:
  19705  *      unit - StrataSwitch Unit #.
  19706  *      port - StrataSwitch port #.
  19707  *      duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx
  19708  * Returns:
  19709  *      BCM_E_NONE
  19710  *      BCM_E_XXX
  19711  * Notes:
  19712  *      Turns off autonegotiation.  Caller must make sure other forced
  19713  *      parameters (such as speed) are set.
  19714  */
  19715 
  19716 int
  19717 bcm_esw_port_duplex_set(int unit, bcm_port_t port, int duplex)
  19718 {
  19719     int         rv;
  19720     pbmp_t      pbm;
  19721     int         an = 0 ;
  19722     int         an_done=0;
  19723 #if defined(BCM_SABER2_SUPPORT)
  19724     int             phy_status;
  19725 #endif
  19726 #if defined(BCM_KATANA2_SUPPORT)
  19727     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19728 #endif
  19729 
  19730     /* Make sure port module is initialized. */
  19731     PORT_INIT(unit);
  19732 
  19733     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19734         return bcmi_esw_portctrl_duplex_set(unit, port, duplex);
  19735     }
  19736 
  19737     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19738         LOG_ERROR(BSL_LS_BCM_PORT,
  19739                   (BSL_META("Error: Cannot set duplex mode on OAMP Port %d.\n"),
  19740                    port));
  19741         return BCM_E_PARAM;
  19742     }
  19743 
  19744 #if defined(BCM_KATANA2_SUPPORT)
  19745 #if defined(BCM_SABER2_SUPPORT)
  19746     if(SOC_IS_SABER2(unit)) {
  19747         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19748     }
  19749 #endif
  19750     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19751         (!((port >= 1) && (port <= max_phy_port)))) {
  19752          return BCM_E_PORT;
  19753     } else
  19754 #endif
  19755      if((!BCM_GPORT_IS_SET(port)) && (!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)))) {
  19756         return BCM_E_PORT;
  19757      }
  19758     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19759 
  19760 #ifdef BCM_RCPU_SUPPORT
  19761     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  19762         return BCM_E_PORT;
  19763     }
  19764 #endif /* BCM_RCPU_SUPPORT */
  19765 
  19766 #if defined(BCM_TOMAHAWK_SUPPORT)
  19767     if (SOC_IS_TOMAHAWK(unit)) {
  19768         /*half-duplex is not supported at any speed Eagle & Falcon */
  19769         if (duplex == 0) {
  19770             return BCM_E_UNAVAIL;
  19771         }
  19772     }
  19773 #endif
  19774 
  19775     /* in SIMULATION, port's alility_mask may not be correct due to NULL phy */
  19776     if (!SAL_BOOT_SIMULATION) {
  19777         BCM_IF_ERROR_RETURN(_bcm_esw_port_duplex_ability_check(unit, port, duplex));
  19778     }
  19779 
  19780     PORT_LOCK(unit);
  19781 
  19782 #if defined(BCM_SABER2_SUPPORT)
  19783     if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  19784         rv = soc_phyctrl_enable_get(unit, port, &phy_status);
  19785         if (BCM_FAILURE(rv)) {
  19786             PORT_UNLOCK(unit);
  19787             return (rv);
  19788         }
  19789         if(phy_status == TRUE) {
  19790             rv = soc_phyctrl_enable_set(unit, port, FALSE);
  19791             if (BCM_FAILURE(rv)) {
  19792                 PORT_UNLOCK(unit);
  19793                 return (rv);
  19794             }
  19795         }
  19796     }
  19797 #endif
  19798     rv = soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done);
  19799     if (BCM_FAILURE(rv)) {
  19800         LOG_VERBOSE(BSL_LS_BCM_PORT,
  19801                     (BSL_META_U(unit,
  19802                                 "PHY_AUTONEG_GETfailed:%s\n"), bcm_errmsg(rv)));
  19803     }
  19804     if(an != FALSE)
  19805     {
  19806         rv = soc_phyctrl_auto_negotiate_set(unit, port, FALSE);
  19807         if (BCM_FAILURE(rv)) {
  19808             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19809                         (BSL_META_U(unit,
  19810                                     "PHY_AUTONEG_SETfailed:%s\n"), bcm_errmsg(rv)));
  19811         }
  19812     }
  19813 
  19814 #if defined(BCM_SABER2_SUPPORT)
  19815     if(SOC_IS_SABER2(unit) &&
  19816             IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  19817         /* Enable phy in tsc only if already enabled before config change */
  19818         rv = soc_phyctrl_enable_set(unit, port, TRUE);
  19819         if (BCM_FAILURE(rv)) {
  19820             PORT_UNLOCK(unit);
  19821             return (rv);
  19822         }
  19823     }
  19824 #endif
  19825 
  19826     if (BCM_SUCCESS(rv)) {
  19827         rv = soc_phyctrl_duplex_set(unit, port, duplex);
  19828         if (BCM_FAILURE(rv)) {
  19829             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19830                         (BSL_META_U(unit,
  19831                                     "PHY_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv)));
  19832         }
  19833     }
  19834 
  19835     if (BCM_SUCCESS(rv)) {
  19836         rv = MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex);
  19837         if (BCM_FAILURE(rv)) {
  19838             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19839                         (BSL_META_U(unit,
  19840                                     "MAC_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv)));
  19841         }
  19842     }
  19843 #if defined(BCM_XMAC_SUPPORT)
  19844     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  19845        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  19846        uint32 vco_disturbed = 0;
  19847        phy_ctrl_t *int_pc;
  19848         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  19849                     IS_XE_PORT(unit, port))) {
  19850 
  19851             int_pc = INT_PHY_SW_STATE(unit, port);
  19852             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  19853             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  19854                 PORT_UNLOCK(unit);
  19855                 return rv;
  19856             }
  19857             if (vco_disturbed) {
  19858                 rv = _mac_x_reinit(unit, port);
  19859                 if (BCM_FAILURE(rv)) {
  19860                     PORT_UNLOCK(unit);
  19861                     return rv;
  19862                 }
  19863             }
  19864         }
  19865     }
  19866 #endif
  19867 
  19868     PORT_UNLOCK(unit);                  /* Unlock before link call */
  19869 
  19870     if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  19871         SOC_PBMP_CLEAR(pbm);
  19872         SOC_PBMP_PORT_ADD(pbm, port);
  19873         (void)bcm_esw_link_change(unit, pbm);
  19874     }
  19875 
  19876     LOG_INFO(BSL_LS_BCM_PORT,
  19877              (BSL_META_U(unit,
  19878                          "bcm_port_duplex_set: u=%d p=%d dup=%d rv=%d\n"),
  19879               unit, port, duplex, rv));
  19880 
  19881     return rv;
  19882 }
  19883 
  19884 /*
  19885  * Function:
  19886  *      bcm_port_pause_get
  19887  * Purpose:
  19888  *      Get the source address for transmitted PAUSE frames.
  19889  * Parameters:
  19890  *      unit - StrataSwitch Unit #.
  19891  *      port - StrataSwitch port #.
  19892  *      pause_tx - (OUT) Boolean value
  19893  *      pause_rx - (OUT) Boolean value
  19894  * Returns:
  19895  *      BCM_E_NONE
  19896  *      BCM_E_XXX
  19897  */
  19898 
  19899 int
  19900 bcm_esw_port_pause_get(int unit, bcm_port_t port, int *pause_tx, int *pause_rx)
  19901 {
  19902     int         rv;
  19903 #if defined(BCM_KATANA2_SUPPORT)
  19904     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19905 #endif
  19906 
  19907     /* Make sure port module is initialized. */
  19908     PORT_INIT(unit);
  19909 
  19910     /* Call Port Control module */
  19911     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19912         return bcmi_esw_portctrl_pause_get(unit, port, pause_tx, pause_rx);
  19913     }
  19914 
  19915     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19916         LOG_ERROR(BSL_LS_BCM_PORT,
  19917                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19918                    port));
  19919         return BCM_E_PARAM;
  19920     }
  19921 
  19922 #if defined(BCM_KATANA2_SUPPORT)
  19923 #if defined(BCM_SABER2_SUPPORT)
  19924     if(SOC_IS_SABER2(unit)) {
  19925         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19926     }
  19927 #endif
  19928     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19929         (!((port >= 1) && (port <= max_phy_port)))) {
  19930          return BCM_E_PORT;
  19931     }
  19932 #endif
  19933 
  19934     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19935 
  19936     PORT_LOCK(unit);
  19937     rv = MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx);
  19938     PORT_UNLOCK(unit);
  19939 
  19940     return rv;
  19941 }
  19942 
  19943 /*
  19944  * Function:
  19945  *      bcm_port_pause_set
  19946  * Purpose:
  19947  *      Set the pause state for a given port
  19948  * Parameters:
  19949  *      unit - StrataSwitch Unit #.
  19950  *      port - StrataSwitch port #.
  19951  *      pause_tx - Boolean value, or -1 (don't change)
  19952  *      pause_rx - Boolean value, or -1 (don't change)
  19953  * Returns:
  19954  *      BCM_E_NONE
  19955  *      BCM_E_XXX
  19956  * Notes:
  19957  *      Symmetric pause requires the two "pause" values to be the same.
  19958  */
  19959 
  19960 int
  19961 bcm_esw_port_pause_set(int unit, bcm_port_t port, int pause_tx, int pause_rx)
  19962 {
  19963     int         rv;
  19964 #ifdef BCM_MONTEREY_SUPPORT
  19965     uint32      enable = 0;
  19966 #endif
  19967 #if defined(BCM_KATANA2_SUPPORT)
  19968     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19969 #endif
  19970 
  19971     /* Make sure port module is initialized. */
  19972     PORT_INIT(unit);
  19973 
  19974     /* Call Port Control module */
  19975     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  19976 #ifdef BCM_MONTEREY_SUPPORT
  19977         if (SOC_IS_MONTEREY(unit)) {
  19978             BCM_IF_ERROR_RETURN(
  19979                 bcmi_esw_portctrl_preemption_mac_config_get(
  19980                 unit, port, bcmPortPreemptControlEnableTx, &enable));
  19981             if (enable && (pause_tx || pause_rx)) {
  19982                 return BCM_E_PARAM;
  19983             }
  19984         }
  19985 #endif
  19986         return bcmi_esw_portctrl_pause_set(unit, port, pause_tx, pause_rx);
  19987     }
  19988 
  19989     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19990         LOG_ERROR(BSL_LS_BCM_PORT,
  19991                   (BSL_META("Error: Cannot set pause state on OAMP Port %d.\n"),
  19992                    port));
  19993         return BCM_E_PARAM;
  19994     }
  19995 
  19996 #if defined(BCM_KATANA2_SUPPORT)
  19997 #if defined(BCM_SABER2_SUPPORT)
  19998     if(SOC_IS_SABER2(unit)) {
  19999         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20000     }
  20001 #endif
  20002     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20003         (!((port >= 1) && (port <= max_phy_port)))) {
  20004          return BCM_E_PORT;
  20005     }
  20006 #endif
  20007 
  20008     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20009 
  20010     PORT_LOCK(unit);
  20011     rv = MAC_PAUSE_SET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx);
  20012     if (BCM_FAILURE(rv)) {
  20013         PORT_UNLOCK(unit);
  20014         return (rv);
  20015     }
  20016 
  20017 #if defined(BCM_BRADLEY_SUPPORT)
  20018     if (SOC_IS_HBX(unit)) {
  20019 #ifdef BCM_SHADOW_SUPPORT
  20020     if (!SOC_IS_SHADOW(unit)) {
  20021 #endif
  20022         rv = _bcm_port_mmu_update(unit, port, -1);
  20023 #ifdef BCM_SHADOW_SUPPORT
  20024     }
  20025 #endif
  20026     }
  20027 #endif /* BCM_BRADLEY_SUPPORT */
  20028 
  20029     PORT_UNLOCK(unit);
  20030     return rv;
  20031 }
  20032 
  20033 /*
  20034  * Function:
  20035  *      bcm_port_pause_sym_get
  20036  * Purpose:
  20037  *      Get the current pause setting for pause
  20038  * Parameters:
  20039  *      unit - StrataSwitch Unit #.
  20040  *      port - StrataSwitch port #.
  20041  *      pause - (OUT) returns a bcm_port_pause_e enum value
  20042  * Returns:
  20043  *      BCM_E_NONE
  20044  *      BCM_E_XXX
  20045  */
  20046 
  20047 int
  20048 bcm_esw_port_pause_sym_get(int unit, bcm_port_t port, int *pause)
  20049 {
  20050     int         pause_rx, pause_tx;
  20051 #if defined(BCM_KATANA2_SUPPORT)
  20052     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20053 #endif
  20054 
  20055 #if defined(BCM_KATANA2_SUPPORT)
  20056 #if defined(BCM_SABER2_SUPPORT)
  20057     if(SOC_IS_SABER2(unit)) {
  20058         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20059     }
  20060 #endif
  20061     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20062         (!((port >= 1) && (port <= max_phy_port)))) {
  20063          return BCM_E_PORT;
  20064     }
  20065 #endif
  20066 
  20067     /* Make sure port module is initialized. */
  20068     PORT_INIT(unit);
  20069 
  20070     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20071         LOG_ERROR(BSL_LS_BCM_PORT,
  20072                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20073                    port));
  20074         return BCM_E_PARAM;
  20075     }
  20076 
  20077     BCM_IF_ERROR_RETURN
  20078         (bcm_esw_port_pause_get(unit, port, &pause_tx, &pause_rx));
  20079     if (pause_tx) {
  20080         if (pause_rx) {
  20081             *pause = BCM_PORT_PAUSE_SYM;
  20082         } else {
  20083             *pause = BCM_PORT_PAUSE_ASYM_TX;
  20084         }
  20085     } else if (pause_rx) {
  20086         *pause = BCM_PORT_PAUSE_ASYM_RX;
  20087     } else {
  20088         *pause = BCM_PORT_PAUSE_NONE;
  20089     }
  20090 
  20091     return BCM_E_NONE;
  20092 }
  20093 
  20094 /*
  20095  * Function:
  20096  *      bcm_port_pause_sym_set
  20097  * Purpose:
  20098  *      Set the pause values for the port using single integer
  20099  * Parameters:
  20100  *      unit - StrataSwitch Unit #.
  20101  *      port - StrataSwitch port #.
  20102  *      pause - a bcm_port_pause_e enum value
  20103  * Returns:
  20104  *      BCM_E_NONE
  20105  *      BCM_E_XXX
  20106  */
  20107 
  20108 int
  20109 bcm_esw_port_pause_sym_set(int unit, bcm_port_t port, int pause)
  20110 {
  20111     int         pause_rx, pause_tx;
  20112 #if defined(BCM_KATANA2_SUPPORT)
  20113     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20114 #endif
  20115 
  20116 #if defined(BCM_KATANA2_SUPPORT)
  20117 #if defined(BCM_SABER2_SUPPORT)
  20118     if(SOC_IS_SABER2(unit)) {
  20119         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20120     }
  20121 #endif
  20122     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20123         (!((port >= 1) && (port <= max_phy_port)))) {
  20124          return BCM_E_PORT;
  20125     }
  20126 #endif
  20127     /* Make sure port module is initialized. */
  20128     PORT_INIT(unit);
  20129 
  20130     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20131         LOG_ERROR(BSL_LS_BCM_PORT,
  20132                   (BSL_META("Error: Cannot set pause values on OAMP Port %d.\n"),
  20133                    port));
  20134         return BCM_E_PARAM;
  20135     }
  20136 
  20137     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20138 
  20139     pause_tx = pause_rx = 0;
  20140 
  20141     switch (pause) {
  20142     case BCM_PORT_PAUSE_SYM:
  20143         pause_tx = pause_rx = 1;
  20144         break;
  20145     case BCM_PORT_PAUSE_ASYM_RX:
  20146         pause_rx = 1;
  20147         break;
  20148     case BCM_PORT_PAUSE_ASYM_TX:
  20149         pause_tx = 1;
  20150         break;
  20151     case BCM_PORT_PAUSE_NONE:
  20152         break;
  20153     default:
  20154         return BCM_E_PARAM;
  20155     }
  20156 
  20157     return bcm_esw_port_pause_set(unit, port, pause_tx, pause_rx);
  20158 }
  20159 
  20160 /*
  20161  * Function:
  20162  *      bcm_port_pause_addr_get
  20163  * Purpose:
  20164  *      Get the source address for transmitted PAUSE frames.
  20165  * Parameters:
  20166  *      unit - StrataSwitch Unit #.
  20167  *      port - StrataSwitch port #.
  20168  *      mac - (OUT) MAC address sent with pause frames.
  20169  * Returns:
  20170  *      BCM_E_NONE
  20171  *      BCM_E_XXX
  20172  */
  20173 
  20174 int
  20175 bcm_esw_port_pause_addr_get(int unit, bcm_port_t port, bcm_mac_t mac)
  20176 {
  20177     int         rv;
  20178 #if defined(BCM_KATANA2_SUPPORT)
  20179     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20180 #endif
  20181 
  20182     /* Make sure port module is initialized. */
  20183     PORT_INIT(unit);
  20184 
  20185     /* Call Port Control module */
  20186     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20187         return bcmi_esw_portctrl_pause_addr_get(unit, port, mac);
  20188     }
  20189 
  20190     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20191         LOG_ERROR(BSL_LS_BCM_PORT,
  20192                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20193                    port));
  20194         return BCM_E_PARAM;
  20195     }
  20196 
  20197 #if defined(BCM_KATANA2_SUPPORT)
  20198 #if defined(BCM_SABER2_SUPPORT)
  20199     if(SOC_IS_SABER2(unit)) {
  20200         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20201     }
  20202 #endif
  20203     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20204         (!((port >= 1) && (port <= max_phy_port)))) {
  20205          return BCM_E_PORT;
  20206     }
  20207 #endif
  20208 
  20209     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20210 
  20211     PORT_LOCK(unit);
  20212     rv = MAC_PAUSE_ADDR_GET(PORT(unit, port).p_mac, unit, port, mac);
  20213     PORT_UNLOCK(unit);
  20214 
  20215     return rv;
  20216 }
  20217 
  20218 /*
  20219  * Function:
  20220  *      bcm_port_pause_addr_set
  20221  * Purpose:
  20222  *      Set the source address for transmitted PAUSE frames.
  20223  * Parameters:
  20224  *      unit - StrataSwitch Unit #.
  20225  *      port - StrataSwitch port #.
  20226  *      mac - station address used for pause frames.
  20227  * Returns:
  20228  *      BCM_E_NONE
  20229  *      BCM_E_XXX
  20230  * Notes:
  20231  *      Symmetric pause requires the two "pause" values to be the same.
  20232  */
  20233 
  20234 int
  20235 bcm_esw_port_pause_addr_set(int unit, bcm_port_t port, bcm_mac_t mac)
  20236 {
  20237     int         rv;
  20238 #if defined(BCM_KATANA2_SUPPORT)
  20239     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20240 #endif
  20241 
  20242     /* Make sure port module is initialized. */
  20243     PORT_INIT(unit);
  20244 
  20245     /* Call Port Control module */
  20246     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20247         return bcmi_esw_portctrl_pause_addr_set(unit, port, mac);
  20248     }
  20249 
  20250     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20251         LOG_ERROR(BSL_LS_BCM_PORT,
  20252                   (BSL_META("Error: Cannot set pause addr on OAMP Port %d.\n"),
  20253                    port));
  20254         return BCM_E_PARAM;
  20255     }
  20256 
  20257 #if defined(BCM_KATANA2_SUPPORT)
  20258 #if defined(BCM_SABER2_SUPPORT)
  20259     if(SOC_IS_SABER2(unit)) {
  20260         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20261     }
  20262 #endif
  20263     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20264         (!((port >= 1) && (port <= max_phy_port)))) {
  20265          return BCM_E_PORT;
  20266     }
  20267 #endif
  20268 
  20269     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20270 
  20271     PORT_LOCK(unit);
  20272     rv = MAC_PAUSE_ADDR_SET(PORT(unit, port).p_mac, unit, port, mac);
  20273     PORT_UNLOCK(unit);
  20274 
  20275     return rv;
  20276 }
  20277 
  20278 /*
  20279  * Function:
  20280  *      bcm_port_advert_get
  20281  * Purpose:
  20282  *      Retrieve the local port advertisement for autonegotiation.
  20283  * Parameters:
  20284  *      unit - StrataSwitch Unit #.
  20285  *      port - StrataSwitch port #.
  20286  *      ability_mask - (OUT) Local advertisement.
  20287  * Returns:
  20288  *      BCM_E_NONE
  20289  *      BCM_E_XXX
  20290  */
  20291 
  20292 int
  20293 bcm_esw_port_advert_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask)
  20294 {
  20295     int                 rv;
  20296     bcm_port_ability_t  ability;
  20297 #if defined(BCM_KATANA2_SUPPORT)
  20298     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20299 #endif
  20300 
  20301     /* Make sure port module is initialized. */
  20302     PORT_INIT(unit);
  20303 
  20304     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20305         return bcmi_esw_portctrl_ability_advert_get(unit, port,
  20306                                                     &ability, ability_mask);
  20307     }
  20308     sal_memset(&ability, 0, sizeof(bcm_port_ability_t));
  20309 
  20310 #if defined(BCM_KATANA2_SUPPORT)
  20311 #if defined(BCM_SABER2_SUPPORT)
  20312     if(SOC_IS_SABER2(unit)) {
  20313         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20314     }
  20315 #endif
  20316     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20317         (!((port >= 1) && (port <= max_phy_port)))) {
  20318          return BCM_E_PORT;
  20319     }
  20320 #endif
  20321     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20322 
  20323     PORT_LOCK(unit);
  20324     rv = soc_phyctrl_ability_advert_get(unit, port, &ability);
  20325     if (BCM_SUCCESS(rv)) {
  20326         rv = soc_port_ability_to_mode(&ability, ability_mask);
  20327     }
  20328     PORT_UNLOCK(unit);
  20329 
  20330 
  20331 
  20332     LOG_INFO(BSL_LS_BCM_PORT,
  20333              (BSL_META_U(unit,
  20334                          "bcm_port_advert_get: u=%d p=%d abil=0x%x rv=%d\n"),
  20335               unit, port, *ability_mask, rv));
  20336 
  20337     return rv;
  20338 }
  20339 
  20340 /*
  20341  * Function:
  20342  *      bcm_esw_port_ability_advert_get
  20343  * Purpose:
  20344  *      Retrieve the local port advertisement for autonegotiation.
  20345  * Parameters:
  20346  *      unit - StrataSwitch Unit #.
  20347  *      port - StrataSwitch port #.
  20348  *      ability_mask - (OUT) Local advertisement.
  20349  * Returns:
  20350  *      BCM_E_NONE
  20351  *      BCM_E_XXX
  20352  */
  20353 
  20354 int
  20355 bcm_esw_port_ability_advert_get(int unit, bcm_port_t port,
  20356                                 bcm_port_ability_t *ability_mask)
  20357 {
  20358     int         rv=BCM_E_NONE;
  20359 #if defined(BCM_KATANA2_SUPPORT)
  20360     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20361 #endif
  20362 
  20363     /* Make sure port module is initialized. */
  20364     PORT_INIT(unit);
  20365 
  20366     /* Call Port Control module */
  20367     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20368         return bcmi_esw_portctrl_ability_advert_get(unit, port,
  20369                                                     ability_mask, NULL);
  20370     }
  20371 
  20372     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20373         LOG_ERROR(BSL_LS_BCM_PORT,
  20374                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20375                    port));
  20376         return BCM_E_PARAM;
  20377     }
  20378 
  20379 #if defined(BCM_KATANA2_SUPPORT)
  20380 #if defined(BCM_SABER2_SUPPORT)
  20381     if(SOC_IS_SABER2(unit)) {
  20382         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20383     }
  20384 #endif
  20385     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20386         (!((port >= 1) && (port <= max_phy_port)))) {
  20387          return BCM_E_PORT;
  20388     }
  20389 #endif
  20390 
  20391     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20392 
  20393     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  20394         return BCM_E_PORT;
  20395     }
  20396 
  20397     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  20398     PORT_LOCK(unit);
  20399     rv = soc_phyctrl_ability_advert_get(unit, port, ability_mask);
  20400     PORT_UNLOCK(unit);
  20401 
  20402     LOG_INFO(BSL_LS_BCM_PORT,
  20403              (BSL_META_U(unit,
  20404                          "bcm_esw_port_ability_advert_get: u=%d p=%d rv=%d\n"),
  20405               unit, port, rv));
  20406 
  20407     return rv;
  20408 }
  20409 /*
  20410  * Function:
  20411  *      bcm_port_autoneg_ability_advert_get
  20412  * Purpose:
  20413  *      Retrieve the local port abilities.
  20414  * Parameters:
  20415  *      unit - StrataSwitch Unit #.
  20416  *      port - StrataSwitch port #.
  20417  *      max_num_ability  -- the max num of autoneg ability this port can advertise
  20418  *      ability - (OUT) values indicating the ability this port advertise
  20419  *      actual_num_ability - (OUT) the actual num of ability that this port advertise
  20420  * Returns:
  20421  *      BCM_E_NONE
  20422  *      BCM_E_XXX
  20423  */
  20424 int
  20425 bcm_esw_port_autoneg_ability_advert_get(int unit,
  20426                                      bcm_port_t port,
  20427                                      int max_num_ability,
  20428                                      bcm_port_speed_ability_t *abilities,
  20429                                      int *actual_num_ability)
  20430 {
  20431     int rv = BCM_E_UNAVAIL;
  20432 
  20433     /* Make sure port module is initialized. */
  20434     PORT_INIT(unit);
  20435 
  20436     /* Call Port Control module */
  20437     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20438         rv = bcmi_esw_portctrl_autoneg_ability_advert_get(unit, port, max_num_ability,
  20439                                                           abilities, actual_num_ability);
  20440     }
  20441 
  20442     return rv;
  20443 }
  20444 
  20445 
  20446 /*
  20447  * Function:
  20448  *      bcm_port_advert_set
  20449  * Purpose:
  20450  *      Set the local port advertisement for autonegotiation.
  20451  * Parameters:
  20452  *      unit - StrataSwitch Unit #.
  20453  *      port - StrataSwitch port #.
  20454  *      ability_mask - Local advertisement.
  20455  * Returns:
  20456  *      BCM_E_NONE
  20457  *      BCM_E_XXX
  20458  * Notes:
  20459  *      This call MAY NOT restart autonegotiation (depending on the phy).
  20460  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  20461  */
  20462 
  20463 int
  20464 bcm_esw_port_advert_set(int unit, bcm_port_t port, bcm_port_abil_t ability_mask)
  20465 {
  20466     int                 rv;
  20467     bcm_port_ability_t  given_ability, port_ability, temp_ability;
  20468 #if defined(BCM_KATANA2_SUPPORT)
  20469     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20470 #endif
  20471 
  20472     /* Make sure port module is initialized. */
  20473     PORT_INIT(unit);
  20474 
  20475     /* Call Port Control module */
  20476     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20477         return bcmi_esw_portctrl_ability_advert_set(unit, port,
  20478                                                     NULL, ability_mask);
  20479     }
  20480 
  20481     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20482         LOG_ERROR(BSL_LS_BCM_PORT,
  20483                   (BSL_META("Error: Cannot set port advert on OAMP Port %d.\n"),
  20484                    port));
  20485         return BCM_E_PARAM;
  20486     }
  20487 
  20488 #if defined(BCM_KATANA2_SUPPORT)
  20489 #if defined(BCM_SABER2_SUPPORT)
  20490     if(SOC_IS_SABER2(unit)) {
  20491         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20492     }
  20493 #endif
  20494     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20495         (!((port >= 1) && (port <= max_phy_port)))) {
  20496          return BCM_E_PORT;
  20497     }
  20498 #endif
  20499 
  20500     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20501 
  20502     BCM_IF_ERROR_RETURN
  20503         (bcm_esw_port_ability_local_get(unit, port, &port_ability));
  20504 
  20505     BCM_IF_ERROR_RETURN
  20506         (bcm_esw_port_ability_advert_get(unit, port, &given_ability));
  20507 
  20508     BCM_IF_ERROR_RETURN(
  20509         soc_port_mode_to_ability(ability_mask, &given_ability));
  20510 
  20511     /* temporary store ability of half duplex */
  20512     temp_ability.speed_half_duplex = given_ability.speed_half_duplex;
  20513     /* make sure that the ability advertising in PHY is supported by MAC */
  20514     soc_port_ability_mask(&given_ability, &port_ability);
  20515     /* restore half duplex ability */
  20516     given_ability.speed_half_duplex = temp_ability.speed_half_duplex;
  20517 
  20518     if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) {
  20519         if (SOC_INFO(unit).port_speed_max[port] < 16000) {
  20520             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_16GB);
  20521             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_16GB);
  20522         }
  20523 
  20524         if (SOC_INFO(unit).port_speed_max[port] < 13000) {
  20525             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_13GB);
  20526             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_13GB);
  20527         }
  20528 
  20529         if (SOC_INFO(unit).port_speed_max[port] < 12000) {
  20530             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_12GB);
  20531             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_12GB);
  20532         }
  20533 
  20534         if (IS_HL_PORT(unit, port)) {
  20535             if (!(given_ability.speed_full_duplex & BCM_PORT_ABILITY_2500MB)) {
  20536                 return BCM_E_CONFIG;
  20537             }
  20538         } else if (!(given_ability.speed_full_duplex & (BCM_PORT_ABILITY_16GB |
  20539               BCM_PORT_ABILITY_13GB | BCM_PORT_ABILITY_12GB |
  20540               BCM_PORT_ABILITY_10GB))) {
  20541             return BCM_E_CONFIG;
  20542         }
  20543     }
  20544 
  20545     PORT_LOCK(unit);
  20546     rv = soc_phyctrl_ability_advert_set(unit, port, &given_ability);
  20547     PORT_UNLOCK(unit);
  20548 
  20549     LOG_INFO(BSL_LS_BCM_PORT,
  20550              (BSL_META_U(unit,
  20551                          "bcm_port_advert_set: u=%d p=%d abil=0x%x rv=%d\n"),
  20552               unit, port, ability_mask, rv));
  20553 
  20554     return rv;
  20555 }
  20556 
  20557 /*
  20558  * Function:
  20559  *      bcm_port_ability_advert_set
  20560  * Purpose:
  20561  *      Set the local port advertisement for autonegotiation.
  20562  * Parameters:
  20563  *      unit - StrataSwitch Unit #.
  20564  *      port - StrataSwitch port #.
  20565  *      ability_mask - Local advertisement.
  20566  * Returns:
  20567  *      BCM_E_NONE
  20568  *      BCM_E_XXX
  20569  * Notes:
  20570  *      This call MAY NOT restart autonegotiation (depending on the phy).
  20571  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  20572  */
  20573 
  20574 int
  20575 bcm_esw_port_ability_advert_set(int unit, bcm_port_t port,
  20576                                 bcm_port_ability_t *ability_mask)
  20577 {
  20578     int             rv=BCM_E_NONE;
  20579     bcm_port_ability_t port_ability, temp_ability;
  20580 #if defined(BCM_KATANA2_SUPPORT)
  20581     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20582 #endif
  20583 
  20584     /* Make sure port module is initialized. */
  20585     PORT_INIT(unit);
  20586 
  20587     /* Call Port Control module */
  20588     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20589         return bcmi_esw_portctrl_ability_advert_set(unit, port,
  20590                                                     ability_mask, 0);
  20591     }
  20592 
  20593     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20594         LOG_ERROR(BSL_LS_BCM_PORT,
  20595                   (BSL_META(
  20596 						"Error: Cannot set port ability on OAMP Port %d.\n"),
  20597                    port));
  20598         return BCM_E_PARAM;
  20599     }
  20600 
  20601 #if defined(BCM_KATANA2_SUPPORT)
  20602 #if defined(BCM_SABER2_SUPPORT)
  20603     if(SOC_IS_SABER2(unit)) {
  20604         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20605     }
  20606 #endif
  20607     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20608         (!((port >= 1) && (port <= max_phy_port)))) {
  20609          return BCM_E_PORT;
  20610     }
  20611 #endif
  20612 
  20613     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20614 
  20615     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  20616         return BCM_E_PORT;
  20617     }
  20618 
  20619     BCM_IF_ERROR_RETURN
  20620         (bcm_esw_port_ability_local_get(unit, port, &port_ability));
  20621 
  20622     /* temporary store speed_half_duplex ability */
  20623     temp_ability.speed_half_duplex = ability_mask->speed_half_duplex;
  20624     /* Make sure to advertise only abilities supported by the port */
  20625     soc_port_ability_mask(&port_ability, ability_mask);
  20626     /* restore speed_half_duplex ability even some mac don't support it */
  20627     port_ability.speed_half_duplex = temp_ability.speed_half_duplex;
  20628     PORT_LOCK(unit);
  20629     rv = soc_phyctrl_ability_advert_set(unit, port, &port_ability);
  20630     PORT_UNLOCK(unit);
  20631     LOG_INFO(BSL_LS_BCM_PORT,
  20632              (BSL_META_U(unit,
  20633                          "bcm_port_ability_advert_set: u=%d p=%d rv=%d\n"),
  20634               unit, port, rv));
  20635     LOG_VERBOSE(BSL_LS_BCM_PORT,
  20636                 (BSL_META_U(unit,
  20637                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x advert_set\n"
  20638                             "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  20639                  port_ability.speed_half_duplex,
  20640                  port_ability.speed_full_duplex,
  20641                  port_ability.pause, port_ability.interface,
  20642                  port_ability.medium, port_ability.loopback,
  20643                  port_ability.flags));
  20644 
  20645     return rv;
  20646 }
  20647 
  20648 /*
  20649  * Function:
  20650  *      bcm_port_autoneg_ability_advert_set
  20651  * Purpose:
  20652  *      Set the local port advertisement for autonegotiation.
  20653  * Parameters:
  20654  *      unit - StrataSwitch Unit #.
  20655  *      port - StrataSwitch port #.
  20656  *      num_ability - number of ability the port will advertise
  20657  *      ability - Local advertisement for each ability.
  20658  * Returns:
  20659  *      BCM_E_NONE
  20660  *      BCM_E_XXX
  20661  * Notes:
  20662  *      This call WILL NOT restart autonegotiation (depending on the phy).
  20663  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  20664  */
  20665 
  20666 int bcm_esw_port_autoneg_ability_advert_set(int unit,
  20667                                             bcm_port_t port,
  20668                                             int num_ability,
  20669                                             bcm_port_speed_ability_t *abilities)
  20670 {
  20671     int             rv = BCM_E_UNAVAIL;
  20672 
  20673     /* Make sure port module is initialized. */
  20674     PORT_INIT(unit);
  20675 
  20676     /* Call Port Control module */
  20677     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20678         rv = bcmi_esw_portctrl_autoneg_ability_advert_set(unit, port,
  20679                                                           num_ability, abilities);
  20680     }
  20681 
  20682     return rv;
  20683 }
  20684 
  20685 
  20686 /*
  20687  * Function:
  20688  *      bcm_port_advert_remote_get
  20689  * Purpose:
  20690  *      Retrieve the local port advertisement for autonegotiation.
  20691  * Parameters:
  20692  *      unit - StrataSwitch Unit #.
  20693  *      port - StrataSwitch port #.
  20694  *      ability_mask - (OUT) Remote advertisement.
  20695  * Returns:
  20696  *      BCM_E_NONE
  20697  *      BCM_E_XXX
  20698  */
  20699 
  20700 int
  20701 bcm_esw_port_advert_remote_get(int unit, bcm_port_t port,
  20702                                bcm_port_abil_t *ability_mask)
  20703 {
  20704     int                 rv;
  20705     bcm_port_ability_t  port_ability;
  20706 #if defined(BCM_KATANA2_SUPPORT)
  20707     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20708 #endif
  20709 
  20710     /* Make sure port module is initialized. */
  20711     PORT_INIT(unit);
  20712 
  20713     /* Call Port Control module */
  20714     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20715         return bcmi_esw_portctrl_ability_remote_get(unit, port,
  20716                                                     &port_ability,
  20717                                                     ability_mask);
  20718     }
  20719 
  20720     sal_memset(&port_ability, 0, sizeof(bcm_port_ability_t));
  20721 
  20722 #if defined(BCM_KATANA2_SUPPORT)
  20723 #if defined(BCM_SABER2_SUPPORT)
  20724     if(SOC_IS_SABER2(unit)) {
  20725         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20726     }
  20727 #endif
  20728     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20729         (!((port >= 1) && (port <= max_phy_port)))) {
  20730          return BCM_E_PORT;
  20731     }
  20732 #endif
  20733     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20734 
  20735     PORT_LOCK(unit);
  20736     rv = _bcm_port_autoneg_advert_remote_get(unit, port, &port_ability);
  20737     if (BCM_SUCCESS(rv)) {
  20738         rv = soc_port_ability_to_mode(&port_ability, ability_mask);
  20739     }
  20740     PORT_UNLOCK(unit);
  20741 
  20742     LOG_INFO(BSL_LS_BCM_PORT,
  20743              (BSL_META_U(unit,
  20744                          "bcm_port_advert_remote_get: u=%d p=%d abil=0x%x rv=%d\n"),
  20745               unit, port, *ability_mask, rv));
  20746 
  20747     return rv;
  20748 }
  20749 
  20750 
  20751 /*
  20752  * Function:
  20753  *      bcm_port_ability_remote_get
  20754  * Purpose:
  20755  *      Retrieve the local port advertisement for autonegotiation.
  20756  * Parameters:
  20757  *      unit - StrataSwitch Unit #.
  20758  *      port - StrataSwitch port #.
  20759  *      ability_mask - (OUT) Remote advertisement.
  20760  * Returns:
  20761  *      BCM_E_NONE
  20762  *      BCM_E_XXX
  20763  */
  20764 int
  20765 bcm_esw_port_ability_remote_get(int unit, bcm_port_t port,
  20766                            bcm_port_ability_t *ability_mask)
  20767 {
  20768     int         rv;
  20769 #if defined(BCM_KATANA2_SUPPORT)
  20770     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20771 #endif
  20772 
  20773     /* Make sure port module is initialized. */
  20774     PORT_INIT(unit);
  20775 
  20776     /* Call Port Control module */
  20777     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20778         return bcmi_esw_portctrl_ability_remote_get(unit, port,
  20779                                                     ability_mask, NULL);
  20780     }
  20781 
  20782 #if defined(BCM_KATANA2_SUPPORT)
  20783 #if defined(BCM_SABER2_SUPPORT)
  20784     if(SOC_IS_SABER2(unit)) {
  20785         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20786     }
  20787 #endif
  20788     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20789         (!((port >= 1) && (port <= max_phy_port)))) {
  20790          return BCM_E_PORT;
  20791     }
  20792 #endif
  20793 
  20794     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20795 
  20796     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  20797     PORT_LOCK(unit);
  20798     rv = _bcm_port_autoneg_advert_remote_get(unit, port, ability_mask);
  20799     PORT_UNLOCK(unit);
  20800 
  20801     LOG_INFO(BSL_LS_BCM_PORT,
  20802              (BSL_META_U(unit,
  20803                          "bcm_port_ability_remote_get: u=%d p=%d rv=%d\n"),
  20804               unit, port, rv));
  20805     LOG_VERBOSE(BSL_LS_BCM_PORT,
  20806                 (BSL_META_U(unit,
  20807                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x remote_get\n"
  20808                             "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  20809                  ability_mask->speed_half_duplex,
  20810                  ability_mask->speed_full_duplex,
  20811                  ability_mask->pause, ability_mask->interface,
  20812                  ability_mask->medium, ability_mask->loopback,
  20813                  ability_mask->flags));
  20814 
  20815     return rv;
  20816 }
  20817 /*
  20818  * Function:
  20819  *      bcm_port_autoneg_ability_remote_get
  20820  * Purpose:
  20821  *      Retrieve the local port abilities.
  20822  * Parameters:
  20823  *      unit - StrataSwitch Unit #.
  20824  *      port - StrataSwitch port #.
  20825  *      max_num_ability  -- the max num of speed ability remote partner can advertise
  20826  *      ability - (OUT) values indicating the ability of the MAC/PHY
  20827  *      actual_num_ability - (OUT) the actual num of ability that remote partner advertise
  20828  * Returns:
  20829  *      BCM_E_NONE
  20830  *      BCM_E_XXX
  20831  */
  20832 int
  20833 bcm_esw_port_autoneg_ability_remote_get(int unit,
  20834                                      bcm_port_t port,
  20835                                      int max_num_ability,
  20836                                      bcm_port_speed_ability_t *abilities,
  20837                                      int *actual_num_ability)
  20838 {
  20839     int rv = BCM_E_UNAVAIL;
  20840 
  20841     /* Make sure port module is initialized. */
  20842     PORT_INIT(unit);
  20843 
  20844     /* Call Port Control module */
  20845     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20846         rv = bcmi_esw_portctrl_autoneg_ability_remote_get(unit, port, max_num_ability,
  20847                                                           abilities, actual_num_ability);
  20848     }
  20849     return rv;
  20850 }
  20851 
  20852 
  20853 /*
  20854  * Function:
  20855  *      bcm_port_ability_get
  20856  * Purpose:
  20857  *      Retrieve the local port abilities.
  20858  * Parameters:
  20859  *      unit - StrataSwitch Unit #.
  20860  *      port - StrataSwitch port #.
  20861  *      ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the
  20862  *              ability of the MAC/PHY.
  20863  * Returns:
  20864  *      BCM_E_NONE
  20865  *      BCM_E_XXX
  20866  */
  20867 
  20868 int
  20869 bcm_esw_port_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask)
  20870 {
  20871     int                 rv;
  20872     bcm_port_ability_t  port_ability;
  20873 #if defined(BCM_KATANA2_SUPPORT)
  20874     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20875 #endif
  20876 
  20877     /* Make sure port module is initialized. */
  20878     PORT_INIT(unit);
  20879 
  20880     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20881         return bcmi_esw_portctrl_ability_get(unit, port,
  20882                                              &port_ability, ability_mask);
  20883     }
  20884 
  20885     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20886         LOG_ERROR(BSL_LS_BCM_PORT,
  20887                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20888                    port));
  20889         return BCM_E_PARAM;
  20890     }
  20891 
  20892 #if defined(BCM_KATANA2_SUPPORT)
  20893 #if defined(BCM_SABER2_SUPPORT)
  20894     if(SOC_IS_SABER2(unit)) {
  20895         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20896     }
  20897 #endif
  20898     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20899         (!((port >= 1) && (port <= max_phy_port)))) {
  20900          return BCM_E_PORT;
  20901     }
  20902 #endif
  20903 
  20904     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20905 
  20906     if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  20907        return BCM_E_PORT;
  20908     }
  20909 
  20910     PORT_LOCK(unit);
  20911     rv = _bcm_port_ability_local_get(unit, port, &port_ability);
  20912     if (BCM_SUCCESS(rv)) {
  20913         rv = soc_port_ability_to_mode(&port_ability, ability_mask);
  20914     }
  20915     PORT_UNLOCK(unit);
  20916 
  20917     LOG_INFO(BSL_LS_BCM_PORT,
  20918              (BSL_META_U(unit,
  20919                          "bcm_port_ability_get: u=%d p=%d abil=0x%x rv=%d\n"),
  20920               unit, port, *ability_mask, rv));
  20921 
  20922     return rv;
  20923 }
  20924 
  20925 /*
  20926  * Function:
  20927  *      bcm_port_ability_local_get
  20928  * Purpose:
  20929  *      Retrieve the local port abilities.
  20930  * Parameters:
  20931  *      unit - StrataSwitch Unit #.
  20932  *      port - StrataSwitch port #.
  20933  *      ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the
  20934  *              ability of the MAC/PHY.
  20935  * Returns:
  20936  *      BCM_E_NONE
  20937  *      BCM_E_XXX
  20938  */
  20939 
  20940 int
  20941 bcm_esw_port_ability_local_get(int unit, bcm_port_t port,
  20942                                bcm_port_ability_t *ability_mask)
  20943 {
  20944     int         rv;
  20945 #if defined(BCM_KATANA2_SUPPORT)
  20946     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20947 #endif
  20948 
  20949     /* Make sure port module is initialized. */
  20950     PORT_INIT(unit);
  20951 
  20952 
  20953     /* Call Port Control module */
  20954     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  20955         return bcmi_esw_portctrl_ability_get(unit, port,
  20956                                              ability_mask, NULL);
  20957     }
  20958 
  20959     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20960         LOG_ERROR(BSL_LS_BCM_PORT,
  20961                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20962                    port));
  20963         return BCM_E_PARAM;
  20964     }
  20965 
  20966 #if defined(BCM_KATANA2_SUPPORT)
  20967 #if defined(BCM_SABER2_SUPPORT)
  20968     if(SOC_IS_SABER2(unit)) {
  20969         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20970     }
  20971 #endif
  20972     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20973         (!((port >= 1) && (port <= max_phy_port)))) {
  20974          return BCM_E_PORT;
  20975     }
  20976 #endif
  20977     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20978 
  20979     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  20980     PORT_LOCK(unit);
  20981     rv = _bcm_port_ability_local_get(unit, port, ability_mask);
  20982     PORT_UNLOCK(unit);
  20983 
  20984     LOG_INFO(BSL_LS_BCM_PORT,
  20985              (BSL_META_U(unit,
  20986                          "bcm_port_ability_local_get: u=%d p=%d rv=%d\n"),
  20987               unit, port, rv));
  20988     LOG_VERBOSE(BSL_LS_BCM_PORT,
  20989                 (BSL_META_U(unit,
  20990                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x local_get\n"
  20991                             "Interface=0x%08x Medium=0x%08x EEE=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  20992                  ability_mask->speed_half_duplex,
  20993                  ability_mask->speed_full_duplex,
  20994                  ability_mask->pause, ability_mask->interface,
  20995                  ability_mask->medium, ability_mask->eee,
  20996                  ability_mask->loopback, ability_mask->flags));
  20997 
  20998     return rv;
  20999 }
  21000 /*
  21001  * Function:
  21002  *      bcm_port_speed_ability_local_get
  21003  * Purpose:
  21004  *      Retrieve the local port abilities.
  21005  * Parameters:
  21006  *      unit - StrataSwitch Unit #.
  21007  *      port - StrataSwitch port #.
  21008  *      max_num_ability  -- the max num of speed ability this port support
  21009  *      ability - (OUT) values indicating the ability of the MAC/PHY
  21010  *      actual_num_ability - (OUT) the actual num of ability that this port can support
  21011  * Returns:
  21012  *      BCM_E_NONE
  21013  *      BCM_E_XXX
  21014  */
  21015 int
  21016 bcm_esw_port_speed_ability_local_get(int unit,
  21017                                      bcm_port_t port,
  21018                                      int max_num_ability,
  21019                                      bcm_port_speed_ability_t *abilities,
  21020                                      int *actual_num_ability)
  21021 {
  21022     int rv = BCM_E_UNAVAIL;
  21023 
  21024     /* Make sure port module is initialized. */
  21025     PORT_INIT(unit);
  21026 
  21027     /* Call Port Control module */
  21028     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  21029         rv = bcmi_esw_portctrl_speed_ability_local_get(unit, port, max_num_ability,
  21030                                                           abilities, actual_num_ability);
  21031     }
  21032     return rv;
  21033 }
  21034 
  21035 /*
  21036  * Function:
  21037  *      bcm_port_discard_get
  21038  * Purpose:
  21039  *      Get port discard attributes for the specified port
  21040  * Parameters:
  21041  *      unit - StrataSwitch Unit #.
  21042  *      port - StrataSwitch port #.
  21043  *      mode - (OUT) Port discard mode, one of BCM_PORT_DISCARD_xxx
  21044  * Returns:
  21045  *      BCM_E_NONE
  21046  *      BCM_E_XXX
  21047  */
  21048 
  21049 int
  21050 bcm_esw_port_discard_get(int unit, bcm_port_t port, int *mode)
  21051 {
  21052     bcm_port_cfg_t pcfg;
  21053     int                 rv;
  21054 
  21055     /* Make sure port module is initialized. */
  21056     PORT_INIT(unit);
  21057 
  21058     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21059         LOG_ERROR(BSL_LS_BCM_PORT,
  21060                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  21061                    port));
  21062         return BCM_E_PARAM;
  21063     }
  21064 
  21065     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21066 
  21067     if ((rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)) ==
  21068         BCM_E_NONE) {
  21069         *mode = pcfg.pc_disc;
  21070     }
  21071 
  21072     return(rv);
  21073 }
  21074 
  21075 /*
  21076  * Function:
  21077  *      bcm_port_discard_set
  21078  * Purpose:
  21079  *      Set port discard attributes for the specified port.
  21080  * Parameters:
  21081  *      unit - StrataSwitch Unit #.
  21082  *      port - StrataSwitch port #.
  21083  *      mode - Port discard mode, one of BCM_PORT_DISCARD_xxx
  21084  * Returns:
  21085  *      BCM_E_NONE
  21086  *      BCM_E_XXX
  21087  */
  21088 
  21089 int
  21090 bcm_esw_port_discard_set(int unit, bcm_port_t port, int mode)
  21091 {
  21092     bcm_port_cfg_t      pcfg;
  21093     int                 rv;
  21094 
  21095     /* Make sure port module is initialized. */
  21096     PORT_INIT(unit);
  21097 
  21098     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21099         LOG_ERROR(BSL_LS_BCM_PORT,
  21100                   (BSL_META("Error: Cannot set discard attr on OAMP Port %d.\n"),
  21101                    port));
  21102         return BCM_E_PARAM;
  21103     }
  21104 
  21105     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21106 
  21107     switch (mode) {
  21108     case BCM_PORT_DISCARD_TAG:
  21109     case BCM_PORT_DISCARD_NONE:
  21110     case BCM_PORT_DISCARD_ALL:
  21111     case BCM_PORT_DISCARD_UNTAG:
  21112         break;
  21113     default:
  21114         return BCM_E_PARAM;
  21115     }
  21116 
  21117     PORT_LOCK(unit);
  21118 
  21119     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  21120 
  21121     if (BCM_SUCCESS(rv)) {
  21122         pcfg.pc_disc = mode;
  21123         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  21124     }
  21125 
  21126     PORT_UNLOCK(unit);
  21127 
  21128     return rv;
  21129 }
  21130 
  21131 /*
  21132  * Function:
  21133  *      _bcm_port_learn_modify
  21134  * Purpose:
  21135  *      Main part of bcm_port_learn_modify.
  21136  */
  21137 
  21138 STATIC int
  21139 _bcm_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove)
  21140 {
  21141     uint32      flags;
  21142 
  21143     SOC_IF_ERROR_RETURN(bcm_esw_port_learn_get(unit, port, &flags));
  21144 
  21145     flags |= add;
  21146     flags &= ~remove;
  21147 
  21148     SOC_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, port, flags));
  21149 
  21150     return BCM_E_NONE;
  21151 }
  21152 
  21153 /*
  21154  * Function:
  21155  *      bcm_port_learn_modify
  21156  * Purpose:
  21157  *      Modify the port learn flags, adding add and removing remove flags.
  21158  * Parameters:
  21159  *      unit - StrataSwitch Unit #.
  21160  *      port - StrataSwitch port #.
  21161  *      add  - Flags to set.
  21162  *      remove - Flags to clear.
  21163  * Returns:
  21164  *      BCM_E_NONE
  21165  *      BCM_E_XXX
  21166  */
  21167 
  21168 int
  21169 bcm_esw_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove)
  21170 {
  21171     int         rv;
  21172     bcm_port_t  port_out;
  21173 
  21174     /* Make sure port module is initialized. */
  21175     PORT_INIT(unit);
  21176 
  21177     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  21178 
  21179     PORT_LOCK(unit);
  21180     rv = _bcm_port_learn_modify(unit, port, add, remove);
  21181     PORT_UNLOCK(unit);
  21182 
  21183     return rv;
  21184 }
  21185 
  21186 /*
  21187  * Function:
  21188  *      bcm_port_learn_get
  21189  * Purpose:
  21190  *      Get the ARL hardware learning options for this port.
  21191  *      This defines what the hardware will do when a packet
  21192  *      is seen with an unknown address.
  21193  * Parameters:
  21194  *      unit - StrataSwitch Unit #.
  21195  *      port - StrataSwitch port #.
  21196  *      flags - (OUT) Logical OR of BCM_PORT_LEARN_xxx flags
  21197  * Returns:
  21198  *      BCM_E_NONE
  21199  *      BCM_E_XXX
  21200  */
  21201 
  21202 int
  21203 bcm_esw_port_learn_get(int unit, bcm_port_t port, uint32 *flags)
  21204 {
  21205     bcm_port_cfg_t      pcfg;
  21206     int                 rv;
  21207 
  21208     /* Make sure port module is initialized. */
  21209     PORT_INIT(unit);
  21210 
  21211     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21212         LOG_ERROR(BSL_LS_BCM_PORT,
  21213                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  21214                    port));
  21215         return BCM_E_PARAM;
  21216     }
  21217 
  21218     if (flags == NULL) {
  21219         return BCM_E_PARAM;
  21220     }
  21221 
  21222 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
  21223     if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  21224          if (SOC_IS_SCORPION(unit)) {
  21225              return BCM_E_UNAVAIL;
  21226          } else {
  21227              return bcm_tr_subport_learn_get(unit, (bcm_gport_t) port, flags);
  21228          }
  21229     }
  21230 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  21231 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  21232     defined(INCLUDE_L3)
  21233     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  21234         return bcm_tr_mpls_port_learn_get(unit, (bcm_gport_t) port, flags);
  21235     }
  21236 #endif
  21237 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21238      && defined(INCLUDE_L3))
  21239     if (BCM_GPORT_IS_MIM_PORT(port)) {
  21240         return bcm_tr2_mim_port_learn_get(unit, (bcm_gport_t) port, flags);
  21241     }
  21242     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21243 #if defined(BCM_TRIUMPH3_SUPPORT)
  21244         if (SOC_IS_TRIUMPH3(unit)) {
  21245             return bcm_tr3_wlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  21246         } else
  21247 #endif /* BCM_TRIUMPH3_SUPPORT */
  21248         {
  21249             return bcm_tr2_wlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  21250         }
  21251     }
  21252 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  21253 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3)
  21254     if (BCM_GPORT_IS_NIV_PORT(port)) {
  21255         return bcm_trident_niv_port_learn_get(unit, (bcm_gport_t) port, flags);
  21256     }
  21257 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  21258 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  21259     if (SOC_IS_TD2_TT2(unit)) {
  21260         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  21261             return bcm_td2_vxlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  21262         }
  21263     }
  21264 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  21265 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21266     if (BCM_GPORT_IS_L2GRE_PORT(port)){
  21267         return bcm_tr3_l2gre_port_learn_get(unit, (bcm_gport_t) port, flags);
  21268     }
  21269 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  21270 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21271     if (BCM_GPORT_IS_EXTENDER_PORT(port)){
  21272         if (soc_feature(unit, soc_feature_port_extension)) {
  21273             return bcm_tr3_extender_port_learn_get(unit, port, flags);
  21274         }
  21275     }
  21276 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  21277 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3)
  21278     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  21279         (soc_feature(unit, soc_feature_channelized_switching))) &&
  21280         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  21281             return bcmi_xgs5_subport_port_learn_get(unit, (bcm_gport_t) port, flags);
  21282     }
  21283 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */
  21284 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  21285     if (BCM_GPORT_IS_TRUNK(port)){
  21286         if (soc_feature(unit, soc_feature_vp_lag)) {
  21287             return bcm_td2_vp_lag_port_learn_get(unit,
  21288                        BCM_GPORT_TRUNK_GET(port), flags);
  21289         }
  21290     }
  21291 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  21292 
  21293     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21294 
  21295     PORT_LOCK(unit);
  21296 
  21297     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  21298 
  21299     PORT_UNLOCK(unit);
  21300 
  21301     BCM_IF_ERROR_RETURN(rv);
  21302 
  21303 #ifdef BCM_TRX_SUPPORT
  21304     if (SOC_IS_TRX(unit)) {
  21305         *flags = 0;
  21306         BCM_IF_ERROR_RETURN(
  21307             _bcm_trx_port_cml_hw2flags(unit, pcfg.pc_cml, flags));
  21308     } else
  21309 #endif
  21310     {
  21311         switch (pcfg.pc_cml) {
  21312         case PVP_CML_SWITCH:
  21313             *flags = (BCM_PORT_LEARN_ARL |
  21314                       BCM_PORT_LEARN_FWD |
  21315                       (pcfg.pc_cpu ? BCM_PORT_LEARN_CPU : 0));
  21316             break;
  21317         case PVP_CML_CPU:
  21318             *flags = BCM_PORT_LEARN_CPU;
  21319             break;
  21320         case PVP_CML_FORWARD:
  21321             *flags = BCM_PORT_LEARN_FWD;
  21322             break;
  21323         case PVP_CML_DROP:
  21324             *flags = 0;
  21325             break;
  21326         case PVP_CML_CPU_SWITCH:
  21327             *flags = (BCM_PORT_LEARN_ARL |
  21328                       BCM_PORT_LEARN_CPU |
  21329                       BCM_PORT_LEARN_FWD);
  21330             break;
  21331         case PVP_CML_CPU_FORWARD:
  21332             *flags = BCM_PORT_LEARN_CPU | BCM_PORT_LEARN_FWD;
  21333             break;
  21334         default:
  21335             return BCM_E_INTERNAL;
  21336         }
  21337     }
  21338 
  21339     return BCM_E_NONE;
  21340 }
  21341 
  21342 /*
  21343  * Function:
  21344  *      bcm_port_learn_set
  21345  * Purpose:
  21346  *      Set the ARL hardware learning options for this port.
  21347  *      This defines what the hardware will do when a packet
  21348  *      is seen with an unknown address.
  21349  * Parameters:
  21350  *      unit - StrataSwitch Unit #.
  21351  *      port - StrataSwitch port #.
  21352  *      flags - Logical OR of BCM_PORT_LEARN_xxx flags
  21353  * Returns:
  21354  *      BCM_E_NONE
  21355  *      BCM_E_XXX
  21356  */
  21357 
  21358 #define Arl     BCM_PORT_LEARN_ARL
  21359 #define Cpu     BCM_PORT_LEARN_CPU
  21360 #define Fwd     BCM_PORT_LEARN_FWD
  21361 
  21362 int
  21363 bcm_esw_port_learn_set(int unit, bcm_port_t port, uint32 flags)
  21364 {
  21365     bcm_port_cfg_t      pcfg;
  21366     int                 rv;
  21367 
  21368     /* Make sure port module is initialized. */
  21369     PORT_INIT(unit);
  21370 
  21371     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21372         LOG_ERROR(BSL_LS_BCM_PORT,
  21373                   (BSL_META("Error: Not permitted on OAMP Port %d.\n"),
  21374                    port));
  21375         return BCM_E_PARAM;
  21376     }
  21377 
  21378 #if defined(BCM_TRX_SUPPORT)  && defined(INCLUDE_L3)
  21379     if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  21380         if (SOC_IS_SCORPION(unit)) {
  21381              return BCM_E_UNAVAIL;
  21382         } else {
  21383             return bcm_tr_subport_learn_set(unit, (bcm_gport_t) port, flags);
  21384         }
  21385     }
  21386 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  21387 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  21388     defined(INCLUDE_L3)
  21389     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  21390         return bcm_tr_mpls_port_learn_set(unit, (bcm_gport_t) port, flags);
  21391     }
  21392 #endif
  21393 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21394      && defined(INCLUDE_L3))
  21395     if (BCM_GPORT_IS_MIM_PORT(port)) {
  21396         return bcm_tr2_mim_port_learn_set(unit, (bcm_gport_t) port, flags);
  21397     }
  21398     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  21399         if (soc_feature(unit, soc_feature_vlan_vp)) {
  21400             return bcm_tr2_vlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  21401         }
  21402     }
  21403     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21404 #if defined(BCM_TRIUMPH3_SUPPORT)
  21405         if (SOC_IS_TRIUMPH3(unit)) {
  21406             return bcm_tr3_wlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  21407         } else
  21408 #endif /* BCM_TRIUMPH3_SUPPORT */
  21409         {
  21410             return bcm_tr2_wlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  21411         }
  21412     }
  21413 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  21414 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3)
  21415     if (BCM_GPORT_IS_NIV_PORT(port)) {
  21416         return bcm_trident_niv_port_learn_set(unit, (bcm_gport_t) port, flags);
  21417     }
  21418 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  21419 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  21420     if (SOC_IS_TD2_TT2(unit)) {
  21421         if (BCM_GPORT_IS_VXLAN_PORT(port)){
  21422             return bcm_td2_vxlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  21423         }
  21424     }
  21425 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  21426 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21427     if (BCM_GPORT_IS_L2GRE_PORT(port)){
  21428         return bcm_tr3_l2gre_port_learn_set(unit, (bcm_gport_t) port, flags);
  21429     }
  21430 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  21431 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21432     if (BCM_GPORT_IS_EXTENDER_PORT(port)){
  21433         if (soc_feature(unit, soc_feature_port_extension)) {
  21434             return bcm_tr3_extender_port_learn_set(unit, port, flags);
  21435         }
  21436     }
  21437 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  21438 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3)
  21439     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  21440         (soc_feature(unit, soc_feature_channelized_switching))) &&
  21441         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  21442             return bcmi_xgs5_subport_port_learn_set(unit, (bcm_gport_t) port, flags);
  21443     }
  21444 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */
  21445 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  21446         if (BCM_GPORT_IS_TRUNK(port)){
  21447             if (soc_feature(unit, soc_feature_vp_lag)) {
  21448                 return bcm_td2_vp_lag_port_learn_set(unit,
  21449                            BCM_GPORT_TRUNK_GET(port), flags);
  21450             }
  21451         }
  21452 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  21453 
  21454     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21455 
  21456     if (flags & BCM_PORT_LEARN_PENDING) {
  21457         if (!soc_feature(unit, soc_feature_l2_pending)) {
  21458             return BCM_E_UNAVAIL;
  21459         } else if (!IS_CPU_PORT(unit, port) & (!(flags & BCM_PORT_LEARN_ARL))) {
  21460             /* When the PENDING flag is set, the ARL must also be set */
  21461             return BCM_E_PARAM;
  21462         }
  21463     }
  21464 
  21465     PORT_LOCK(unit);
  21466 
  21467     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  21468 
  21469     pcfg.pc_cpu = ((flags & BCM_PORT_LEARN_CPU) != 0);
  21470 
  21471     /* Use shortened names to handle each flag combination individually */
  21472 
  21473 #ifdef BCM_TRX_SUPPORT
  21474     if (SOC_IS_TRX(unit)) {
  21475         pcfg.pc_cml = 0;
  21476         rv = _bcm_trx_port_cml_flags2hw(unit, flags, (uint32 *)&pcfg.pc_cml);
  21477         if (BCM_FAILURE(rv)) {
  21478             PORT_UNLOCK(unit);
  21479             return (rv);
  21480         }
  21481     } else
  21482 #endif
  21483     {
  21484         switch (flags) {
  21485         case ((!Arl) | (!Cpu) | (!Fwd)):
  21486             pcfg.pc_cml = PVP_CML_DROP;
  21487             break;
  21488         case ((!Arl) | (!Cpu) | ( Fwd)):
  21489             pcfg.pc_cml = PVP_CML_FORWARD;
  21490             break;
  21491         case ((!Arl) | ( Cpu) | (!Fwd)):
  21492             pcfg.pc_cml = PVP_CML_CPU;
  21493             break;
  21494         case ((!Arl) | ( Cpu) | ( Fwd)):
  21495             if (SOC_IS_XGS_SWITCH(unit)) {
  21496                 pcfg.pc_cml = PVP_CML_CPU_FORWARD;
  21497             } else {
  21498                 rv = BCM_E_UNAVAIL;
  21499             }
  21500             break;
  21501         case (( Arl) | (!Cpu) | (!Fwd)):
  21502             rv = BCM_E_UNAVAIL;
  21503             break;
  21504         case (( Arl) | (!Cpu) | ( Fwd)):
  21505             pcfg.pc_cml = PVP_CML_SWITCH;
  21506             break;
  21507         case (( Arl) | ( Cpu) | (!Fwd)):
  21508             rv = BCM_E_UNAVAIL;
  21509             break;
  21510         case (( Arl) | ( Cpu) | ( Fwd)):
  21511             if (SOC_IS_XGS_SWITCH(unit)) {
  21512                 pcfg.pc_cml = PVP_CML_CPU_SWITCH;
  21513             } else {
  21514                 pcfg.pc_cml = PVP_CML_SWITCH;       /* pc_cpu also being set */
  21515             }
  21516             break;
  21517         }
  21518     }
  21519 
  21520     if (BCM_SUCCESS(rv)) {
  21521         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  21522     }
  21523 
  21524     PORT_UNLOCK(unit);
  21525 
  21526     return rv;
  21527 }
  21528 
  21529 #undef Arl
  21530 #undef Cpu
  21531 #undef Fwd
  21532 
  21533 /*
  21534  * Function:
  21535  *      bcm_port_ifilter_get
  21536  * Description:
  21537  *      Return input filter mode for a port.
  21538  * Parameters:
  21539  *      unit - StrataSwitch PCI device unit number (driver internal).
  21540  *      port - Port number to operate on
  21541  *      mode - (OUT) Filter mode, 1 is enable; 0 is disable.
  21542  * Returns:
  21543  *      BCM_E_NONE              Success.
  21544  *      BCM_E_INTERNAL          Chip access failure.
  21545  * Notes:
  21546  *      This API is superseded by bcm_port_vlan_member_get.
  21547  */
  21548 
  21549 int
  21550 bcm_esw_port_ifilter_get(int unit, bcm_port_t port, int *mode)
  21551 {
  21552     int rv;
  21553     uint32 flags;
  21554 
  21555     /* Make sure port module is initialized. */
  21556     PORT_INIT(unit);
  21557 
  21558     rv = bcm_esw_port_vlan_member_get(unit, port, &flags);
  21559 
  21560     if (BCM_SUCCESS(rv)) {
  21561         *mode = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  21562     }
  21563 
  21564     return rv;
  21565 }
  21566 
  21567 /*
  21568  * Function:
  21569  *      bcm_port_ifilter_set
  21570  * Description:
  21571  *      Set input filter mode for a port.
  21572  * Parameters:
  21573  *      unit - StrataSwitch PCI device unit number (driver internal).
  21574  *      port - Port number to operate on
  21575  *      mode - 1 to enable, 0 to disable.
  21576  * Returns:
  21577  *      BCM_E_NONE              Success.
  21578  *      BCM_E_INTERNAL          Chip access failure.
  21579  * Notes:
  21580  *      This API is superseded by bcm_port_vlan_member_set.
  21581  *
  21582  *      When input filtering is turned on for a port, packets received
  21583  *      on the port that do not match the port's VLAN classifications
  21584  *      are discarded.
  21585  */
  21586 
  21587 int
  21588 bcm_esw_port_ifilter_set(int unit, bcm_port_t port, int mode)
  21589 {
  21590     uint32 flags;
  21591 
  21592     /* Make sure port module is initialized. */
  21593     PORT_INIT(unit);
  21594 
  21595     BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, port, &flags));
  21596 
  21597     if (mode) {
  21598         flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  21599     }  else {
  21600         flags &= (~BCM_PORT_VLAN_MEMBER_INGRESS);
  21601     }
  21602 
  21603     return bcm_esw_port_vlan_member_set(unit, port, flags);
  21604 }
  21605 
  21606 /*
  21607  * Function:
  21608  *      bcm_esw_port_vlan_member_get
  21609  * Description:
  21610  *      Return filter mode for a port.
  21611  * Parameters:
  21612  *      unit - StrataSwitch PCI device unit number (driver internal).
  21613  *      port - Port number to operate on
  21614  *      flags - (OUT) Filter mode, one of BCM_PORT_VLAN_MEMBER_xxx.
  21615  * Returns:
  21616  *      BCM_E_NONE              Success.
  21617  *      BCM_E_INTERNAL          Chip access failure.
  21618  */
  21619 
  21620 int
  21621 bcm_esw_port_vlan_member_get(int unit, bcm_port_t port, uint32 *flags)
  21622 {
  21623     int  rv = BCM_E_UNAVAIL;
  21624 
  21625     *flags = 0;
  21626 
  21627     /* Make sure port module is initialized. */
  21628     PORT_INIT(unit);
  21629 
  21630 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  21631     if (BCMI_GPORT_TYPE_VALID(port)) {
  21632 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  21633         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  21634             return bcm_td2p_vp_vlan_member_get(unit, port, -1, flags);
  21635         } else
  21636 #endif
  21637         {
  21638             return bcm_td_vp_vlan_member_get(unit, port, flags);
  21639         }
  21640     } else
  21641 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  21642     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21643         rv = BCM_E_NONE;
  21644     } else {
  21645         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  21646     }
  21647     BCM_IF_ERROR_RETURN(rv);
  21648     rv = BCM_E_UNAVAIL;
  21649 
  21650     switch (BCM_CHIP_FAMILY(unit)) {
  21651 
  21652     case BCM_FAMILY_HERCULES:
  21653         rv = BCM_E_NONE;
  21654         break;
  21655 
  21656     case BCM_FAMILY_FIREBOLT:
  21657     case BCM_FAMILY_BRADLEY:
  21658     case BCM_FAMILY_HUMV:
  21659     case BCM_FAMILY_TRIUMPH:
  21660     case BCM_FAMILY_SCORPION:
  21661     case BCM_FAMILY_CONQUEROR:
  21662     case BCM_FAMILY_TRIUMPH2:
  21663     case BCM_FAMILY_TRIDENT:
  21664     case BCM_FAMILY_TITAN:
  21665     case BCM_FAMILY_KATANA:
  21666         if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) {
  21667             rv = BCM_E_NONE;
  21668         } else {
  21669             uint32 ent[SOC_MAX_MEM_FIELD_WORDS];
  21670             soc_mem_t mem;
  21671             soc_field_t field = EN_EFILTERf;
  21672 
  21673 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21674      && defined(INCLUDE_L3))
  21675             if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21676                 int value;
  21677                 if (!soc_feature(unit, soc_feature_wlan)) {
  21678                     return BCM_E_PORT;
  21679                 }
  21680 #if defined(BCM_TRIUMPH3_SUPPORT)
  21681                 if (SOC_IS_TRIUMPH3(unit)) {
  21682                     rv = bcm_tr3_wlan_lport_field_get(unit, port,
  21683                                                       EN_IFILTERf, &value);
  21684                 } else
  21685 #endif /* BCM_TRIUMPH3_SUPPORT */
  21686                 {
  21687                     rv = bcm_tr2_wlan_lport_field_get(unit, port,
  21688                                                       EN_IFILTERf, &value);
  21689                 }
  21690                 if (value) {
  21691                     *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  21692                 }
  21693                 return rv;
  21694             }
  21695 #endif
  21696 
  21697             mem = SOC_PORT_MEM_TAB(unit, port);
  21698             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
  21699 #ifdef BCM_TRIDENT3_SUPPORT
  21700                 int value;
  21701                 rv = _bcm_esw_port_tab_get(unit, port, EN_IFILTERf, &value);
  21702                 if (rv == BCM_E_NONE) {
  21703                     if(value) {
  21704                         *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  21705                         if (value == 2) {
  21706                             *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  21707                         }
  21708                     }
  21709                 }
  21710 #endif
  21711             } else {
  21712                 uint32 value = 0;
  21713                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
  21714                                   SOC_PORT_MOD_OFFSET(unit, port), &ent);
  21715 
  21716                 if (BCM_SUCCESS(rv)) {
  21717                     value = soc_PORT_TABm_field32_get(unit, &ent, EN_IFILTERf);
  21718                     if (value) {
  21719                         *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  21720                         if (value == 2) {
  21721                             *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  21722                         }
  21723                     }
  21724                 }
  21725             }
  21726 
  21727 #ifdef BCM_TRIDENT_SUPPORT
  21728             mem = EGR_PORTm;
  21729             field = EN_EFILTERf;
  21730 #ifdef BCM_TRIDENT3_SUPPORT
  21731             if (SOC_IS_TRIDENT3X(unit)) {
  21732                 int val = 0;
  21733                 rv = _bcm_esw_egr_port_tab_get(unit, port, field, &val);
  21734                 if (BCM_SUCCESS(rv) && val != 0) {
  21735                     *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  21736                     if(val == 2) {
  21737                         *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  21738                     }
  21739                 }
  21740             } else
  21741 #endif
  21742             if (SOC_MEM_IS_VALID(unit, mem)) {
  21743                 int val = 0;
  21744                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent);
  21745                 val = soc_mem_field32_get(unit, mem, &ent, field);
  21746                 if (BCM_SUCCESS(rv) && val) {
  21747                     *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  21748                     if(val == 2) {
  21749                         *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  21750                     }
  21751                 }
  21752             } else
  21753 #endif /* BCM_TRIDENT_SUPPORT */
  21754             if (SOC_IS_XGS3_SWITCH(unit)) {
  21755                 uint32 egr_val;
  21756                 uint64 egr_val64;
  21757                 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) {
  21758                     rv = READ_EGR_PORTr(unit, port, &egr_val);
  21759                 } else {
  21760                     rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  21761                 }
  21762                 if (BCM_SUCCESS(rv)) {
  21763                     if (SOC_REG_IS_VALID(unit, EGR_PORTr)) {
  21764                         if (soc_reg_field_valid(unit, EGR_PORTr, field)) {
  21765                             if (soc_reg_field_get(unit, EGR_PORTr,
  21766                                                   egr_val, field)) {
  21767                                 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  21768                             }
  21769                         }
  21770                     } else if (soc_reg64_field32_get(unit,
  21771                                    EGR_PORT_64r, egr_val64, field)) {
  21772                             *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  21773                     }
  21774                 }
  21775             }
  21776         }
  21777         break;
  21778 
  21779     default:
  21780         break;
  21781     }
  21782 
  21783     return rv;
  21784 }
  21785 
  21786 /*
  21787  * Function:
  21788  *      bcm_esw_port_vlan_member_set
  21789  * Description:
  21790  *      Set ingress and egress filter mode for a port.
  21791  * Parameters:
  21792  *      unit - StrataSwitch PCI device unit number (driver internal).
  21793  *      port - Port number to operate on
  21794  *      flags - BCM_PORT_VLAN_MEMBER_xxx.
  21795  * Returns:
  21796  *      BCM_E_NONE              Success.
  21797  *      BCM_E_INTERNAL          Chip access failure.
  21798  */
  21799 
  21800 int
  21801 bcm_esw_port_vlan_member_set(int unit, bcm_port_t port, uint32 flags)
  21802 {
  21803     int       rv = BCM_E_UNAVAIL;
  21804     int fieldLen = 0;
  21805 
  21806     /* Make sure port module is initialized. */
  21807     PORT_INIT(unit);
  21808 
  21809     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21810         LOG_ERROR(BSL_LS_BCM_PORT,
  21811                   (BSL_META("Error: Not permitted on OAMP Port %d.\n"),
  21812                    port));
  21813         return BCM_E_PARAM;
  21814     }
  21815 
  21816     if (BCMI_GPORT_TYPE_VALID(port)) {
  21817 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  21818 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  21819         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  21820             rv = bcm_td2p_vp_vlan_member_set(unit, port, flags);
  21821         } else
  21822 #endif
  21823         {
  21824             rv = bcm_td_vp_vlan_member_set(unit, port, flags);
  21825         }
  21826 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  21827         return rv;
  21828     } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21829         rv = BCM_E_NONE;
  21830     } else {
  21831         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  21832     }
  21833     BCM_IF_ERROR_RETURN(rv);
  21834     rv = BCM_E_UNAVAIL;
  21835 
  21836     PORT_LOCK(unit);
  21837 
  21838     switch (BCM_CHIP_FAMILY(unit)) {
  21839 
  21840     case BCM_FAMILY_HERCULES:
  21841         rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL :
  21842               ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : BCM_E_NONE);
  21843         break;
  21844 
  21845     case BCM_FAMILY_FIREBOLT:
  21846     case BCM_FAMILY_BRADLEY:
  21847     case BCM_FAMILY_HUMV:
  21848     case BCM_FAMILY_TRIUMPH:
  21849     case BCM_FAMILY_SCORPION:
  21850     case BCM_FAMILY_CONQUEROR:
  21851     case BCM_FAMILY_TRIUMPH2:
  21852     case BCM_FAMILY_TRIDENT:
  21853     case BCM_FAMILY_TITAN:
  21854     case BCM_FAMILY_KATANA:
  21855         if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) {
  21856             rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL :
  21857                   ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL :
  21858                   BCM_E_NONE);
  21859         } else {
  21860 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21861      && defined(INCLUDE_L3))
  21862 
  21863             if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21864                 if (!soc_feature(unit, soc_feature_wlan)) {
  21865                     PORT_UNLOCK(unit);
  21866                     return BCM_E_PORT;
  21867                 }
  21868                 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) {
  21869 #if defined(BCM_TRIUMPH3_SUPPORT)
  21870                     if (SOC_IS_TRIUMPH3(unit)) {
  21871                         rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 1);
  21872                     } else
  21873 #endif /* BCM_TRIUMPH3_SUPPORT */
  21874                     {
  21875                         rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 1);
  21876                     }
  21877                 } else {
  21878 #if defined(BCM_TRIUMPH3_SUPPORT)
  21879                     if (SOC_IS_TRIUMPH3(unit)) {
  21880                         rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 0);
  21881                     } else
  21882 #endif /* BCM_TRIUMPH3_SUPPORT */
  21883                     {
  21884                         rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 0);
  21885                     }
  21886                 }
  21887                 PORT_UNLOCK(unit);
  21888                 return rv;
  21889             }
  21890 #endif
  21891             if (SOC_MEM_IS_VALID(unit, PORT_TABm) &&
  21892                 SOC_MEM_FIELD_VALID(unit, PORT_TABm, EN_IFILTERf)) {
  21893                 fieldLen = soc_mem_field_length(unit, PORT_TABm, EN_IFILTERf);
  21894             } else if (SOC_MEM_IS_VALID(unit, LPORT_TABm) &&
  21895                 SOC_MEM_FIELD_VALID(unit, LPORT_TABm, EN_IFILTERf)) {
  21896                 fieldLen = soc_mem_field_length(unit, LPORT_TABm, EN_IFILTERf);
  21897             }
  21898             if (fieldLen > 0) {
  21899                 /* value = 2 requires EN_IFILTERf to have 2 bits. In some
  21900                  * chips the field only has 1 bit */
  21901                 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) &&
  21902                         fieldLen == 1) {
  21903                     PORT_UNLOCK(unit);
  21904                     return BCM_E_PARAM;
  21905                 }
  21906             }
  21907 
  21908             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
  21909                 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  21910                 if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  21911                     (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21912                     if (value == 1) {
  21913                         value = 2;
  21914                     }
  21915                 }
  21916                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  21917                                            EN_IFILTERf, value);
  21918             } else {
  21919                 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  21920                 if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  21921                     (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21922                     if (value == 1) {
  21923                         value = 2;
  21924                     }
  21925                 }
  21926                 rv = _bcm_esw_port_tab_set(unit, port, 0, EN_IFILTERf, value);
  21927             }
  21928 
  21929 #ifdef BCM_TRIDENT_SUPPORT
  21930             if (SOC_MEM_IS_VALID(unit, ING_EN_EFILTER_BITMAPm)) {
  21931                 uint32 efilter;
  21932                 ing_en_efilter_bitmap_entry_t entry;
  21933                 pbmp_t pbmp;
  21934 
  21935                 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  21936                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EN_EFILTERf)) {
  21937                     fieldLen = soc_mem_field_length(unit, EGR_PORTm, EN_EFILTERf);
  21938                 } else if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm) &&
  21939                     SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, EN_EFILTERf)) {
  21940                     fieldLen = soc_mem_field_length(unit, EGR_LPORT_PROFILEm, EN_EFILTERf);
  21941                 }
  21942                 if (fieldLen > 0) {
  21943                     /* value = 2 requires EN_EFILTERf to have 2 bits. In some
  21944                      * chips the field only has 1 bit */
  21945                     if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) &&
  21946                             fieldLen == 1) {
  21947                         PORT_UNLOCK(unit);
  21948                         return BCM_E_PARAM;
  21949                     }
  21950                 }
  21951 
  21952                 efilter = flags & BCM_PORT_VLAN_MEMBER_EGRESS ? 1 : 0;
  21953                 if((efilter == 1) && (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21954                     efilter = 2;
  21955                 }
  21956                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf)) {
  21957                     rv = _bcm_esw_egr_port_tab_set(unit, port, EN_EFILTERf,
  21958                                                    efilter);
  21959                 } else {
  21960                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port, EN_EFILTERf,
  21961                                                 efilter);
  21962                 }
  21963                 if (BCM_SUCCESS(rv)) {
  21964                     rv = soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  21965                                       MEM_BLOCK_ANY, 0, &entry);
  21966                 }
  21967                 if (BCM_SUCCESS(rv)) {
  21968                     soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm,
  21969                                            &entry, BITMAPf, &pbmp);
  21970                     if (efilter && PORT(unit, port).vp_count == 0) {
  21971                         SOC_PBMP_PORT_ADD(pbmp, port);
  21972                     } else {
  21973                         SOC_PBMP_PORT_REMOVE(pbmp, port);
  21974                     }
  21975                     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm,
  21976                                            &entry, BITMAPf, &pbmp);
  21977                     rv = soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  21978                                        MEM_BLOCK_ANY, 0, &entry);
  21979                 }
  21980             } else
  21981 #endif /* BCM_TRIDENT_SUPPORT */
  21982             if (SOC_IS_XGS3_SWITCH(unit)) {
  21983                 soc_reg_t egr_port_reg;
  21984                 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  21985                                 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  21986                                 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  21987                                 EGR_PORT_64r : EGR_PORTr;
  21988                 rv = soc_reg_field32_modify(unit, egr_port_reg, port, EN_EFILTERf,
  21989                                           (flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? 1 : 0);
  21990                 if (BCM_SUCCESS(rv)) {
  21991 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  21992         defined(BCM_SCORPION_SUPPORT)
  21993                     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  21994                         SOC_IS_SC_CQ(unit) || SOC_IS_HAWKEYE(unit)) {
  21995                         uint32 egr_val;
  21996                         pbmp_t pbmp;
  21997                         uint32 bitmap, pbmp32;
  21998 
  21999                         rv = READ_ING_EN_EFILTER_BITMAPr(unit, &egr_val);
  22000                         if (BCM_SUCCESS(rv)) {
  22001                             SOC_PBMP_PORT_SET(pbmp, port);
  22002                             pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0);
  22003                             bitmap =
  22004                                 soc_reg_field_get(unit,
  22005                                                   ING_EN_EFILTER_BITMAPr,
  22006                                                   egr_val, BITMAPf);
  22007                             if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) {
  22008                                 bitmap |= pbmp32;
  22009                             } else {
  22010                                 bitmap &= ~pbmp32;
  22011                             }
  22012                             soc_reg_field_set(unit, ING_EN_EFILTER_BITMAPr,
  22013                                               &egr_val, BITMAPf, bitmap);
  22014                             rv = WRITE_ING_EN_EFILTER_BITMAPr(unit, egr_val);
  22015                         }
  22016                     }
  22017 #endif /* BCM_FIREBOLT_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
  22018 #if defined(BCM_TRIUMPH_SUPPORT)
  22019                     /* Do this only if there is no VP on this port */
  22020                     if (soc_feature (unit, soc_feature_high_portcount_register)) {
  22021                         /*
  22022                         *  pbmp reg split to multiple reg due to high port count
  22023                         *  Note :
  22024                         *   - ING_EN_EFILTER_BITMAP_64r here is split to
  22025                         *      {ING_EN_EFILTER_BITMAP_LOr + ING_EN_EFILTER_BITMAP_HIr}
  22026                         */
  22027                         uint64      fval64, rval64;
  22028                         uint32      t_port;
  22029                         soc_reg_t   reg;
  22030                         pbmp_t      curr_pbmp;
  22031 
  22032                         BCM_PBMP_CLEAR(curr_pbmp);
  22033                         COMPILER_64_ZERO(fval64);
  22034                         COMPILER_64_ZERO(rval64);
  22035 
  22036                         if (port < 64) {
  22037                             reg = ING_EN_EFILTER_BITMAP_LOr;
  22038                             t_port = port;
  22039                         } else {
  22040                             reg = ING_EN_EFILTER_BITMAP_HIr;
  22041                             t_port = port - 64;
  22042                         }
  22043                         rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  22044                         if (BCM_SUCCESS(rv)) {
  22045                             fval64 = soc_reg64_field_get(unit, reg,
  22046                                                          rval64, BITMAPf);
  22047                             SOC_PBMP_WORD_SET(curr_pbmp, 0,
  22048                                               COMPILER_64_LO(fval64));
  22049                             SOC_PBMP_WORD_SET(curr_pbmp, 1,
  22050                                               COMPILER_64_HI(fval64));
  22051 
  22052                             if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)){
  22053                                 SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  22054                             } else {
  22055                                 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  22056                             }
  22057 
  22058                             COMPILER_64_SET(fval64,
  22059                                             SOC_PBMP_WORD_GET(curr_pbmp, 1),
  22060                                             SOC_PBMP_WORD_GET(curr_pbmp, 0));
  22061                             soc_reg64_field_set(unit, reg, &rval64,
  22062                                                 BITMAPf, fval64);
  22063                             rv = soc_reg_set(unit, reg,
  22064                                              REG_PORT_ANY, 0, rval64);
  22065                         }
  22066                     } else if (SOC_IS_TR_VL(unit)) {
  22067                         uint64 egr_val_64;
  22068                         pbmp_t pbmp;
  22069                         uint32 bitmap, pbmp32;
  22070 
  22071                         rv = READ_ING_EN_EFILTER_BITMAP_64r(unit, &egr_val_64);
  22072                         if (BCM_SUCCESS(rv)) {
  22073                             SOC_PBMP_PORT_SET(pbmp, port);
  22074                             /* Low bitmap */
  22075                             bitmap =
  22076                                 soc_reg64_field32_get(unit,
  22077                                                       ING_EN_EFILTER_BITMAP_64r,
  22078                                                       egr_val_64, BITMAP_LOf);
  22079                             pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0);
  22080                             if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)  &&
  22081                                 (PORT(unit, port).vp_count == 0)) {
  22082                                 bitmap |= pbmp32;
  22083                             } else {
  22084                                 bitmap &= ~pbmp32;
  22085                             }
  22086                             soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r,
  22087                                                   &egr_val_64, BITMAP_LOf, bitmap);
  22088 
  22089                             if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  22090                                     !SOC_IS_GREYHOUND(unit)) {
  22091                                 /* High bitmap */
  22092                                 bitmap =
  22093                                     soc_reg64_field32_get(unit,
  22094                                                           ING_EN_EFILTER_BITMAP_64r,
  22095                                                           egr_val_64, BITMAP_HIf);
  22096                                 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  22097                                 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)  &&
  22098                                     (PORT(unit, port).vp_count == 0)) {
  22099                                     bitmap |= pbmp32;
  22100                                 } else {
  22101                                     bitmap &= ~pbmp32;
  22102                                 }
  22103                                 soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r,
  22104                                                       &egr_val_64, BITMAP_HIf, bitmap);
  22105                             }
  22106 
  22107                             rv = WRITE_ING_EN_EFILTER_BITMAP_64r(unit, egr_val_64);
  22108                         }
  22109                     }
  22110 #endif
  22111                 }
  22112             }
  22113         }
  22114         break;
  22115 
  22116     default:
  22117         break;
  22118     }
  22119 
  22120     PORT_UNLOCK(unit);
  22121 
  22122     return rv;
  22123 }
  22124 
  22125 /*
  22126  * Function:
  22127  *      _bcm_port_link_get
  22128  * Purpose:
  22129  *      Return current PHY up/down status
  22130  * Parameters:
  22131  *      unit - StrataSwitch Unit #.
  22132  *      port - StrataSwitch port #.
  22133  *      hw - If TRUE, assume hardware linkscan is active and use it
  22134  *              to reduce PHY reads.
  22135  *           If FALSE, do not use information from hardware linkscan.
  22136  *      up - (OUT) TRUE for link up, FALSE for link down.
  22137  * Returns:
  22138  *      BCM_E_NONE
  22139  *      BCM_E_XXX
  22140  */
  22141 
  22142 int
  22143 _bcm_port_link_get(int unit, bcm_port_t port, int hw, int *up)
  22144 {
  22145     int     rv = 0;
  22146 #if defined(BCM_KATANA2_SUPPORT)
  22147     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  22148 #endif
  22149 
  22150     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  22151         return bcmi_esw_portctrl_link_get(unit, port, hw, up);
  22152     }
  22153 
  22154 #if defined(BCM_KATANA2_SUPPORT)
  22155 #if defined(BCM_SABER2_SUPPORT)
  22156     if(SOC_IS_SABER2(unit)) {
  22157         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  22158     }
  22159 #endif
  22160     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  22161         (!((port >= 1) && (port <= max_phy_port)))) {
  22162          return BCM_E_PORT;
  22163     }
  22164 #endif
  22165     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22166 
  22167     PORT_LOCK(unit);
  22168 
  22169     if (hw) {
  22170         pbmp_t hw_linkstat;
  22171 
  22172         rv = soc_linkscan_hw_link_get(unit, &hw_linkstat);
  22173 
  22174         *up = PBMP_MEMBER(hw_linkstat, port);
  22175 
  22176         /*
  22177          * We need to confirm link down because we may receive false link
  22178          * change interrupts when hardware and software linkscan are mixed.
  22179          * Processing a false link down event is known to cause packet
  22180          * loss, which is obviously unacceptable.
  22181          */
  22182         if(!(*up)) {
  22183             rv = soc_phyctrl_link_get(unit, port, up);
  22184         }
  22185     } else {
  22186         if (SOC_IS_RCPU_ONLY(unit)) {
  22187             rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, up);
  22188         } else {
  22189             rv = soc_phyctrl_link_get(unit, port, up);
  22190         }
  22191     }
  22192 
  22193     if (BCM_SUCCESS(rv)) {
  22194         if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_MEDIUM_CHANGE)) {
  22195             soc_port_medium_t  medium;
  22196             soc_phyctrl_medium_get(unit, port, &medium);
  22197             soc_phy_medium_status_notify(unit, port, medium);
  22198         }
  22199     }
  22200     PORT_UNLOCK(unit);
  22201 
  22202     LOG_VERBOSE(BSL_LS_BCM_PORT,
  22203                 (BSL_META_U(unit,
  22204                             "_bcm_port_link_get: u=%d p=%d hw=%d up=%d rv=%d\n"),
  22205                  unit, port, hw, *up, rv));
  22206 
  22207     return rv;
  22208 }
  22209 
  22210 /*
  22211  * Function:
  22212  *      bcm_port_link_status_get
  22213  * Purpose:
  22214  *      Return current Link up/down status, queries linkscan, if unable to
  22215  *      retrieve status queries the PHY.
  22216  * Parameters:
  22217  *      unit - StrataSwitch Unit #.
  22218  *      port - StrataSwitch port #.
  22219  *      up - (OUT) Boolean value, FALSE for link down and TRUE for link up
  22220  * Returns:
  22221  *      BCM_E_NONE
  22222  *      BCM_E_XXX
  22223  */
  22224 
  22225 int
  22226 bcm_esw_port_link_status_get(int unit, bcm_port_t port, int *up)
  22227 {
  22228     int                 rv;
  22229 #if defined(BCM_KATANA2_SUPPORT)
  22230     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  22231 #endif
  22232 
  22233     /* Make sure port module is initialized. */
  22234     PORT_INIT(unit);
  22235 
  22236     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22237         LOG_ERROR(BSL_LS_BCM_PORT,
  22238                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  22239                    port));
  22240         return BCM_E_PARAM;
  22241     }
  22242 
  22243 #if defined(BCM_KATANA2_SUPPORT)
  22244 #if defined(BCM_SABER2_SUPPORT)
  22245     if(SOC_IS_SABER2(unit)) {
  22246         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  22247     }
  22248 #endif
  22249     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  22250         (!((port >= 1) && (port <= max_phy_port)))) {
  22251          return BCM_E_PORT;
  22252     }
  22253 #endif
  22254     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22255 
  22256     rv = _bcm_esw_link_get(unit, port, up);
  22257 
  22258     if (rv == BCM_E_DISABLED) {
  22259         int mode;
  22260         mode = BCM_LINKSCAN_MODE_NONE;
  22261 
  22262         rv = bcm_esw_linkscan_mode_get(unit, port, &mode);
  22263 
  22264 #if defined(BCM_KATANA2_SUPPORT)
  22265         /*
  22266          * Check added for invalid ports where the port number
  22267          * lies between the maximum and minimum port values.
  22268          */
  22269         if (SOC_IS_KATANA2(unit) && rv == BCM_E_PORT) {
  22270             return rv;
  22271         }
  22272 #endif
  22273         if (mode == BCM_LINKSCAN_MODE_HW) {
  22274             rv = _bcm_port_link_get(unit, port, 1, up);
  22275         } else {
  22276             rv = _bcm_port_link_get(unit, port, 0, up);
  22277         }
  22278     }
  22279 
  22280 
  22281     return rv;
  22282 }
  22283 
  22284 /*
  22285  * Function:
  22286  *      bcm_esw_port_link_failed_clear
  22287  * Purpose:
  22288  *      Clear failed link status from a port which has undergone
  22289  *      LAG failover.
  22290  * Parameters:
  22291  *      unit - StrataSwitch Unit #.
  22292  *      port - StrataSwitch port #.
  22293  * Notes:
  22294  *      The port is moved to down status.  The application is responsible
  22295  *      for removing the port from all trunk memberships before calling this
  22296  *      function.
  22297  * Returns:
  22298  *      BCM_E_NONE
  22299  *      BCM_E_XXX
  22300  */
  22301 
  22302 int
  22303 bcm_esw_port_link_failed_clear(int unit, bcm_port_t port)
  22304 {
  22305     /* Make sure port module is initialized. */
  22306     PORT_INIT(unit);
  22307 
  22308     return _bcm_esw_link_failed_clear(unit, port);
  22309 }
  22310 
  22311 /*
  22312  * Function:
  22313  *      _bcm_port_pfm_set
  22314  * Purpose:
  22315  *      Main part of function bcm_port_pfm_set
  22316  */
  22317 
  22318 STATIC int
  22319 _bcm_port_pfm_set(int unit, bcm_port_t port, int mode)
  22320 {
  22321     int                 rv = BCM_E_NONE;
  22322 
  22323     /*
  22324      * The filter mode for the first 16 ports is in one register
  22325      * and for the rest in another
  22326      */
  22327     switch (BCM_CHIP_FAMILY(unit)) {
  22328 
  22329 #ifdef BCM_XGS12_FABRIC_SUPPORT
  22330     case BCM_FAMILY_HERCULES:
  22331         /* See remarks under bcm_port_pfm_get below */
  22332         break;
  22333 #endif
  22334 
  22335 #ifdef BCM_XGS3_SWITCH_SUPPORT
  22336     case BCM_FAMILY_FIREBOLT:
  22337     case BCM_FAMILY_BRADLEY:
  22338     case BCM_FAMILY_HUMV:
  22339     case BCM_FAMILY_TRIUMPH:
  22340     case BCM_FAMILY_SCORPION:
  22341     case BCM_FAMILY_CONQUEROR:
  22342     case BCM_FAMILY_TRIUMPH2:
  22343     case BCM_FAMILY_TRIDENT:
  22344     case BCM_FAMILY_TITAN:
  22345     case BCM_FAMILY_KATANA:
  22346         /*
  22347          * PFM is a per VLAN attribute. It is not a per port attribute
  22348          * on XGS3
  22349          */
  22350         return BCM_E_UNAVAIL;
  22351 #endif
  22352 
  22353     default:
  22354         return BCM_E_UNAVAIL;
  22355         break;
  22356     }
  22357 
  22358     return rv;
  22359 }
  22360 
  22361 /*
  22362  * Function:
  22363  *      bcm_port_pfm_set
  22364  * Purpose:
  22365  *      Set current port filtering mode (see port.h)
  22366  * Parameters:
  22367  *      unit - StrataSwitch Unit #.
  22368  *      port - StrataSwitch port #.
  22369  *      mode - mode for PFM bits (see port.h)
  22370  * Returns:
  22371  *      BCM_E_NONE
  22372  *      BCM_E_XXX
  22373  */
  22374 
  22375 int
  22376 bcm_esw_port_pfm_set(int unit, bcm_port_t port, int mode)
  22377 {
  22378     int                 rv;
  22379 
  22380     /* Make sure port module is initialized. */
  22381     PORT_INIT(unit);
  22382 
  22383     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22384     if (!IS_PORT(unit, port)) {
  22385         return BCM_E_PORT;
  22386     }
  22387 
  22388     PORT_LOCK(unit);
  22389     rv = _bcm_port_pfm_set(unit, port, mode);
  22390     PORT_UNLOCK(unit);
  22391 
  22392     return rv;
  22393 }
  22394 
  22395 /*
  22396  * Function:
  22397  *      bcm_port_pfm_get
  22398  * Purpose:
  22399  *      Return current port filtering mode (see port.h)
  22400  * Parameters:
  22401  *      unit - StrataSwitch Unit #.
  22402  *      port - StrataSwitch port #.
  22403  *      mode - (OUT) mode read from StrataSwitch for PFM bits (see port.h)
  22404  * Returns:
  22405  *      BCM_E_NONE
  22406  *      BCM_E_XXX
  22407  * Notes:
  22408  *      This function not supported on 5670.
  22409  */
  22410 
  22411 int
  22412 bcm_esw_port_pfm_get(int unit, bcm_port_t port, int *mode)
  22413 {
  22414     /* Make sure port module is initialized. */
  22415     PORT_INIT(unit);
  22416 
  22417     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22418     if (!IS_PORT(unit, port)) {
  22419         return BCM_E_PORT;
  22420     }
  22421 
  22422     switch (BCM_CHIP_FAMILY(unit)) {
  22423 
  22424 #ifdef BCM_HERCULES_SUPPORT
  22425     case BCM_FAMILY_HERCULES:
  22426         /*
  22427          * Packets marked as multicast prompt a lookup in the
  22428          * MC table in 567x.  There is no notion of missing a multicast
  22429          * address.
  22430          *
  22431          * Alternatively, we can mess with the MC/IPMC table
  22432          * entries to support the different modes.  This is
  22433          * probably not worth the trouble when we look at how
  22434          * 567x is meant to fit into the system.
  22435          */
  22436         *mode = BCM_PORT_PFM_MODEC;
  22437         break;
  22438 #endif
  22439 
  22440 #ifdef BCM_XGS3_SWITCH_SUPPORT
  22441     case BCM_FAMILY_FIREBOLT:
  22442     case BCM_FAMILY_BRADLEY:
  22443     case BCM_FAMILY_HUMV:
  22444     case BCM_FAMILY_TRIUMPH:
  22445     case BCM_FAMILY_SCORPION:
  22446     case BCM_FAMILY_CONQUEROR:
  22447     case BCM_FAMILY_TRIUMPH2:
  22448     case BCM_FAMILY_TRIDENT:
  22449     case BCM_FAMILY_TITAN:
  22450     case BCM_FAMILY_KATANA:
  22451         /*
  22452          * PFM is a per VLAN attribute. It is not a per port attribute
  22453          * on XGS3
  22454          */
  22455         *mode = BCM_PORT_PFM_MODEC;
  22456         return BCM_E_UNAVAIL;
  22457 #endif
  22458 
  22459     default:
  22460         return BCM_E_UNAVAIL;
  22461         break;
  22462     }
  22463 
  22464     return BCM_E_NONE;
  22465 }
  22466 
  22467 /*
  22468  * Function:
  22469  *      _bcm_port_untagged_priority_set
  22470  * Purpose:
  22471  *      Main part of bcm_port_untagged_priority_set.
  22472  */
  22473 
  22474 STATIC int
  22475 _bcm_port_untagged_priority_set(int unit, bcm_port_t port, int priority)
  22476 {
  22477     if (priority > 7) {
  22478         return BCM_E_PARAM;
  22479     }
  22480 
  22481     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22482         LOG_ERROR(BSL_LS_BCM_PORT,
  22483                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22484                    port));
  22485         return BCM_E_PARAM;
  22486     }
  22487 
  22488 #if defined(BCM_XGS_SWITCH_SUPPORT)
  22489     if (soc_feature(unit, soc_feature_remap_ut_prio) && (priority >= 0)) {
  22490         bcm_port_cfg_t pcfg;
  22491         SOC_IF_ERROR_RETURN(
  22492             mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  22493         pcfg.pc_remap_pri_en = 1;
  22494             pcfg.pc_new_opri = priority;
  22495         SOC_IF_ERROR_RETURN(
  22496             mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  22497         PORT(unit, port).p_ut_prio = pcfg.pc_new_opri;
  22498         return SOC_E_NONE;
  22499     }
  22500 #endif /* BCM_XGS_SWITCH_SUPPORT */
  22501 
  22502     if (priority < 0) {
  22503         return BCM_E_PARAM;
  22504     }
  22505 
  22506     return BCM_E_UNAVAIL;
  22507 }
  22508 
  22509 /*
  22510  * Function:
  22511  *      bcm_port_untagged_priority_set
  22512  * Purpose:
  22513  *      Set the 802.1P priority for untagged packets coming in on a
  22514  *      port.  This value will be written into the priority field of the
  22515  *      tag that is added at the ingress.
  22516  * Parameters:
  22517  *      unit      - StrataSwitch Unit #.
  22518  *      port      - StrataSwitch port #.
  22519  *      priority  - Priority to be set in 802.1p priority tag, from 0 to 7.
  22520  *                  A negative priority leaves the ingress port priority as
  22521  *                  is, but disables it from overriding ARL-based priorities.
  22522  *                  (on those devices that support ARL-based priority).
  22523  * Returns:
  22524  *      BCM_E_NONE
  22525  *      BCM_E_XXX
  22526  */
  22527 
  22528 int
  22529 bcm_esw_port_untagged_priority_set(int unit, bcm_port_t port, int priority)
  22530 {
  22531     int         rv;
  22532 
  22533     /* Make sure port module is initialized. */
  22534     PORT_INIT(unit);
  22535 
  22536     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22537         LOG_ERROR(BSL_LS_BCM_PORT,
  22538                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22539                    port));
  22540         return BCM_E_PARAM;
  22541     }
  22542 
  22543 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  22544      && defined(INCLUDE_L3))
  22545     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  22546 #if defined(BCM_TRIUMPH3_SUPPORT)
  22547         if (SOC_IS_TRIUMPH3(unit)) {
  22548             return bcm_tr3_wlan_port_untagged_prio_set(unit, port, priority);
  22549         } else
  22550 #endif /* BCM_TRIUMPH3_SUPPORT */
  22551         {
  22552             return bcm_tr2_wlan_port_untagged_prio_set(unit, port, priority);
  22553         }
  22554     }
  22555 #endif
  22556     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22557 
  22558     PORT_LOCK(unit);
  22559     rv = _bcm_port_untagged_priority_set(unit, port, priority);
  22560     PORT_UNLOCK(unit);
  22561 
  22562     LOG_INFO(BSL_LS_BCM_PORT,
  22563              (BSL_META_U(unit,
  22564                          "bcm_port_ut_priority_set: u=%d p=%d pri=%d rv=%d\n"),
  22565               unit, port, priority, rv));
  22566 
  22567     return rv;
  22568 }
  22569 
  22570 /*
  22571  * Function:
  22572  *      bcm_port_untagged_priority_get
  22573  * Purpose:
  22574  *      Returns priority being assigned to untagged receive packets
  22575  * Parameters:
  22576  *      unit      - StrataSwitch Unit #.
  22577  *      port      - StrataSwitch port #.
  22578  *      priority  - Pointer to an int in which priority value is returned.
  22579  * Returns:
  22580  *      BCM_E_NONE
  22581  *      BCM_E_XXX
  22582  */
  22583 
  22584 int
  22585 bcm_esw_port_untagged_priority_get(int unit, bcm_port_t port, int *priority)
  22586 {
  22587     /* Make sure port module is initialized. */
  22588     PORT_INIT(unit);
  22589 
  22590     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22591         LOG_ERROR(BSL_LS_BCM_PORT,
  22592                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22593                    port));
  22594         return BCM_E_PARAM;
  22595     }
  22596 
  22597 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  22598      && defined(INCLUDE_L3))
  22599     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  22600 #if defined(BCM_TRIUMPH3_SUPPORT)
  22601         if (SOC_IS_TRIUMPH3(unit)) {
  22602             return bcm_tr3_wlan_port_untagged_prio_get(unit, port, priority);
  22603         } else
  22604 #endif /* BCM_TRIUMPH3_SUPPORT */
  22605         {
  22606             return bcm_tr2_wlan_port_untagged_prio_get(unit, port, priority);
  22607         }
  22608     }
  22609 #endif
  22610     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22611 
  22612     if (priority != NULL) {
  22613         *priority = PORT(unit, port).p_ut_prio;
  22614         LOG_INFO(BSL_LS_BCM_PORT,
  22615                  (BSL_META_U(unit,
  22616                              "bcm_port_ut_priority_get: u=%d p=%d pri=%d\n"),
  22617                   unit, port, *priority));
  22618     }
  22619 
  22620     return BCM_E_NONE;
  22621 }
  22622 
  22623 /*
  22624  * Function:
  22625  *      bcm_port_selective_get
  22626  * Purpose:
  22627  *      Get requested port parameters
  22628  * Parameters:
  22629  *      unit - switch Unit
  22630  *      port - switch port
  22631  *      info - (IN/OUT) port information structure
  22632  * Returns:
  22633  *      BCM_E_XXX
  22634  * Notes:
  22635  *      The action_mask field of the info argument is used as an input
  22636  */
  22637 
  22638 int
  22639 bcm_esw_port_selective_get(int unit, bcm_port_t port, bcm_port_info_t *info)
  22640 {
  22641     int                 r;
  22642     uint32              mask;
  22643     bcm_port_if_t       intf;
  22644     int                 speed;
  22645 
  22646     /* Make sure port module is initialized. */
  22647     PORT_INIT(unit);
  22648     if (!BCM_GPORT_IS_SET(port)) {
  22649         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {
  22650             return BCM_E_PORT;
  22651         }
  22652     }
  22653 
  22654     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22655         LOG_ERROR(BSL_LS_BCM_PORT,
  22656                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22657                    port));
  22658         return BCM_E_PARAM;
  22659     }
  22660 
  22661     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22662 
  22663     mask = info->action_mask;
  22664 
  22665     /* PM8x50 does not support these things, so do not try to fetch them */
  22666     if (IS_CD_PORT(unit, port)) {
  22667         mask &= ~BCM_PORT_ATTR_ABILITY_MASK;
  22668         mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  22669         mask &= ~BCM_PORT_ATTR_INTERFACE_MASK;
  22670     }
  22671 
  22672     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) ||
  22673         IS_CE_PORT(unit, port)) {
  22674         if (!(IS_CD_PORT(unit, port))) {
  22675             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  22676             BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &intf));
  22677 
  22678             /* check if the port has no fault status to retrieve */
  22679             if (speed < 5000) {
  22680                 mask &= ~BCM_PORT_ATTR_FAULT_MASK;
  22681             } else if (speed == 5000) {
  22682                 if (intf != BCM_PORT_IF_KR) {
  22683                     mask &= ~BCM_PORT_ATTR_FAULT_MASK;
  22684                 }
  22685             } else if (speed < 10000) {
  22686                 mask &= ~BCM_PORT_ATTR_FAULT_MASK;
  22687             }
  22688         }
  22689     }
  22690 
  22691     if (IS_QSGMII_PORT(unit, port)) {
  22692         mask &= ~BCM_PORT_ATTR_FAULT_MASK;
  22693     }
  22694 
  22695     if (mask & BCM_PORT_ATTR_ENCAP_MASK) {
  22696         r = bcm_esw_port_encap_get(unit, port, &info->encap_mode);
  22697         if (BCM_FAILURE(r)) {
  22698             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22699                         (BSL_META_U(unit,
  22700                                     "bcm_port_encap_getfailed:%s\n"), bcm_errmsg(r)));
  22701         }
  22702         BCM_IF_ERROR_RETURN(r);
  22703     }
  22704 
  22705     if (mask & BCM_PORT_ATTR_ENABLE_MASK) {
  22706         r = bcm_esw_port_enable_get(unit, port, &info->enable);
  22707         if (BCM_FAILURE(r)) {
  22708             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22709                         (BSL_META_U(unit,
  22710                                     "bcm_port_enable_getfailed:%s\n"), bcm_errmsg(r)));
  22711         }
  22712         BCM_IF_ERROR_RETURN(r);
  22713     }
  22714 
  22715     if (mask & BCM_PORT_ATTR_LINKSTAT_MASK) {
  22716         r = bcm_esw_port_link_status_get(unit, port, &info->linkstatus);
  22717         if (BCM_FAILURE(r)) {
  22718             /* LOG_VERBOSE(BSL_LS_BCM_PORT,
  22719                         (BSL_META_U(unit,
  22720                                     "bcm_port_link_status_getfailed:%s\n"), bcm_errmsg(r))); */
  22721         }
  22722         BCM_IF_ERROR_RETURN(r);
  22723     }
  22724 
  22725     if (mask & BCM_PORT_ATTR_AUTONEG_MASK) {
  22726         r = bcm_esw_port_autoneg_get(unit, port, &info->autoneg);
  22727         if (BCM_FAILURE(r)) {
  22728             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22729                         (BSL_META_U(unit,
  22730                                     "bcm_port_autoneg_getfailed:%s\n"), bcm_errmsg(r)));
  22731         }
  22732         BCM_IF_ERROR_RETURN(r);
  22733     }
  22734 
  22735     if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) {
  22736         r = bcm_esw_port_ability_advert_get(unit, port,
  22737                                             &info->local_ability);
  22738         if (BCM_FAILURE(r)) {
  22739             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22740                         (BSL_META_U(unit,
  22741                                     "bcm_port_ability_advert_getfailed:%s\n"),
  22742                          bcm_errmsg(r)));
  22743         }
  22744         BCM_IF_ERROR_RETURN(r);
  22745         r = soc_port_ability_to_mode(&info->local_ability,
  22746                                      &info->local_advert);
  22747         BCM_IF_ERROR_RETURN(r);
  22748     }
  22749 
  22750     if (mask & BCM_PORT_ATTR_REMOTE_ADVERT_MASK) {
  22751 
  22752         if ((r = bcm_esw_port_ability_remote_get(unit, port,
  22753                                                  &info->remote_ability)) < 0) {
  22754             info->remote_advert = 0;
  22755             info->remote_advert_valid = FALSE;
  22756         } else {
  22757             r = soc_port_ability_to_mode(&info->remote_ability,
  22758                                          &info->remote_advert);
  22759             BCM_IF_ERROR_RETURN(r);
  22760             info->remote_advert_valid = TRUE;
  22761         }
  22762     }
  22763 
  22764     if (mask & BCM_PORT_ATTR_SPEED_MASK) {
  22765         if ((r = bcm_esw_port_speed_get(unit, port, &info->speed)) < 0) {
  22766             if (r != BCM_E_BUSY) {
  22767                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  22768                             (BSL_META_U(unit,
  22769                                         "bcm_port_speed_get failed: %s\n"), bcm_errmsg(r)));
  22770                 return(r);
  22771             } else {
  22772                 info->speed = 0;
  22773             }
  22774         }
  22775     }
  22776 
  22777     if (mask & BCM_PORT_ATTR_DUPLEX_MASK) {
  22778         if ((r = bcm_esw_port_duplex_get(unit, port, &info->duplex)) < 0) {
  22779             if (r != BCM_E_BUSY) {
  22780                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  22781                             (BSL_META_U(unit,
  22782                                         "bcm_port_duplex_get failed: %s\n"), bcm_errmsg(r)));
  22783                 return r;
  22784             } else {
  22785                 info->duplex = 0;
  22786             }
  22787         }
  22788     }
  22789 
  22790     /* get both if either mask bit set */
  22791     if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK |
  22792                 BCM_PORT_ATTR_PAUSE_RX_MASK)) {
  22793         r = bcm_esw_port_pause_get(unit, port,
  22794                                    &info->pause_tx, &info->pause_rx);
  22795         if (BCM_FAILURE(r)) {
  22796             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22797                         (BSL_META_U(unit,
  22798                                     "bcm_port_pause_get failed:%s\n"), bcm_errmsg(r)));
  22799         }
  22800         BCM_IF_ERROR_RETURN(r);
  22801     }
  22802 
  22803     if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) {
  22804         r = bcm_esw_port_pause_addr_get(unit, port, info->pause_mac);
  22805         if (BCM_FAILURE(r)) {
  22806             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22807                         (BSL_META_U(unit,
  22808                                     "bcm_port_pause_addr_get failed:%s\n"), bcm_errmsg(r)));
  22809         }
  22810         BCM_IF_ERROR_RETURN(r);
  22811     }
  22812 
  22813     if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) {
  22814         r = bcm_esw_port_linkscan_get(unit, port, &info->linkscan);
  22815         if (BCM_FAILURE(r)) {
  22816             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22817                         (BSL_META_U(unit,
  22818                                     "bcm_port_linkscan_get failed:%s\n"), bcm_errmsg(r)));
  22819         }
  22820         BCM_IF_ERROR_RETURN(r);
  22821     }
  22822 
  22823     if (mask & BCM_PORT_ATTR_LEARN_MASK) {
  22824         r = bcm_esw_port_learn_get(unit, port, &info->learn);
  22825         if (BCM_FAILURE(r)) {
  22826             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22827                         (BSL_META_U(unit,
  22828                                     "bcm_port_learn_getfailed:%s\n"), bcm_errmsg(r)));
  22829         }
  22830         BCM_IF_ERROR_RETURN(r);
  22831     }
  22832 
  22833     if (mask & BCM_PORT_ATTR_DISCARD_MASK) {
  22834         r = bcm_esw_port_discard_get(unit, port, &info->discard);
  22835         if (BCM_FAILURE(r)) {
  22836             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22837                         (BSL_META_U(unit,
  22838                                     "bcm_port_discard_get failed:%s\n"), bcm_errmsg(r)));
  22839         }
  22840         BCM_IF_ERROR_RETURN(r);
  22841     }
  22842 
  22843     if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) {
  22844         r = bcm_esw_port_vlan_member_get(unit, port, &info->vlanfilter);
  22845         if (BCM_FAILURE(r)) {
  22846             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22847                         (BSL_META_U(unit,
  22848                                     "bcm_esw_port_vlan_member_get failed:%s\n"),
  22849                          bcm_errmsg(r)));
  22850         }
  22851         BCM_IF_ERROR_RETURN(r);
  22852     }
  22853 
  22854     if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) {
  22855         r = bcm_esw_port_untagged_priority_get(unit, port,
  22856                                                &info->untagged_priority);
  22857         if (BCM_FAILURE(r)) {
  22858             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22859                         (BSL_META_U(unit,
  22860                                     "bcm_port_untagged_priority_get failed:%s\n"),
  22861                          bcm_errmsg(r)));
  22862         }
  22863         BCM_IF_ERROR_RETURN(r);
  22864     }
  22865 
  22866     if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) {
  22867         r = bcm_esw_port_untagged_vlan_get(unit, port,
  22868                                            &info->untagged_vlan);
  22869         if (BCM_FAILURE(r)) {
  22870             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22871                         (BSL_META_U(unit,
  22872                                     "bcm_port_untagged_vlan_get failed:%s\n"),
  22873                          bcm_errmsg(r)));
  22874         }
  22875         BCM_IF_ERROR_RETURN(r);
  22876     }
  22877 
  22878     if (mask & BCM_PORT_ATTR_STP_STATE_MASK) {
  22879         r = bcm_esw_port_stp_get(unit, port, &info->stp_state);
  22880         if (BCM_FAILURE(r)) {
  22881             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22882                         (BSL_META_U(unit,
  22883                                     "bcm_port_stp_get failed:%s\n"), bcm_errmsg(r)));
  22884         }
  22885         BCM_IF_ERROR_RETURN(r);
  22886     }
  22887 
  22888     if (mask & BCM_PORT_ATTR_PFM_MASK) {
  22889         r = bcm_esw_port_pfm_get(unit, port, &info->pfm);
  22890         if (r != BCM_E_UNAVAIL) {
  22891             if (BCM_FAILURE(r)) {
  22892                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  22893                             (BSL_META_U(unit,
  22894                                         "bcm_port_pfm_get failed:%s\n"), bcm_errmsg(r)));
  22895             }
  22896         }
  22897         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  22898     }
  22899 
  22900     if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) {
  22901         r = bcm_esw_port_loopback_get(unit, port, &info->loopback);
  22902         if (BCM_FAILURE(r)) {
  22903             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22904                         (BSL_META_U(unit,
  22905                                     "bcm_port_loopback_get failed:%s\n"), bcm_errmsg(r)));
  22906         }
  22907         BCM_IF_ERROR_RETURN(r);
  22908     }
  22909 
  22910     if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) {
  22911         r = bcm_esw_port_master_get(unit, port, &info->phy_master);
  22912         if (BCM_FAILURE(r)) {
  22913             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22914                         (BSL_META_U(unit,
  22915                                     "bcm_port_master_get failed:%s\n"), bcm_errmsg(r)));
  22916         }
  22917         BCM_IF_ERROR_RETURN(r);
  22918     }
  22919 
  22920     if (mask & BCM_PORT_ATTR_INTERFACE_MASK) {
  22921         r = bcm_esw_port_interface_get(unit, port, &info->interface);
  22922         if (BCM_FAILURE(r)) {
  22923             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22924                         (BSL_META_U(unit,
  22925                                     "bcm_port_interface_get failed:%s\n"), bcm_errmsg(r)));
  22926         }
  22927         BCM_IF_ERROR_RETURN(r);
  22928     }
  22929 
  22930     if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) {
  22931         r = bcm_esw_rate_mcast_get(unit, &info->mcast_limit,
  22932                                    &info->mcast_limit_enable, port);
  22933         if (r == BCM_E_UNAVAIL) {
  22934             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22935         }
  22936         if (BCM_FAILURE(r)) {
  22937             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22938                         (BSL_META_U(unit,
  22939                                     "bcm_rate_mcast_get failed:%s\n"), bcm_errmsg(r)));
  22940         }
  22941         BCM_IF_ERROR_RETURN(r);
  22942     }
  22943 
  22944     if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) {
  22945         r = bcm_esw_rate_bcast_get(unit, &info->bcast_limit,
  22946                                    &info->bcast_limit_enable, port);
  22947         if (r == BCM_E_UNAVAIL) {
  22948             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22949         }
  22950         if (BCM_FAILURE(r)) {
  22951             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22952                         (BSL_META_U(unit,
  22953                                     "bcm_rate_bcast_get failed:%s\n"), bcm_errmsg(r)));
  22954         }
  22955         BCM_IF_ERROR_RETURN(r);
  22956     }
  22957 
  22958     if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) {
  22959         r = bcm_esw_rate_dlfbc_get(unit, &info->dlfbc_limit,
  22960                                    &info->dlfbc_limit_enable, port);
  22961         if (r == BCM_E_UNAVAIL) {
  22962             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22963         }
  22964         if (BCM_FAILURE(r)) {
  22965             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22966                         (BSL_META_U(unit,
  22967                                     "bcm_rate_dlfbc_get failed:%s\n"), bcm_errmsg(r)));
  22968         }
  22969         BCM_IF_ERROR_RETURN(r);
  22970     }
  22971 
  22972     if (mask & BCM_PORT_ATTR_SPEED_MAX_MASK) {
  22973         r = bcm_esw_port_speed_max(unit, port, &info->speed_max);
  22974         if (BCM_FAILURE(r)) {
  22975             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22976                         (BSL_META_U(unit,
  22977                                     "bcm_port_speed_max failed:%s\n"), bcm_errmsg(r)));
  22978         }
  22979         BCM_IF_ERROR_RETURN(r);
  22980     }
  22981 
  22982     if (mask & BCM_PORT_ATTR_ABILITY_MASK) {
  22983         r = bcm_esw_port_ability_local_get(unit, port, &info->port_ability);
  22984         if (BCM_FAILURE(r)) {
  22985             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22986                         (BSL_META_U(unit,
  22987                                     "bcm_port_ability_get failed:%s\n"), bcm_errmsg(r)));
  22988         }
  22989         BCM_IF_ERROR_RETURN(r);
  22990         r = soc_port_ability_to_mode(&info->port_ability,
  22991                                      &info->ability);
  22992         BCM_IF_ERROR_RETURN(r);
  22993     }
  22994 
  22995     if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) {
  22996         r = bcm_esw_port_frame_max_get(unit, port, &info->frame_max);
  22997         if (BCM_FAILURE(r)) {
  22998             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22999                         (BSL_META_U(unit,
  23000                                     "bcm_port_frame_max_get failed:%s\n"), bcm_errmsg(r)));
  23001         }
  23002         BCM_IF_ERROR_RETURN(r);
  23003     }
  23004 
  23005     if (mask & BCM_PORT_ATTR_MDIX_MASK) {
  23006         r = bcm_esw_port_mdix_get(unit, port, &info->mdix);
  23007         if (BCM_FAILURE(r)) {
  23008             LOG_VERBOSE(BSL_LS_BCM_PORT,
  23009                         (BSL_META_U(unit,
  23010                                     "bcm_port_mdix_get failed:%s\n"), bcm_errmsg(r)));
  23011         }
  23012         BCM_IF_ERROR_RETURN(r);
  23013     }
  23014 
  23015     if (mask & BCM_PORT_ATTR_MDIX_STATUS_MASK) {
  23016         r = bcm_esw_port_mdix_status_get(unit, port, &info->mdix_status);
  23017         if (BCM_FAILURE(r)) {
  23018             LOG_VERBOSE(BSL_LS_BCM_PORT,
  23019                         (BSL_META_U(unit,
  23020                                     "bcm_port_mdix_status_get failed:%s\n"), bcm_errmsg(r)));
  23021         }
  23022         BCM_IF_ERROR_RETURN(r);
  23023     }
  23024 
  23025     if (mask & BCM_PORT_ATTR_MEDIUM_MASK) {
  23026         r = bcm_esw_port_medium_get(unit, port, &info->medium);
  23027         if (BCM_FAILURE(r)) {
  23028             LOG_VERBOSE(BSL_LS_BCM_PORT,
  23029                         (BSL_META_U(unit,
  23030                                     "bcm_port_medium_get failed:%s\n"), bcm_errmsg(r)));
  23031         }
  23032         BCM_IF_ERROR_RETURN(r);
  23033     }
  23034 
  23035     if (mask & BCM_PORT_ATTR_FAULT_MASK) {
  23036         r = bcm_esw_port_fault_get(unit, port, &info->fault);
  23037         if (r == BCM_E_PORT) {
  23038             r = BCM_E_NONE;     /* Ignore if not supported on chip/port */
  23039         }
  23040         if (BCM_FAILURE(r)) {
  23041             LOG_VERBOSE(BSL_LS_BCM_PORT,
  23042                         (BSL_META_U(unit,
  23043                                     "bcm_port_fault_get failed:%s\n"), bcm_errmsg(r)));
  23044         }
  23045         BCM_IF_ERROR_RETURN(r);
  23046     }
  23047 
  23048     return BCM_E_NONE;
  23049 }
  23050 
  23051 /*
  23052  * Function:
  23053  *      bcm_port_selective_set
  23054  * Purpose:
  23055  *      Set requested port parameters
  23056  * Parameters:
  23057  *      unit - switch unit
  23058  *      port - switch port
  23059  *      info - port information structure
  23060  * Returns:
  23061  *      BCM_E_NONE
  23062  *      BCM_E_XXX
  23063  * Notes:
  23064  *      Does not set spanning tree state.
  23065  */
  23066 
  23067 int
  23068 bcm_esw_port_selective_set(int unit, bcm_port_t port, bcm_port_info_t *info)
  23069 {
  23070     int                 r;
  23071     uint32              mask;
  23072     int                 flags = 0;
  23073     soc_info_t          *si;
  23074 
  23075     if (!(si = &SOC_INFO(unit))) {
  23076         return SOC_E_INTERNAL;
  23077     }
  23078 
  23079     LOG_INFO(BSL_LS_BCM_PORT,
  23080              (BSL_META_U(unit,
  23081                          "bcm_port_selective_set: u=%d p=%d\n"), unit, port));
  23082 
  23083     /* Make sure port module is initialized. */
  23084     PORT_INIT(unit);
  23085     if (!BCM_GPORT_IS_SET(port)) {
  23086         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {
  23087             return BCM_E_PORT;
  23088         }
  23089     }
  23090 
  23091     if(bcm_common_oamp_port_enable_get(unit, port)) {
  23092         LOG_ERROR(BSL_LS_BCM_PORT,
  23093                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  23094                    port));
  23095         return BCM_E_PARAM;
  23096     }
  23097 
  23098     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  23099 
  23100     mask = info->action_mask;
  23101 
  23102     /* PM8x50 does not support these things, so do not try to fetch them */
  23103     if (IS_CD_PORT(unit, port)) {
  23104         mask &= ~BCM_PORT_ATTR_ABILITY_MASK;
  23105         mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  23106         mask &= ~BCM_PORT_ATTR_INTERFACE_MASK;
  23107     }
  23108 
  23109     if (mask & BCM_PORT_ATTR_ENCAP_MASK) {
  23110         if (info->encap_mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  23111             /* HGOE mode valid only for TD3 fabric */
  23112 #ifdef BCM_TRIDENT3_SUPPORT
  23113             if (SOC_IS_TRIDENT3X(unit) &&
  23114                  soc_feature(unit, soc_feature_higig_over_ethernet)) {
  23115                 bcm_port_encap_config_t config;
  23116                 config.encap = info->encap_mode;
  23117                 BCM_IF_ERROR_RETURN(
  23118                     bcm_esw_port_encap_config_set(unit, port, &config));
  23119             } else
  23120 #endif
  23121             {
  23122                 return BCM_E_PARAM;
  23123             }
  23124         } else {
  23125 
  23126             BCM_IF_ERROR_RETURN
  23127                 (bcmi_esw_port_encap_validate(unit, port, info->encap_mode,
  23128                             ((mask & BCM_PORT_ATTR_SPEED_MASK) ? info->speed : 0)));
  23129             r = _bcm_esw_port_encap_set(unit, port, info->encap_mode);
  23130             if (BCM_FAILURE(r)) {
  23131                 LOG_ERROR(BSL_LS_BCM_PORT,
  23132                             (BSL_META_U(unit,
  23133                                         "bcm_port_encap_set failed:%s\n"), bcm_errmsg(r)));
  23134             }
  23135             BCM_IF_ERROR_RETURN(r);
  23136         }
  23137     }
  23138 
  23139     if (mask & BCM_PORT_ATTR_ENABLE_MASK) {
  23140         r = bcm_esw_port_enable_set(unit, port, info->enable);
  23141         if (BCM_FAILURE(r)) {
  23142             LOG_ERROR(BSL_LS_BCM_PORT,
  23143                         (BSL_META_U(unit,
  23144                                     "bcm_port_enable_set failed:%s\n"), bcm_errmsg(r)));
  23145         }
  23146         BCM_IF_ERROR_RETURN(r);
  23147     }
  23148 
  23149     if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) {
  23150         r = bcm_esw_port_pause_addr_set(unit, port, info->pause_mac);
  23151         if (BCM_FAILURE(r)) {
  23152             LOG_ERROR(BSL_LS_BCM_PORT,
  23153                         (BSL_META_U(unit,
  23154                                     "bcm_port_pause_addr_set failed:%s\n"), bcm_errmsg(r)));
  23155         }
  23156         BCM_IF_ERROR_RETURN(r);
  23157     }
  23158 
  23159     if (mask & BCM_PORT_ATTR_INTERFACE_MASK) {
  23160         r = bcm_esw_port_interface_set(unit, port, info->interface);
  23161         if (BCM_FAILURE(r)) {
  23162             LOG_ERROR(BSL_LS_BCM_PORT,
  23163                         (BSL_META_U(unit,
  23164                                     "bcm_port_interface_set failed:%s\n"), bcm_errmsg(r)));
  23165         }
  23166         BCM_IF_ERROR_RETURN(r);
  23167     }
  23168 
  23169     if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) {
  23170         r = bcm_esw_port_master_set(unit, port, info->phy_master);
  23171         if (r != BCM_E_UNAVAIL) {
  23172             if (BCM_FAILURE(r)) {
  23173                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  23174                             (BSL_META_U(unit,
  23175                                         "bcm_port_master_set failed:%s\n"), bcm_errmsg(r)));
  23176             }
  23177         }
  23178         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  23179     }
  23180 
  23181     if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) {
  23182         r = bcm_esw_port_linkscan_set(unit, port, info->linkscan);
  23183         if (BCM_FAILURE(r)) {
  23184             LOG_ERROR(BSL_LS_BCM_PORT,
  23185                         (BSL_META_U(unit,
  23186                                     "bcm_port_linkscan_set failed:%s\n"), bcm_errmsg(r)));
  23187         }
  23188         BCM_IF_ERROR_RETURN(r);
  23189     }
  23190 
  23191     if (mask & BCM_PORT_ATTR_LEARN_MASK) {
  23192         r = bcm_esw_port_learn_set(unit, port, info->learn);
  23193         if (BCM_FAILURE(r)) {
  23194             LOG_ERROR(BSL_LS_BCM_PORT,
  23195                         (BSL_META_U(unit,
  23196                                     "bcm_port_learn_set failed:%s\n"), bcm_errmsg(r)));
  23197         }
  23198         BCM_IF_ERROR_RETURN(r);
  23199     }
  23200 
  23201     if (mask & BCM_PORT_ATTR_DISCARD_MASK) {
  23202         r = bcm_esw_port_discard_set(unit, port, info->discard);
  23203         if (BCM_FAILURE(r)) {
  23204             LOG_ERROR(BSL_LS_BCM_PORT,
  23205                         (BSL_META_U(unit,
  23206                                     "bcm_port_discard_set failed:%s\n"), bcm_errmsg(r)));
  23207         }
  23208         BCM_IF_ERROR_RETURN(r);
  23209     }
  23210 
  23211     if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) {
  23212         r = bcm_esw_port_vlan_member_set(unit, port, info->vlanfilter);
  23213         if (BCM_FAILURE(r)) {
  23214             LOG_ERROR(BSL_LS_BCM_PORT,
  23215                         (BSL_META_U(unit,
  23216                                     "bcm_esw_port_vlan_member_set failed:%s\n"),
  23217                          bcm_errmsg(r)));
  23218         }
  23219         BCM_IF_ERROR_RETURN(r);
  23220     }
  23221 
  23222     if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) {
  23223         r = bcm_esw_port_untagged_priority_set(unit, port,
  23224                                                info->untagged_priority);
  23225         if (BCM_FAILURE(r)) {
  23226             LOG_ERROR(BSL_LS_BCM_PORT,
  23227                         (BSL_META_U(unit,
  23228                                     "bcm_port_untagged_priority_set failed:%s\n"),
  23229                          bcm_errmsg(r)));
  23230         }
  23231         BCM_IF_ERROR_RETURN(r);
  23232     }
  23233 
  23234     if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) {
  23235         r = bcm_esw_port_untagged_vlan_set(unit, port, info->untagged_vlan);
  23236         if (BCM_FAILURE(r)) {
  23237             LOG_ERROR(BSL_LS_BCM_PORT,
  23238                         (BSL_META_U(unit,
  23239                                     "bcm_port_untagged_vlan_set (%d) failed: %s\n"),
  23240                          info->untagged_vlan, bcm_errmsg(r)));
  23241         }
  23242         BCM_IF_ERROR_RETURN(r);
  23243     }
  23244 
  23245     if (mask & BCM_PORT_ATTR_PFM_MASK) {
  23246         r = bcm_esw_port_pfm_set(unit, port, info->pfm);
  23247         if (r != BCM_E_UNAVAIL) {
  23248             if (BCM_FAILURE(r)) {
  23249                 LOG_ERROR(BSL_LS_BCM_PORT,
  23250                             (BSL_META_U(unit,
  23251                                         "bcm_port_pfm_set failed:%s\n"), bcm_errmsg(r)));
  23252             }
  23253         }
  23254         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  23255     }
  23256 
  23257     /*
  23258      * Set loopback mode before setting the speed/duplex, since it may
  23259      * affect the allowable values for speed/duplex.
  23260      */
  23261 
  23262     if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) {
  23263         r = bcm_esw_port_loopback_set(unit, port, info->loopback);
  23264         if (BCM_FAILURE(r)) {
  23265             LOG_ERROR(BSL_LS_BCM_PORT,
  23266                         (BSL_META_U(unit,
  23267                                     "bcm_port_loopback_set failed:%s\n"), bcm_errmsg(r)));
  23268         }
  23269         BCM_IF_ERROR_RETURN(r);
  23270     }
  23271 
  23272     if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) {
  23273         if (info->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) {
  23274             r = bcm_esw_port_ability_advert_set(unit, port,
  23275                                                 &(info->local_ability));
  23276             if (BCM_FAILURE(r)) {
  23277                 LOG_ERROR(BSL_LS_BCM_PORT,
  23278                             (BSL_META_U(unit,
  23279                                         "bcm_port_ability_advert_set failed: %s\n"),
  23280                              bcm_errmsg(r)));
  23281             }
  23282             BCM_IF_ERROR_RETURN(r);
  23283         } else {
  23284             r = bcm_esw_port_advert_set(unit, port, info->local_advert);
  23285             if (BCM_FAILURE(r)) {
  23286                 LOG_ERROR(BSL_LS_BCM_PORT,
  23287                             (BSL_META_U(unit,
  23288                                         "bcm_port_advert_set failed: (0x%x): %s\n"),
  23289                              info->local_advert, bcm_errmsg(r)));
  23290             }
  23291             BCM_IF_ERROR_RETURN(r);
  23292         }
  23293     }
  23294 
  23295     if (mask & BCM_PORT_ATTR_AUTONEG_MASK) {
  23296 #if defined(BCM_TOMAHAWK_SUPPORT)
  23297         if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) && IS_CL_PORT(unit, port)) {
  23298             int speed = si->port_init_speed[port];
  23299             if (1000 == speed) {    /* 1G ports do not support autoneg, force off */
  23300                 info->autoneg = 0;
  23301             }
  23302         }
  23303 #endif
  23304         r = bcm_esw_port_autoneg_set(unit, port, info->autoneg);
  23305         if (BCM_FAILURE(r)) {
  23306             LOG_ERROR(BSL_LS_BCM_PORT,
  23307                         (BSL_META_U(unit,
  23308                                     "bcm_port_autoneg_set failed:%s\n"), bcm_errmsg(r)));
  23309         }
  23310         BCM_IF_ERROR_RETURN(r);
  23311     }
  23312 
  23313     if (mask & BCM_PORT_ATTR_SPEED_MASK) {
  23314         /*When AN=on, speed will be auto-detected. Hence don't set*/
  23315         if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) {
  23316             r = BCM_E_PARAM;
  23317             if (BCM_FAILURE(r)) {
  23318                 LOG_ERROR(BSL_LS_BCM_PORT,
  23319                          (BSL_META_U(unit,
  23320                           "Autoneg:On. SPEED will be "
  23321                            "auto-detected :%s\n"), bcm_errmsg(r)));
  23322             }
  23323             BCM_IF_ERROR_RETURN(r);
  23324         }
  23325 #ifdef BCM_TOMAHAWK3_SUPPORT
  23326         if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) {
  23327             bcm_port_resource_t pr;
  23328             r = bcm_esw_port_resource_get(unit, port, &pr);
  23329             BCM_IF_ERROR_RETURN(r);
  23330             if (pr.speed != info->speed) {
  23331                 LOG_INFO(BSL_LS_BCM_PORT,
  23332                          (BSL_META_U(unit,
  23333                           "Warning: bcm_port_info speed (%d) does NOT match "
  23334                           " current speed (%d). May have fec/link training/"
  23335                           "phy lane config mismatches!\n"),
  23336                           pr.speed, info->speed));
  23337             }
  23338             pr.speed = info->speed;
  23339             r = bcm_esw_port_resource_speed_set(unit, port, &pr);
  23340             BCM_IF_ERROR_RETURN(r);
  23341         } else
  23342 #endif
  23343         {
  23344         r = bcm_esw_port_speed_set(unit, port, info->speed);
  23345         }
  23346         if (BCM_FAILURE(r)) {
  23347             LOG_ERROR(BSL_LS_BCM_PORT,
  23348                         (BSL_META_U(unit,
  23349                                     "bcm_port_speed_set failed:%s\n"), bcm_errmsg(r)));
  23350         }
  23351         BCM_IF_ERROR_RETURN(r);
  23352     }
  23353 
  23354     if (mask & BCM_PORT_ATTR_DUPLEX_MASK) {
  23355         /*When AN=on, then duplex method will be auto-detected, hence don't set*/
  23356         if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) {
  23357             r = BCM_E_PARAM;
  23358             if (BCM_FAILURE(r)) {
  23359                 LOG_ERROR(BSL_LS_BCM_PORT,
  23360                          (BSL_META_U(unit,
  23361                           "Autoneg:On. DUPLEX should be "
  23362                            "auto-detected :%s\n"), bcm_errmsg(r)));
  23363             }
  23364             BCM_IF_ERROR_RETURN(r);
  23365         }
  23366         r = bcm_esw_port_duplex_set(unit, port, info->duplex);
  23367         if (BCM_FAILURE(r)) {
  23368             LOG_ERROR(BSL_LS_BCM_PORT,
  23369                         (BSL_META_U(unit,
  23370                                     "bcm_port_duplex_set failed:%s\n"), bcm_errmsg(r)));
  23371         }
  23372         BCM_IF_ERROR_RETURN(r);
  23373     }
  23374 
  23375     if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK |
  23376                 BCM_PORT_ATTR_PAUSE_RX_MASK)) {
  23377         int     tpause, rpause;
  23378 
  23379         tpause = rpause = -1;
  23380         if (mask & BCM_PORT_ATTR_PAUSE_TX_MASK) {
  23381             tpause = info->pause_tx;
  23382         }
  23383         if (mask & BCM_PORT_ATTR_PAUSE_RX_MASK) {
  23384             rpause = info->pause_rx;
  23385         }
  23386         r = bcm_esw_port_pause_set(unit, port, tpause, rpause);
  23387         if (BCM_FAILURE(r)) {
  23388             LOG_ERROR(BSL_LS_BCM_PORT,
  23389                         (BSL_META_U(unit,
  23390                                     "bcm_port_pause_set failed:%s\n"), bcm_errmsg(r)));
  23391         }
  23392         BCM_IF_ERROR_RETURN(r);
  23393     }
  23394 
  23395     if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) {
  23396         flags = (info->mcast_limit_enable) ? BCM_RATE_MCAST : 0;
  23397         r = bcm_esw_rate_mcast_set(unit, info->mcast_limit, flags, port);
  23398         if (r == BCM_E_UNAVAIL) {
  23399             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  23400         }
  23401         if (BCM_FAILURE(r)) {
  23402             LOG_ERROR(BSL_LS_BCM_PORT,
  23403                         (BSL_META_U(unit,
  23404                                     "bcm_rate_mcast_port_set failed:%s\n"), bcm_errmsg(r)));
  23405         }
  23406         BCM_IF_ERROR_RETURN(r);
  23407     }
  23408 
  23409     if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) {
  23410         flags = (info->bcast_limit_enable) ? BCM_RATE_BCAST : 0;
  23411         r = bcm_esw_rate_bcast_set(unit, info->bcast_limit, flags, port);
  23412         if (r == BCM_E_UNAVAIL) {
  23413             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  23414         }
  23415         if (BCM_FAILURE(r)) {
  23416             LOG_ERROR(BSL_LS_BCM_PORT,
  23417                         (BSL_META_U(unit,
  23418                                     "bcm_rate_bcast_port_set failed:%s\n"), bcm_errmsg(r)));
  23419         }
  23420         BCM_IF_ERROR_RETURN(r);
  23421     }
  23422 
  23423     if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) {
  23424         flags = (info->dlfbc_limit_enable) ? BCM_RATE_DLF : 0;
  23425         r = bcm_esw_rate_dlfbc_set(unit, info->dlfbc_limit, flags, port);
  23426         if (r == BCM_E_UNAVAIL) {
  23427             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  23428         }
  23429         if (BCM_FAILURE(r)) {
  23430             LOG_ERROR(BSL_LS_BCM_PORT,
  23431                         (BSL_META_U(unit,
  23432                                     "bcm_rate_dlfbcast_port_set failed:%s\n"),
  23433                          bcm_errmsg(r)));
  23434         }
  23435         BCM_IF_ERROR_RETURN(r);
  23436     }
  23437 
  23438     if (mask & BCM_PORT_ATTR_STP_STATE_MASK) {
  23439         r = bcm_esw_port_stp_set(unit, port, info->stp_state);
  23440         if (BCM_FAILURE(r)) {
  23441             LOG_ERROR(BSL_LS_BCM_PORT,
  23442                         (BSL_META_U(unit,
  23443                                     "bcm_port_stp_set failed:%s\n"), bcm_errmsg(r)));
  23444         }
  23445         BCM_IF_ERROR_RETURN(r);
  23446     }
  23447 
  23448     if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) {
  23449         r = bcm_esw_port_frame_max_set(unit, port, info->frame_max);
  23450         if (BCM_FAILURE(r)) {
  23451             LOG_ERROR(BSL_LS_BCM_PORT,
  23452                         (BSL_META_U(unit,
  23453                                     "bcm_port_frame_max_set failed:%s\n"), bcm_errmsg(r)));
  23454         }
  23455         BCM_IF_ERROR_RETURN(r);
  23456     }
  23457 
  23458     if (mask & BCM_PORT_ATTR_MDIX_MASK) {
  23459         r = bcm_esw_port_mdix_set(unit, port, info->mdix);
  23460         if (BCM_FAILURE(r)) {
  23461             LOG_ERROR(BSL_LS_BCM_PORT,
  23462                         (BSL_META_U(unit,
  23463                                     "bcm_port_mdix_set failed:%s\n"), bcm_errmsg(r)));
  23464         }
  23465         BCM_IF_ERROR_RETURN(r);
  23466     }
  23467 
  23468     return BCM_E_NONE;
  23469 }
  23470 
  23471 /*
  23472  * Function:
  23473  *      bcm_port_info_get
  23474  * Purpose:
  23475  *      Get all information on the port
  23476  * Parameters:
  23477  *      unit - StrataSwitch unit #
  23478  *      port - StrataSwitch port #
  23479  *      info - Pointer to structure in which to save values
  23480  * Returns:
  23481  *      BCM_E_XXX
  23482  */
  23483 
  23484 int
  23485 bcm_esw_port_info_get(int unit, bcm_port_t port, bcm_port_info_t *info)
  23486 {
  23487     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  23488 
  23489     /* Make sure port module is initialized. */
  23490     PORT_INIT(unit);
  23491 
  23492     bcm_port_info_t_init(info);
  23493 
  23494     if (IS_ST_PORT(unit, port)) {
  23495         info->action_mask = BCM_PORT_HERC_ATTRS;
  23496         if (SOC_IS_XGS_SWITCH(unit)) {
  23497             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK |
  23498                                  BCM_PORT_ATTR_DISCARD_MASK |
  23499                                  BCM_PORT_ATTR_LEARN_MASK;
  23500         }
  23501     } else {
  23502         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  23503     }
  23504 
  23505     return bcm_esw_port_selective_get(unit, port, info);
  23506 }
  23507 
  23508 /*
  23509  * Function:
  23510  *      bcm_port_info_set
  23511  * Purpose:
  23512  *      Set all information on the port
  23513  * Parameters:
  23514  *      unit - StrataSwitch unit #
  23515  *      port - StrataSwitch port #
  23516  *      info - Pointer to structure in which to save values
  23517  * Returns:
  23518  *      BCM_E_XXX
  23519  * Notes:
  23520  *      Checks if AN is on, and if so, clears the
  23521  *      proper bits in the action mask.
  23522  */
  23523 
  23524 int
  23525 bcm_esw_port_info_set(int unit, bcm_port_t port, bcm_port_info_t *info)
  23526 {
  23527     /* Make sure port module is initialized. */
  23528     PORT_INIT(unit);
  23529 
  23530     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  23531 
  23532     if (IS_ST_PORT(unit, port)) {
  23533         info->action_mask = BCM_PORT_HERC_ATTRS;
  23534         if (SOC_IS_XGS_SWITCH(unit)) {
  23535             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK |
  23536                                  BCM_PORT_ATTR_DISCARD_MASK |
  23537                                  BCM_PORT_ATTR_LEARN_MASK;
  23538         }
  23539     } else {
  23540         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  23541     }
  23542 
  23543     /* If autoneg is set, remove those attributes controlled by it */
  23544     if (info->autoneg) {
  23545         info->action_mask &= ~BCM_PORT_AN_ATTRS;
  23546     }
  23547 
  23548     return bcm_esw_port_selective_set(unit, port, info);
  23549 }
  23550 
  23551 /*
  23552  * Function:
  23553  *      bcm_port_info_save
  23554  * Purpose:
  23555  *      Save the current settings of a port
  23556  * Parameters:
  23557  *      unit - StrataSwitch unit #
  23558  *      port - StrataSwitch port #
  23559  *      info - Pointer to structure in which to save values
  23560  * Returns:
  23561  *      BCM_E_XXX
  23562  * Notes:
  23563  *      The action_mask will be adjusted so that the
  23564  *      proper values will be set when a restore is made.
  23565  *      This mask should not be altered between these calls.
  23566  */
  23567 
  23568 int
  23569 bcm_esw_port_info_save(int unit, bcm_port_t port, bcm_port_info_t *info)
  23570 {
  23571     /* Make sure port module is initialized. */
  23572     PORT_INIT(unit);
  23573 
  23574     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  23575 
  23576     if (IS_ST_PORT(unit, port)) {
  23577         info->action_mask = BCM_PORT_HERC_ATTRS;
  23578         if (SOC_IS_XGS_SWITCH(unit)) {
  23579             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK;
  23580         }
  23581 #ifdef BCM_GXPORT_SUPPORT
  23582         if (IS_GX_PORT(unit, port)) {
  23583             info->action_mask |= BCM_PORT_ATTR_AUTONEG_MASK;
  23584         }
  23585 #endif
  23586     } else {
  23587         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  23588     }
  23589     info->action_mask2 = BCM_PORT_ATTR2_PORT_ABILITY;
  23590 
  23591     BCM_IF_ERROR_RETURN(bcm_esw_port_selective_get(unit, port, info));
  23592 
  23593     if (info->autoneg) {
  23594         info->action_mask &= ~BCM_PORT_AN_ATTRS;
  23595     }
  23596 
  23597     return BCM_E_NONE;
  23598 }
  23599 
  23600 /*
  23601  * Function:
  23602  *      bcm_port_info_restore
  23603  * Purpose:
  23604  *      Restore port settings saved by info_save
  23605  * Parameters:
  23606  *      unit - StrataSwitch unit #
  23607  *      port - StrataSwitch port #
  23608  *      info - Pointer to structure with info from port_info_save
  23609  * Returns:
  23610  *      BCM_E_XXX
  23611  * Notes:
  23612  *      bcm_port_info_save has done all the work.
  23613  *      We just call port_selective_set.
  23614  */
  23615 
  23616 int
  23617 bcm_esw_port_info_restore(int unit, bcm_port_t port, bcm_port_info_t *info)
  23618 {
  23619     /* Make sure port module is initialized. */
  23620     PORT_INIT(unit);
  23621 
  23622     return bcm_esw_port_selective_set(unit, port, info);
  23623 }
  23624 
  23625 /*
  23626  * Function:
  23627  *      bcm_port_phy_drv_name_get
  23628  * Purpose:
  23629  *      Return the name of the PHY driver being used on a port.
  23630  * Parameters:
  23631  *      unit - StrataSwitch unit #
  23632  *      port - StrataSwitch port #
  23633  * Returns:
  23634  *      Pointer to static string
  23635  */
  23636 int
  23637 bcm_esw_port_phy_drv_name_get(int unit, bcm_port_t port, char *name, int len)
  23638 {
  23639     int str_len;
  23640 
  23641     /* Make sure port module is initialized. */
  23642     PORT_INIT(unit);
  23643 
  23644     if(bcm_common_oamp_port_enable_get(unit, port)) {
  23645         LOG_ERROR(BSL_LS_BCM_PORT,
  23646                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  23647                    port));
  23648         return BCM_E_PARAM;
  23649     }
  23650 
  23651     /* Call Port Control module */
  23652     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  23653         return bcmi_esw_portctrl_phy_drv_name_get(unit, port, name, len);
  23654     }
  23655 
  23656     if (bcm_port_info[unit] == NULL) {
  23657         str_len = sal_strlen("driver not initialized");
  23658         if (str_len <= len) {
  23659             sal_strlcpy(name, "driver not initialized", len);
  23660         }
  23661         return BCM_E_INIT;
  23662     }
  23663     if (!SOC_PORT_VALID(unit, port)) {
  23664         str_len = sal_strlen("invalid port");
  23665         if (str_len <= len) {
  23666             sal_strlcpy(name, "invalid port", len);
  23667         }
  23668         return BCM_E_PORT;
  23669     }
  23670     return (soc_phyctrl_drv_name_get(unit, port, name, len));
  23671 }
  23672 
  23673 /*
  23674  * Function:
  23675  *      _bcm_port_encap_xport_set
  23676  * Purpose:
  23677  *      Convert 10G Ether port to Higig port, or reverse
  23678  * Notes;
  23679  *      Must be called with PORT_LOCK held.
  23680  */
  23681 
  23682 int
  23683 _bcm_port_encap_xport_set(int unit, bcm_port_t port, int mode,
  23684                           int update_port_mode)
  23685 {
  23686 #ifdef BCM_FIREBOLT_SUPPORT
  23687     bcm_stg_t        stg;
  23688     int              to_higig;
  23689     soc_field_t      port_type_field;
  23690     soc_reg_t        egr_port_reg;
  23691     soc_port_ability_t ability;
  23692     soc_port_mode_t  non_ieee_speed;
  23693     int              an, an_done, force_speed, port_type;
  23694     uint32           entry[SOC_MAX_MEM_WORDS];
  23695 #ifdef BCM_TRIDENT2_SUPPORT
  23696     int              config_speed = 0;
  23697 #endif
  23698 #if defined(BCM_KATANA2_SUPPORT)
  23699     int speed = 0;
  23700     bcmMxqPhyPortMode_t phy_mode;
  23701 #endif
  23702 int              enable = 0;
  23703 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  23704     uint32 rval = 0;
  23705     uint32 mtu = 0;
  23706     soc_info_t       *si = &SOC_INFO(unit);
  23707 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  23708 
  23709     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  23710         return bcmi_esw_portctrl_encap_xport_set(unit, port, mode);
  23711     }
  23712 
  23713     to_higig = (mode != BCM_PORT_ENCAP_IEEE);
  23714     port_type_field = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  23715                        SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  23716                        SOC_IS_HURRICANEX(unit) || SOC_IS_TD_TT(unit) ||
  23717                        SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)||
  23718                        SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) ?
  23719                        PORT_TYPEf : HIGIG_PACKETf;
  23720     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  23721                     SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  23722                     SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  23723                     EGR_PORT_64r : EGR_PORTr;
  23724 
  23725 #if defined(BCM_KATANA2_SUPPORT)
  23726     if (to_higig && SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit) &&
  23727             update_port_mode) {
  23728         /*
  23729          * Updating the phy_mode according to the port encap type.
  23730          * Using 13G as default speed for higig since the underlying routine
  23731          * do not differentiate on higig speeds.
  23732          */
  23733         SOC_IF_ERROR_RETURN
  23734             (soc_katana2_get_phy_port_mode(unit, port, 13000, &phy_mode));
  23735     }
  23736 #endif
  23737     SOC_IF_ERROR_RETURN
  23738         (MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode));
  23739 
  23740     if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  23741         if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  23742             SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  23743         } else {
  23744             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  23745         }
  23746     }
  23747     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  23748         if ((mode == BCM_PORT_ENCAP_HIGIG2_LITE) && IS_ST_PORT(unit, port)) {
  23749             /*KT2: HL port is treated as GE port too*/
  23750             SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  23751             SOC_PBMP_PORT_ADD(SOC_INFO(unit).ge.bitmap, port);
  23752         } else if ((mode == BCM_PORT_ENCAP_IEEE) && IS_XE_PORT(unit,port)) {
  23753             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  23754             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).ge.bitmap, port);
  23755         }
  23756         soc_dport_map_update(unit);
  23757     }
  23758     /*
  23759      * MAC_ENCAP_SET() would change the ING_MTU to defalut value.
  23760      * So also change EGR_MTU to default value manually.
  23761      */
  23762 #ifdef BCM_SHADOW_SUPPORT
  23763     if (SOC_IS_SHADOW(unit)) {
  23764         mtu = (1 << soc_reg_field_length(unit, EGR_L2_MTUr, VALUEf)) - 1;
  23765         soc_reg_field_set(unit, EGR_L2_MTUr, &rval,
  23766                           VALUEf, mtu);
  23767         SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval));
  23768     } else
  23769 #endif /* BCM_SHADOW_SUPPORT */
  23770 
  23771 #ifdef BCM_XGS3_SWITCH_SUPPORT
  23772     if (SOC_IS_XGS3_SWITCH(unit)) {
  23773         soc_reg_t reg;
  23774         soc_mem_t mem;
  23775         uint32 field_val_clear = 0;
  23776 
  23777         if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  23778             mem = EGR_MTUm;
  23779             mtu = si->max_mtu;
  23780             if (soc_feature(unit, soc_feature_egr_all_profile)) {
  23781                 BCM_IF_ERROR_RETURN(
  23782                     bcm_esw_port_egr_lport_field_set(unit, port, mem,
  23783                     MTU_SIZEf, mtu));
  23784             } else {
  23785                 SOC_IF_ERROR_RETURN(
  23786                     soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, entry));
  23787                 soc_mem_field_set(unit, mem, entry, MTU_SIZEf, &mtu);
  23788                 if (soc_mem_field_valid(unit, mem, MTU_ENABLEf)) {
  23789                 soc_mem_field_set(unit, mem, entry, MTU_ENABLEf,
  23790                                   &field_val_clear);
  23791                 }
  23792                 SOC_IF_ERROR_RETURN(
  23793                     soc_mem_write(unit, mem, MEM_BLOCK_ANY, port, entry));
  23794             }
  23795         } else {
  23796             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  23797             mtu = si->max_mtu;
  23798             soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu);
  23799             if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) {
  23800                 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 0);
  23801             }
  23802             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  23803         }
  23804     }
  23805 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  23806 
  23807     if (!to_higig) {
  23808         SOC_IF_ERROR_RETURN
  23809             (MAC_INTERFACE_SET(PORT(unit, port).p_mac,
  23810                                unit, port, SOC_PORT_IF_XGMII));
  23811     }
  23812 
  23813     /* Sepcific for GH on avoiding port speed change */
  23814     if (!soc_feature(unit, soc_feature_hg_no_speed_change)) {
  23815         BCM_IF_ERROR_RETURN
  23816                 (bcm_esw_port_ability_local_get(unit, port, &ability));
  23817 
  23818         non_ieee_speed = ability.speed_full_duplex &
  23819                 ~(SOC_PA_SPEED_100GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_10GB |
  23820                   SOC_PA_SPEED_2500MB | SOC_PA_SPEED_1000MB | SOC_PA_SPEED_100MB |
  23821                   SOC_PA_SPEED_10MB);
  23822 
  23823         BCM_IF_ERROR_RETURN
  23824                 (bcm_esw_port_ability_advert_get(unit, port, &ability));
  23825         if (to_higig) {
  23826             ability.speed_full_duplex |= non_ieee_speed;
  23827             ability.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM);
  23828             /* Retrieving the max speed */
  23829             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, port, &force_speed));
  23830             force_speed = force_speed == 0 ?
  23831                     SOC_CONTROL(unit)->info.port_speed_max[port] : force_speed;
  23832 
  23833 #ifdef BCM_TRIDENT2_SUPPORT
  23834             if (SOC_IS_TRIDENT2(unit) &&
  23835                 soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0) &&
  23836                 (si->port_num_lanes[port] != 4)) {
  23837                 config_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, force_speed);
  23838                 force_speed = (force_speed > config_speed) ? config_speed : force_speed;
  23839             }
  23840 #endif
  23841 
  23842             ability.speed_full_duplex |= SOC_PA_SPEED(force_speed);
  23843         } else {
  23844             ability.speed_full_duplex &= ~non_ieee_speed;
  23845             force_speed = IS_GE_PORT(unit , port) ? 1000 : IS_CE_PORT(unit , port) ?
  23846                 100000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 40000 ?
  23847                 40000 :  SOC_CONTROL(unit)->info.port_speed_max[port] >= 10000 ?
  23848                 10000 : 1000;
  23849 #if defined(BCM_KATANA2_SUPPORT)
  23850             /* For Katana2 Warpcore the xlport_mode_reg. The phy_port_mode value
  23851             * differs when speed is 1000 vs 2500.
  23852             * GE port does not necessarily have 1000 speed always.
  23853             * The VCO frequency can change ased on phy_port_mode,
  23854             * core_port_mode and number of lanes on Warpcore.
  23855             * The lower layer Warpcore driver relies on these values.
  23856             * So we need to set the correct forced speed for the port */
  23857             if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && force_speed == 1000) {
  23858                 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  23859                 force_speed = (speed == 2500) ? speed : force_speed;
  23860             }
  23861 #endif
  23862         }
  23863 
  23864     BCM_IF_ERROR_RETURN
  23865         (bcm_esw_port_ability_advert_set(unit, port, &ability));
  23866 
  23867 #ifdef BCM_KATANA2_SUPPORT
  23868 #ifdef BCM_METROLITE_SUPPORT
  23869     if (SOC_IS_METROLITE(unit)) {
  23870        BCM_IF_ERROR_RETURN
  23871               (_bcm_ml_update_port_mode(unit, port, force_speed));
  23872 
  23873         if (IS_XL_PORT(unit,port) &&
  23874             ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) {
  23875             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23876             SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac,
  23877                                   unit, port, force_speed));
  23878         }
  23879     } else
  23880 #endif
  23881 
  23882 #ifdef BCM_SABER2_SUPPORT
  23883     if (SOC_IS_SABER2(unit)) {
  23884        BCM_IF_ERROR_RETURN
  23885               (_bcm_sb2_update_port_mode(unit, port, force_speed));
  23886 
  23887         if (IS_XL_PORT(unit,port) &&
  23888             ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) {
  23889             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23890             SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac,
  23891                                   unit, port, force_speed));
  23892         }
  23893     } else
  23894 #endif
  23895         if(SOC_IS_KATANA2(unit) && update_port_mode) {
  23896             BCM_IF_ERROR_RETURN
  23897                 (_bcm_kt2_update_port_mode(unit, port, force_speed));
  23898         }
  23899 #endif
  23900         SOC_IF_ERROR_RETURN
  23901                 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  23902         /* some phy driver will enable the port no matter previous port
  23903          * state while executing speed_set or autoneg_set. So we need to
  23904          * get the port state before speed_set or autoneg_set, and set it
  23905          * back after speed_set or autoneg_set. So that it can keep the
  23906          * same port state before after speed_set or autoneg_set*/
  23907         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  23908 
  23909         /* Some mac driver re-init phy while executing MAC_ENCAP_SET, in that case
  23910          * autoneg is probably always true here */
  23911         if (an) {
  23912             SOC_IF_ERROR_RETURN(bcm_esw_port_autoneg_set(unit, port, TRUE));
  23913         } else {
  23914             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23915         }
  23916         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable));
  23917     }
  23918 
  23919     /* Now we propagate the changes */
  23920     port_type = to_higig ? 1 : 0;
  23921     if (soc_mem_field_valid(unit, PORT_TABm, port_type_field)) {
  23922         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(
  23923                             unit, PORT_TABm, port, port_type_field, port_type));
  23924     }
  23925     if (SOC_MEM_IS_VALID(unit, EGR_PORTm)) {
  23926         if (soc_mem_field_valid(unit, EGR_PORTm, port_type_field)) {
  23927             SOC_IF_ERROR_RETURN
  23928                 (soc_mem_field32_modify(unit, EGR_PORTm, port, port_type_field,
  23929                                         port_type));
  23930         }
  23931     } else {
  23932         SOC_IF_ERROR_RETURN
  23933             (soc_reg_field32_modify(unit, egr_port_reg, port, port_type_field,
  23934                                     port_type));
  23935     }
  23936 
  23937     if (SOC_MEM_IS_VALID(unit, EGR_ING_PORTm)) {
  23938         if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) {
  23939             SOC_IF_ERROR_RETURN
  23940                 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf,
  23941                                         mode == BCM_PORT_ENCAP_IEEE ? 0 : 1));
  23942         }
  23943     }
  23944 
  23945     
  23946     if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  23947         icontrol_opcode_bitmap_entry_t entry;
  23948         soc_pbmp_t pbmp;
  23949 
  23950         SOC_IF_ERROR_RETURN
  23951             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23952         SOC_PBMP_CLEAR(pbmp);
  23953         if (to_higig) {
  23954             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  23955         }
  23956         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  23957                                BITMAPf, &pbmp);
  23958         SOC_IF_ERROR_RETURN
  23959             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23960     } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  23961         SOC_IS_VALKYRIE2(unit)) {
  23962         uint64 cpu_pbm64;
  23963         uint64 rval64;      /* Current 64 bit register data.  */
  23964         COMPILER_64_ZERO(cpu_pbm64);
  23965         COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0);
  23966         SOC_IF_ERROR_RETURN(READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,
  23967                                                             &rval64));
  23968         soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64,
  23969                             BITMAPf, cpu_pbm64);
  23970         SOC_IF_ERROR_RETURN(WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port,
  23971                                                              rval64));
  23972     } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_LOr) &&
  23973                SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_HIr)) {
  23974         uint64      fval64, rval64;
  23975         uint32      t_port;
  23976         pbmp_t      curr_pbmp;
  23977         soc_reg_t   reg;
  23978 
  23979         BCM_PBMP_CLEAR(curr_pbmp);
  23980         COMPILER_64_ZERO(fval64);
  23981 
  23982         /* Set HG ingress CPU Opcode map to the CPU */
  23983         if (CMIC_PORT(unit) < 64) {
  23984             reg = ICONTROL_OPCODE_BITMAP_LOr;
  23985             t_port = CMIC_PORT(unit);
  23986         } else {
  23987             reg = ICONTROL_OPCODE_BITMAP_HIr;
  23988             t_port = CMIC_PORT(unit) - 64;
  23989         }
  23990 
  23991 
  23992         if (to_higig) {
  23993             SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  23994         }
  23995 
  23996         BCM_IF_ERROR_RETURN(soc_reg_get(unit,
  23997                             reg, port, 0, &rval64));
  23998         COMPILER_64_SET(fval64,
  23999                         SOC_PBMP_WORD_GET(curr_pbmp, 1),
  24000                         SOC_PBMP_WORD_GET(curr_pbmp, 0));
  24001 
  24002         soc_reg64_field_set(unit,
  24003                 reg, &rval64, BITMAPf, fval64);
  24004         BCM_IF_ERROR_RETURN(soc_reg_set(unit,
  24005                 reg, port, 0, rval64));
  24006 
  24007     } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAPr)) {
  24008 
  24009         /* Set HG ingress CPU Opcode map to the CPU */
  24010         int pbm_len;
  24011         uint32 cpu_pbm = 0;
  24012 
  24013         if (to_higig) {
  24014             if (SOC_IS_TR_VL(unit)) {
  24015                 soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit),
  24016                                               &cpu_pbm);
  24017             } else if (CMIC_PORT(unit)) {
  24018                 pbm_len = soc_reg_field_length(unit, ICONTROL_OPCODE_BITMAPr,
  24019                                                BITMAPf);
  24020                 cpu_pbm = 1 << (pbm_len - 1);
  24021             } else {
  24022                 cpu_pbm = 1;
  24023             }
  24024         } /* else, cpu_pbm = 0 */
  24025 
  24026         SOC_IF_ERROR_RETURN
  24027             (soc_reg_field32_modify(unit, ICONTROL_OPCODE_BITMAPr,
  24028                                     port, BITMAPf, cpu_pbm));
  24029     }
  24030 
  24031     if (to_higig) {
  24032         /* HG ports to forwarding */
  24033         BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port,
  24034                                                  BCM_STG_STP_FORWARD));
  24035     }  
  24036 
  24037 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  24038     /*
  24039      * Higig ports need the MIRROR_CONTROL.M_ENABLE=1 in order to respond to
  24040      * the mirror bit in the Higig headers.
  24041      */
  24042     if (to_higig) {
  24043         BCM_IF_ERROR_RETURN(_bcm_esw_mirror_enable_set(unit, port, TRUE));
  24044     }
  24045 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  24046 
  24047     /* Clear mirror enable settings */
  24048     /* coverity[stack_use_callee] */
  24049     /* coverity[stack_use_overflow] */
  24050     BCM_IF_ERROR_RETURN(bcm_esw_mirror_port_set(unit, port, -1, -1, 0));
  24051 
  24052     /* Set untagged state in default VLAN properly */
  24053     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig));
  24054 
  24055     /* Resolve STG 0 */
  24056     BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg));
  24057     BCM_IF_ERROR_RETURN
  24058         (bcm_esw_stg_stp_set(unit, 0, port,
  24059                              to_higig ? BCM_STG_STP_FORWARD : BCM_STG_STP_DISABLE));
  24060 
  24061 #ifdef BCM_TRX_SUPPORT
  24062     /* Reset the vlan default action */
  24063     if (SOC_IS_TRX(unit) &&
  24064         (soc_feature(unit, soc_feature_vlan_action) ||
  24065          soc_feature(unit, soc_feature_egr_vlan_action))) {
  24066         bcm_vlan_action_set_t action;
  24067 
  24068         BCM_IF_ERROR_RETURN
  24069             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  24070                                                          port, &action));
  24071         /* Backward compatible defaults */
  24072         if (to_higig && (!SOC_IS_TRIDENT3X(unit))) {
  24073             action.ot_outer = bcmVlanActionDelete;
  24074             action.dt_outer = bcmVlanActionDelete;
  24075         } else {
  24076             action.ot_outer = bcmVlanActionNone;
  24077             action.dt_outer = bcmVlanActionNone;
  24078         }
  24079         BCM_IF_ERROR_RETURN
  24080             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  24081                                                          port, &action));
  24082     }
  24083 #endif
  24084 
  24085 #ifdef INCLUDE_L3
  24086     if (soc_feature(unit, soc_feature_ip_mcast)) {
  24087         BCM_IF_ERROR_RETURN(bcm_esw_ipmc_egress_port_set(unit, port,
  24088                 to_higig ? _soc_mac_all_ones :_soc_mac_all_zeroes,
  24089                 0, 0, 0));
  24090     }
  24091 #endif /* INCLUDE_L3 */
  24092 
  24093     return BCM_E_NONE;
  24094 #else
  24095     return BCM_E_PARAM;
  24096 #endif
  24097 }
  24098 
  24099 /*
  24100  * Function:
  24101  *      _bcm_port_encap_stport_set
  24102  * Purpose:
  24103  *      Convert 2.5G Higig 2 port to Ether port, or reverse
  24104  */
  24105 int
  24106 _bcm_port_encap_stport_set(int unit, bcm_port_t port, int mode)
  24107 {
  24108 #if defined(BCM_RAVEN_SUPPORT) || defined (BCM_TRIUMPH2_SUPPORT) || \
  24109     defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  24110     uint32           rval;
  24111     bcm_stg_t        stg;
  24112     int              to_higig = 0, max_mtu = 0;
  24113     uint32           tab_higig_type;
  24114     soc_info_t       *si = &SOC_INFO(unit);
  24115     soc_field_t      hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1,
  24116                                  HGIG2_EN_S3f, HGIG2_EN_S4f};
  24117     soc_field_t      port_type;
  24118     soc_reg_t        egr_port;
  24119 
  24120     if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE
  24121         || mode == BCM_PORT_ENCAP_HIGIG || mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  24122         to_higig = TRUE;
  24123     }
  24124 
  24125 #ifdef BCM_FIRELIGHT_SUPPORT
  24126     if (SOC_IS_FIRELIGHT(unit)) {
  24127         /* FL goes through */
  24128     } else
  24129 #endif
  24130     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  24131         SOC_IS_GREYHOUND2(unit)) {
  24132         if (!soc_feature(unit, soc_feature_wh2)) {
  24133         return BCM_E_INTERNAL;
  24134     }
  24135     }
  24136 
  24137     /* This check is not correct for devices supporting embedded higig */
  24138     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  24139         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  24140         if (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) {
  24141             if ((port != 26) && (port != 27) && (port != 28) && (port != 29)) {
  24142                 return BCM_E_PORT;
  24143             }
  24144             SOC_IF_ERROR_RETURN
  24145                 (soc_reg_field32_modify(unit, EHG_RX_CONTROLr, port, MODEf,
  24146                                         to_higig ? 2 : 0));
  24147         } else if (SOC_IS_HURRICANE2(unit)) {
  24148             if ((port < 26) || (port > 29)) {
  24149                 return BCM_E_PORT;
  24150             }
  24151         } else if (SOC_IS_KATANA(unit)) {
  24152             /* Only ports 25..34 are HGL capable */
  24153             if ((port < 25) || (port > 34)) {
  24154                 return BCM_E_PORT;
  24155             }
  24156         } else if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  24157             /* Only ports 25..40 are HGL capable */
  24158             if ((port < 25) || (port > 40)) {
  24159                 return BCM_E_PORT;
  24160             }
  24161         } else if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TOMAHAWKX(unit) ||
  24162                    SOC_IS_TRIDENT3X(unit)) {
  24163             /* Need to check what is the right condition for Embedded Higig */
  24164         } else if (soc_feature(unit, soc_feature_wh2)) {
  24165             /* All ports are HGL capable */
  24166 #ifdef BCM_FIRELIGHT_SUPPORT
  24167         } else if (SOC_IS_FIRELIGHT(unit)) {
  24168             /* All ports are HGL capable */
  24169 #endif
  24170         } else {
  24171             if ((port != 1) && (port != 2) && (port != 4) && (port != 5)) {
  24172                 return BCM_E_PORT;
  24173             }
  24174         }
  24175     }
  24176 
  24177 #if defined(BCM_KATANA2_SUPPORT)
  24178     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  24179         SOC_IF_ERROR_RETURN(MAC_ENCAP_SET(PORT(unit, port).p_mac,
  24180                                                unit, port, mode));
  24181     } else
  24182 #endif
  24183     {
  24184         port_type = SOC_MEM_FIELD_VALID(unit,
  24185                              SOC_PORT_MEM_TAB(unit, port),
  24186                              HIGIG_PACKETf) ?
  24187                              HIGIG_PACKETf : PORT_TYPEf;
  24188 
  24189         BCM_IF_ERROR_RETURN
  24190              (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24191                                     port_type, to_higig));
  24192 
  24193         if (to_higig == 1) {
  24194             if (mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  24195                 tab_higig_type = BCM_PORT_HG_TYPE_HGOE_TRANSPORT;
  24196             } else if (mode == BCM_PORT_ENCAP_HIGIG) {
  24197                 tab_higig_type = BCM_PORT_HG_TYPE_HIGIGPLUS;
  24198             } else {
  24199                 tab_higig_type = BCM_PORT_HG_TYPE_HIGIG2_NORMAL;
  24200             }
  24201         } else {
  24202             tab_higig_type = 0;
  24203         }
  24204 
  24205         if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) {
  24206             SOC_IF_ERROR_RETURN
  24207                 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  24208                  HG_TYPEf, tab_higig_type));
  24209         }
  24210 
  24211         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) {
  24212             SOC_IF_ERROR_RETURN
  24213                 (soc_mem_field32_modify(unit, EGR_PORTm, port,
  24214                  HG_TYPEf, tab_higig_type));
  24215         }
  24216 
  24217         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, PORT_TYPEf)) {
  24218             SOC_IF_ERROR_RETURN
  24219                 (soc_mem_field32_modify(unit, EGR_PORTm, port,
  24220                              PORT_TYPEf, to_higig));
  24221         } else {
  24222             if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) {
  24223                 egr_port = EGR_PORT_64r;
  24224             } else {
  24225                 egr_port = EGR_PORTr;
  24226             }
  24227             SOC_IF_ERROR_RETURN
  24228                 (soc_reg_field32_modify(unit, egr_port, port,
  24229                                         port_type, to_higig));
  24230        }
  24231 
  24232        /* The port number check is for Coverity.  No port > 6 will
  24233         * reach this logic on Raven. */
  24234         if (SOC_IS_RAVEN(unit) && (port < 6)) {
  24235             SOC_IF_ERROR_RETURN
  24236                 (soc_reg_field32_modify(unit, GPORT_CONFIGr, port,
  24237                                         hg_en[port], to_higig));
  24238         }
  24239     }
  24240 
  24241     if (to_higig) {
  24242         BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 0, 0));
  24243         /* For encap to hg/st port, SOC_PORT_MIN need to update or
  24244            cannot do SOC_PBMP_PORT_ADD if the port is lower than
  24245            SOC_PORT_MIN
  24246         */
  24247         if ((port < SOC_PORT_MIN(unit,st)) || (SOC_PORT_MIN(unit,st) == -1)) {
  24248             SOC_PORT_MIN(unit,st) = port;
  24249         }
  24250         if (port > SOC_PORT_MAX(unit,st)) {
  24251             SOC_PORT_MAX(unit,st) = port;
  24252         }
  24253 
  24254         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  24255         SOC_PBMP_PORT_ADD(si->hl.bitmap, port);
  24256         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  24257         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  24258 
  24259         SOC_PBMP_PORT_INFO_UPDATE(si->xe);
  24260 
  24261         max_mtu = SOC_INFO(unit).max_mtu;
  24262         BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu));
  24263     } else {
  24264         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  24265         SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port);
  24266         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  24267 
  24268         /* Set pause and frame - other abilities depend on the board and
  24269          * the application needs to call other APIs appropriately */
  24270         BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 1, 1));
  24271         max_mtu = SOC_INFO(unit).max_mtu - 4;
  24272         BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu));
  24273     }
  24274     SOC_PBMP_PORT_INFO_UPDATE(si->ether);
  24275     SOC_PBMP_PORT_INFO_UPDATE(si->st);
  24276     SOC_PBMP_PORT_INFO_UPDATE(si->hl);
  24277 
  24278     /* Set HG ingress CPU Opcode map to the CPU */
  24279     if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  24280         icontrol_opcode_bitmap_entry_t entry;
  24281         soc_pbmp_t pbmp;
  24282 
  24283         SOC_IF_ERROR_RETURN
  24284             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24285         SOC_PBMP_CLEAR(pbmp);
  24286         if (to_higig) {
  24287             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  24288         }
  24289         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  24290                                BITMAPf, &pbmp);
  24291         SOC_IF_ERROR_RETURN
  24292             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24293     } else if (SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_64r)) {
  24294         uint64 cpu_pbm64;
  24295         uint64 rval64;      /* Current 64 bit register data.  */
  24296         COMPILER_64_ZERO(cpu_pbm64);
  24297         COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0);
  24298         SOC_IF_ERROR_RETURN(
  24299             READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,&rval64));
  24300 
  24301         soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64,
  24302                             BITMAPf, cpu_pbm64);
  24303 
  24304         SOC_IF_ERROR_RETURN(
  24305             WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, rval64));
  24306     } else {
  24307         uint32 cpu_pbm;
  24308 
  24309         if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) {
  24310             if(to_higig) {
  24311                 SOC_IF_ERROR_RETURN
  24312                         (soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit),
  24313                                            &cpu_pbm));
  24314             } else {
  24315                 cpu_pbm = 0;
  24316             }
  24317         } else {
  24318             cpu_pbm = to_higig ? 1 : 0;
  24319         }
  24320 #ifdef BCM_FIRELIGHT_SUPPORT
  24321         if (SOC_IS_FIRELIGHT(unit)) {
  24322             uint64      fval64, rval64;
  24323             uint32      t_port;
  24324             pbmp_t      curr_pbmp;
  24325             soc_reg_t   reg;
  24326 
  24327             BCM_PBMP_CLEAR(curr_pbmp);
  24328             COMPILER_64_ZERO(fval64);
  24329 
  24330             /* Set HG ingress CPU Opcode map to the CPU */
  24331             if (CMIC_PORT(unit) < 64) {
  24332                 reg = ICONTROL_OPCODE_BITMAP_LOr;
  24333                 t_port = CMIC_PORT(unit);
  24334             } else {
  24335                 reg = ICONTROL_OPCODE_BITMAP_HIr;
  24336                 t_port = CMIC_PORT(unit) - 64;
  24337             }
  24338 
  24339             if (to_higig) {
  24340                 SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  24341             }
  24342 
  24343             BCM_IF_ERROR_RETURN(soc_reg_get(unit,
  24344                                 reg, port, 0, &rval64));
  24345             COMPILER_64_SET(fval64,
  24346                             SOC_PBMP_WORD_GET(curr_pbmp, 1),
  24347                             SOC_PBMP_WORD_GET(curr_pbmp, 0));
  24348 
  24349             soc_reg64_field_set(unit,
  24350                     reg, &rval64, BITMAPf, fval64);
  24351             BCM_IF_ERROR_RETURN(soc_reg_set(unit,
  24352                     reg, port, 0, rval64));
  24353         } else
  24354 #endif
  24355         {
  24356             SOC_IF_ERROR_RETURN(
  24357                 READ_ICONTROL_OPCODE_BITMAPr(unit, port,&rval));
  24358 
  24359             soc_reg_field_set(unit, ICONTROL_OPCODE_BITMAPr,
  24360                               &rval, BITMAPf, cpu_pbm);
  24361 
  24362             SOC_IF_ERROR_RETURN(
  24363                 WRITE_ICONTROL_OPCODE_BITMAPr(unit, port, rval));
  24364         }
  24365     }
  24366 
  24367     /* HG ports to forwarding */
  24368     BCM_IF_ERROR_RETURN(
  24369         bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD));
  24370 
  24371     /* Set untagged state in default VLAN properly */
  24372     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig));
  24373 
  24374     /* Resolve STG 0 */
  24375     BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg));
  24376     BCM_IF_ERROR_RETURN(
  24377         bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD));
  24378 
  24379 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  24380     /* Reset the vlan default action */
  24381     if ((SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) ||
  24382          SOC_IS_KATANA2(unit)) &&
  24383             soc_feature(unit, soc_feature_vlan_action)) {
  24384         bcm_vlan_action_set_t action;
  24385 
  24386         BCM_IF_ERROR_RETURN
  24387             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  24388                                                          port, &action));
  24389         if (to_higig) {
  24390             action.ot_outer = bcmVlanActionDelete;
  24391             action.dt_outer = bcmVlanActionDelete;
  24392         } else {
  24393             action.ot_outer = bcmVlanActionNone;
  24394             action.dt_outer = bcmVlanActionNone;
  24395         }
  24396         BCM_IF_ERROR_RETURN
  24397             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  24398                                                          port, &action));
  24399     }
  24400 #endif /* BCM_ENDURO_SUPPORT */
  24401 
  24402     return BCM_E_NONE;
  24403 #else
  24404     return BCM_E_PARAM;
  24405 #endif
  24406 }
  24407 
  24408 /*
  24409  * Function:
  24410  *      _bcm_port_ehg_header_mem_get
  24411  * Purpose:
  24412  *      Calculates the correct memories for a given port
  24413  * Parameters:
  24414  *      unit            - (IN) device id
  24415  *      port            - (IN) Physical port
  24416  *      tx_mem          - (OUT) tx memory for EHG heade
  24417  *      rx_mem          - (OUT) rx memory for EHG heade
  24418  *      rx_mask_mem     - (OUT) rx mask memory for EHG heade
  24419  * Returns:
  24420  *      BCM_E_XXX
  24421  */
  24422 STATIC int
  24423 _bcm_port_ehg_header_mem_get(int unit, bcm_port_t port, soc_mem_t *tx_mem,
  24424                              soc_mem_t *rx_mem, soc_mem_t *rx_mask_mem)
  24425 {
  24426     int phy_port;
  24427 
  24428     if (NULL == tx_mem || NULL == rx_mem || NULL == rx_mask_mem) {
  24429         return BCM_E_PARAM;
  24430     }
  24431 
  24432     if (soc_feature(unit, soc_feature_logical_port_num)) {
  24433         /* coverity[overrun-local : FALSE] */
  24434         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  24435     } else {
  24436         phy_port = port;
  24437     }
  24438     switch (SOC_PORT_BLOCK_TYPE(unit, phy_port)) {
  24439         case SOC_BLK_GXPORT:
  24440             *tx_mem = XPORT_EHG_TX_TUNNEL_DATAm;
  24441             *rx_mem = XPORT_EHG_RX_TUNNEL_DATAm;
  24442             *rx_mask_mem = XPORT_EHG_RX_TUNNEL_MASKm;
  24443             break;
  24444         case SOC_BLK_GPORT:
  24445             *tx_mem = GPORT_EHG_TX_TUNNEL_DATAm;
  24446             *rx_mem = GPORT_EHG_RX_TUNNEL_DATAm;
  24447             *rx_mask_mem = GPORT_EHG_RX_TUNNEL_MASKm;
  24448             break;
  24449         case SOC_BLK_SPORT:
  24450             *tx_mem = SPORT_EHG_TX_TUNNEL_DATAm;
  24451             *rx_mem = SPORT_EHG_RX_TUNNEL_DATAm;
  24452             *rx_mask_mem = SPORT_EHG_RX_TUNNEL_MASKm;
  24453             break;
  24454         case SOC_BLK_XQPORT:
  24455             *tx_mem = XQPORT_EHG_TX_TUNNEL_DATAm;
  24456             *rx_mem = XQPORT_EHG_RX_TUNNEL_DATAm;
  24457             *rx_mask_mem = XQPORT_EHG_RX_TUNNEL_MASKm;
  24458             break;
  24459         case SOC_BLK_CLPORT:
  24460         case SOC_BLK_XLPORT:
  24461         case SOC_BLK_XTPORT:
  24462         case SOC_BLK_XWPORT:
  24463             *tx_mem = PORT_EHG_TX_TUNNEL_DATAm;
  24464             *rx_mem = PORT_EHG_RX_TUNNEL_DATAm;
  24465             *rx_mask_mem = PORT_EHG_RX_TUNNEL_MASKm;
  24466             break;
  24467         default:
  24468             *tx_mem = *rx_mem = *rx_mask_mem = INVALIDm;
  24469     }
  24470 
  24471     return BCM_E_NONE;
  24472 }
  24473 
  24474 /*
  24475  * Function:
  24476  *      _bcm_port_ehg_header_read
  24477  * Purpose:
  24478  *      Reads EHG header from the HW tables
  24479  * Parameters:
  24480  *      unit            - (IN) device id
  24481  *      port            - (IN) Physical port
  24482  *      buffer          - (OUT) Pointer to the buffer to contain header
  24483  * Returns:
  24484  *      BCM_E_XXX
  24485  */
  24486 
  24487 STATIC int
  24488 _bcm_port_ehg_header_read(int unit, bcm_port_t port, uint32 *buffer)
  24489 {
  24490     soc_mem_t   tx_mem, rx_mem, rx_mask_mem;
  24491     int         tbl_idx_start, tbl_idx_end, idx;
  24492     xqport_ehg_rx_tunnel_data_entry_t      entry;
  24493     int         phy_port;
  24494 
  24495     BCM_IF_ERROR_RETURN
  24496         (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem,
  24497                                       &rx_mask_mem));
  24498 
  24499     if (INVALIDm == tx_mem) {
  24500         return (BCM_E_PORT);
  24501     }
  24502 
  24503     if (soc_feature(unit, soc_feature_logical_port_num)) {
  24504         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  24505     } else {
  24506         phy_port = port;
  24507     }
  24508 
  24509     tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4;
  24510     tbl_idx_end = tbl_idx_start + 3;
  24511 
  24512     for (idx = 0 ; idx <= (tbl_idx_end - tbl_idx_start); idx ++) {
  24513         BCM_IF_ERROR_RETURN
  24514             (soc_mem_read(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port),
  24515                           (idx + tbl_idx_start), (void *)&entry));
  24516         soc_mem_field_get(unit, tx_mem, (void *)&entry, TUNNEL_DATAf,
  24517                           (buffer + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  24518     }
  24519 
  24520     return (BCM_E_NONE);
  24521 }
  24522 
  24523 /*
  24524  * Function:
  24525  *      _bcm_port_ehg_header_write
  24526  * Purpose:
  24527  *      Writes EHG header into the HW tables
  24528  * Parameters:
  24529  *      unit            - (IN) device id
  24530  *      port            - (IN) Physical port
  24531  *      tx_buff         - (IN) Pointer to the tx header
  24532  *      rx_buff         - (IN) Pointer to the rx header
  24533  *      mask            - (IN) Pointer to the mask header
  24534  *      len             - (IN) Header length
  24535  * Returns:
  24536  *      BCM_E_XXX
  24537  */
  24538 int
  24539 _bcm_port_ehg_header_write(int unit, bcm_port_t port, uint32 *tx_buf,
  24540                            uint32 *rx_buf, uint32 *mask, int len)
  24541 {
  24542     soc_mem_t   tx_mem, rx_mem, rx_mask_mem;
  24543     int         tbl_idx_start, tbl_idx_end, idx;
  24544     xqport_ehg_rx_tunnel_data_entry_t data_entry;
  24545     xqport_ehg_rx_tunnel_mask_entry_t mask_entry;
  24546     int         phy_port;
  24547 
  24548     BCM_IF_ERROR_RETURN
  24549         (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem,
  24550                                       &rx_mask_mem));
  24551 
  24552     if (INVALIDm == tx_mem) {
  24553         return (BCM_E_PORT);
  24554     }
  24555 
  24556     if (soc_feature(unit, soc_feature_logical_port_num)) {
  24557         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  24558     } else {
  24559         phy_port = port;
  24560     }
  24561 
  24562     tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4;
  24563     tbl_idx_end = tbl_idx_start + (len / 4) - 1;
  24564 
  24565     for (idx = 0; idx <= (tbl_idx_end - tbl_idx_start); idx ++) {
  24566         /* Reset hw buffer. */
  24567         sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t));
  24568         soc_mem_field_set(unit, tx_mem, (uint32 *)&data_entry, TUNNEL_DATAf,
  24569                           (tx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  24570         BCM_IF_ERROR_RETURN
  24571             (soc_mem_write(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port),
  24572                            (idx + tbl_idx_start), &data_entry));
  24573 
  24574         /* Reset hw buffer. */
  24575         sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t));
  24576         soc_mem_field_set(unit, rx_mem, (uint32 *)&data_entry, TUNNEL_DATAf,
  24577                           (rx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  24578         BCM_IF_ERROR_RETURN
  24579             (soc_mem_write(unit, rx_mem, SOC_PORT_BLOCK(unit, phy_port),
  24580                            (idx + tbl_idx_start), &data_entry));
  24581 
  24582         /* Reset hw buffer. */
  24583         sal_memset(&mask_entry, 0, sizeof(xqport_ehg_rx_tunnel_mask_entry_t));
  24584         soc_mem_field_set(unit, rx_mask_mem, (uint32 *)&mask_entry, TUNNEL_MASKf,
  24585                           (mask + ((tbl_idx_end - tbl_idx_start - idx)* 4)));
  24586         BCM_IF_ERROR_RETURN
  24587             (soc_mem_write(unit, rx_mask_mem, SOC_PORT_BLOCK(unit, phy_port),
  24588                            (idx + tbl_idx_start), &mask_entry));
  24589     }
  24590 
  24591     return (BCM_E_NONE);
  24592 }
  24593 
  24594 
  24595 /*
  24596  * Function:
  24597  *      _bcm_port_ehg_setup_txrx_ethernet_hdr
  24598  * Purpose:
  24599  *      Prepares SRC and DEST MAC addresses into rx and tx buffers on a given index
  24600  * Parameters:
  24601  *      tx_buffer       -(IN/OUT) - tx buffer to fill
  24602  *      rx_buffer       -(IN/OUT) - rx buffer to fill
  24603  *      index           -(IN/OUT) - index to the right location in buffer
  24604  *      encap_config    - (IN) structure describes port encapsulation configuration
  24605  * Returns:
  24606  *      BCM_E_XXX
  24607  */
  24608 
  24609 STATIC void
  24610 _bcm_port_ehg_setup_txrx_ethernet_hdr(uint32 *tx_buffer, uint32 *rx_buffer,
  24611                                       int *index,
  24612                                       bcm_port_encap_config_t *encap_config)
  24613 {
  24614     int idx = *index;
  24615 
  24616     /* Destination mac address. */
  24617     tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[0]) << 24 | \
  24618                       ((uint32)(encap_config->dst_mac)[1]) << 16 | \
  24619                       ((uint32)(encap_config->dst_mac)[2]) << 8  | \
  24620                       ((uint32)(encap_config->dst_mac)[3]));
  24621     /* TX dest MAC is RX src MAC */
  24622     rx_buffer[idx] = (((uint32)(encap_config->src_mac)[0]) << 24 | \
  24623                       ((uint32)(encap_config->src_mac)[1]) << 16 | \
  24624                       ((uint32)(encap_config->src_mac)[2]) << 8  | \
  24625                       ((uint32)(encap_config->src_mac)[3]));
  24626     idx--;
  24627 
  24628     tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[4]) << 24 | \
  24629                       ((uint32)(encap_config->dst_mac)[5]) << 16 | \
  24630                       ((uint32)(encap_config->src_mac)[0]) << 8  | \
  24631                       ((uint32)(encap_config->src_mac)[1]));
  24632     /* TX dest MAC is RX src MAC */
  24633     rx_buffer[idx] = (((uint32)(encap_config->src_mac)[4]) << 24 | \
  24634                       ((uint32)(encap_config->src_mac)[5]) << 16 | \
  24635                       ((uint32)(encap_config->dst_mac)[0]) << 8  | \
  24636                       ((uint32)(encap_config->dst_mac)[1]));
  24637     idx--;
  24638     /* Source mac address. */
  24639     tx_buffer[idx] = (((uint32)(encap_config->src_mac)[2]) << 24 | \
  24640                       ((uint32)(encap_config->src_mac)[3]) << 16 | \
  24641                       ((uint32)(encap_config->src_mac)[4]) << 8  | \
  24642                       ((uint32)(encap_config->src_mac)[5]));
  24643     /* TX src MAC is RX dest MAC */
  24644     rx_buffer[idx] = (((uint32)(encap_config->dst_mac)[2]) << 24 | \
  24645                       ((uint32)(encap_config->dst_mac)[3]) << 16 | \
  24646                       ((uint32)(encap_config->dst_mac)[4]) << 8  | \
  24647                       ((uint32)(encap_config->dst_mac)[5]));
  24648     idx--;
  24649 
  24650     *index = idx;
  24651     return;
  24652 }
  24653 
  24654 /* Embedded Higig register access macros */
  24655 #define EHG_TX_REG(unit) \
  24656         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TX_CONTROLr : EHG_TX_CONTROLr)
  24657 #define EHG_RX_REG(unit) \
  24658         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_RX_CONTROLr : EHG_RX_CONTROLr)
  24659 #define EHG_TPID_REG(unit) \
  24660         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TPIDr : EHG_TPIDr)
  24661 
  24662 /*
  24663  * Function:
  24664  *      _bcm_port_ehg_ethernet_header_parse
  24665  * Purpose:
  24666  *      Parses Ethernet header from EHG header
  24667  * Parameters:
  24668  *      unit            - (IN) device id
  24669  *      port            - (IN) Physical port
  24670  *      header          - (IN) pointer to the EHG header buffer
  24671  *      encap_config    - (IN/OUT) structure describes port encapsulation configuration
  24672  *      index           - (IN/OUT) index to the right location in buffer
  24673  * Returns:
  24674  *      BCM_E_XXX
  24675  */
  24676 STATIC int
  24677 _bcm_port_ehg_ethernet_header_parse(int unit, bcm_port_t port, uint32 *header,
  24678                                     bcm_port_encap_config_t *encap_config, int *index)
  24679 {
  24680     uint32  val;
  24681     int     idx = *index;
  24682     soc_reg_t ehg_tx_reg = EHG_TX_REG(unit);
  24683 
  24684     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  24685     encap_config->dst_mac[0] = (uint8)(header[idx] >> 24);
  24686     encap_config->dst_mac[1] = (uint8)(header[idx] >> 16);
  24687     encap_config->dst_mac[2] = (uint8)(header[idx] >> 8);
  24688     encap_config->dst_mac[3] = (uint8)(header[idx]);
  24689     idx--;
  24690     encap_config->dst_mac[4] = (uint8)(header[idx] >> 24);
  24691     encap_config->dst_mac[5] = (uint8)(header[idx] >> 16);
  24692     encap_config->src_mac[0] = (uint8)(header[idx] >> 8);
  24693     encap_config->src_mac[1] = (uint8)(header[idx]);
  24694     idx--;
  24695     encap_config->src_mac[2] = (uint8)(header[idx] >> 24);
  24696     encap_config->src_mac[3] = (uint8)(header[idx] >> 16);
  24697     encap_config->src_mac[4] = (uint8)(header[idx] >> 8);
  24698     encap_config->src_mac[5] = (uint8)(header[idx]);
  24699     idx--;
  24700 
  24701     if (soc_reg_field_get(unit, ehg_tx_reg, val, VLAN_TAG_CONTROLf)) {
  24702         encap_config->tpid = (uint16)(header[idx] >> 16);
  24703         encap_config->vlan = (uint16)(header[idx]);
  24704         idx--;
  24705     } else {
  24706         encap_config->vlan = BCM_VLAN_NONE;
  24707         encap_config->tpid = BCM_VLAN_NONE;
  24708     }
  24709 
  24710     *index = idx;
  24711     return BCM_E_NONE;
  24712 }
  24713 /*
  24714  * Function:
  24715  *      _bcm_port_ip4_tunnel_header_set
  24716  * Purpose:
  24717  *      Prepares and sets IP GRE tunnel header for Embedded higig
  24718  * Parameters:
  24719  *      unit            - (IN) device id
  24720  *      port            - (IN) Physical port
  24721  *      encap_config    - (IN) structure describes port encapsulation configuration
  24722  * Returns:
  24723  *      BCM_E_XXX
  24724  */
  24725 STATIC int
  24726 _bcm_port_ip4_tunnel_header_set(int unit, bcm_port_t port,
  24727                                bcm_port_encap_config_t *encap_config)
  24728 {
  24729     /*SW tunnel tx encap buffer.*/
  24730     uint32 tx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  24731     /*SW tunnel rx encap buffer.*/
  24732     uint32 rx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  24733     uint32      mask[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  24734     int    idx;  /* Headers offset iterator.*/
  24735     int    adjust_rx_offset = 0;
  24736 
  24737     sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  24738     sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  24739     sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  24740 
  24741     idx = _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1;
  24742 
  24743     _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx,
  24744                                           encap_config);
  24745 
  24746     /* Set tpid & vlan id. */
  24747     if (BCM_VLAN_VALID(encap_config->vlan)) {
  24748         /* Tpid. Priority,  Cfi, Vlan id. */
  24749         tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \
  24750                            ((uint32)(encap_config->vlan)));
  24751         /*rx_buffer should not have the VLAN and TPID included*/
  24752         idx--;
  24753         adjust_rx_offset = 1;
  24754     }
  24755 
  24756     /*
  24757      *   IPv4 header.
  24758      */
  24759     /* Set ether type to ip. 0x800  */
  24760     /* Version + 5 word no options length.  + Tos */
  24761     /* Length, Id, Flags, Fragmentation offset. */
  24762     tx_buffer[idx] |= (((uint32)(0x0800) << 16) | \
  24763                        ((uint32)(0x45) << 8) | \
  24764                        ((uint32)(encap_config->tos)));
  24765     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24766     idx--;
  24767     idx--;
  24768 
  24769     /* Ttl */
  24770     /* Protocol (GRE 0x2f) */
  24771     tx_buffer[idx] = (((uint32)(encap_config->ttl) << 8) | \
  24772                       ((uint32)(0x2f)));
  24773     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24774     idx--;
  24775 
  24776     /* TX Src Ip. */
  24777     tx_buffer[idx] |= ((uint32)(encap_config->src_addr) >> 16);
  24778 
  24779     /* RX Dst Ip. */
  24780     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) >> 16);
  24781     idx--;
  24782 
  24783     /* TX Src Ip. */
  24784     tx_buffer[idx] |= ((uint32)(encap_config->src_addr) << 16);
  24785 
  24786     /* RX Dst Ip. */
  24787     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) << 16);
  24788 
  24789     /* TX Dst Ip. */
  24790     tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) >> 16);
  24791 
  24792     /* RX Src Ip */
  24793     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) >> 16);
  24794     idx--;
  24795 
  24796 
  24797     /* TX Dst Ip. */
  24798     tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) << 16);
  24799 
  24800     /* RX Src Ip */
  24801     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) << 16);
  24802     idx--;
  24803 
  24804     /* Gre header */
  24805     /* Set protocol type in GRE header to ether type specified by user */
  24806     tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype) << 16) | \
  24807                        ((uint32)(encap_config->oui)[0]) << 8 | \
  24808                        ((uint32)(encap_config->oui)[1]));
  24809     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24810     mask[idx + adjust_rx_offset]=0x0000FFFF;/*TUNNEL_TYPE=1:The first 38 bytes will be compared against the rx table data*/
  24811     sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset));
  24812     idx--;
  24813 
  24814     /* Set TX OUI and OUI Ethertype*/
  24815     tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \
  24816                        ((uint32)(encap_config->oui_ethertype)) << 8);
  24817     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24818 
  24819     return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask,
  24820                                       _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ);
  24821 }
  24822 
  24823 /*
  24824  * Function:
  24825  *      _bcm_port_ipv4_tunnel_header_parse
  24826  * Purpose:
  24827  *      Parse IPv4 GRE tunnel header for Embedded higig and updates encap_config
  24828  *      structure accordingly
  24829  * Parameters:
  24830  *      unit            - (IN) device id
  24831  *      port            - (IN) Physical port
  24832  *      header          - (IN) Buffer contains EHG header to parse
  24833  *      encap_config    - (OUT) structure describes port encapsulation configuration
  24834  * Returns:
  24835  *      BCM_E_XXX
  24836  */
  24837 STATIC int
  24838 _bcm_port_ipv4_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header,
  24839                                    bcm_port_encap_config_t *encap_config)
  24840 {
  24841     /* Headers offset iterator, begins at end of header */
  24842     int  idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1;
  24843 
  24844     BCM_IF_ERROR_RETURN(
  24845     _bcm_port_ehg_ethernet_header_parse(unit, port, header, encap_config,
  24846                                             &idx));
  24847 
  24848     encap_config->tos = (uint8)(header[idx]);
  24849     idx--;
  24850     idx--;
  24851     encap_config->ttl = (uint8)(header[idx] >> 8);
  24852     idx--;
  24853     encap_config->src_addr = ((uint16)(header[idx])) << 16;
  24854     idx--;
  24855     encap_config->src_addr |=(uint16)(header[idx] >> 16);
  24856     encap_config->dst_addr = ((uint16)(header[idx])) << 16;
  24857     idx--;
  24858     encap_config->dst_addr |=(uint16)(header[idx] >> 16);
  24859     idx--;
  24860     encap_config->higig_ethertype = (uint16)(header[idx] >> 16);
  24861     encap_config->oui[0] = (uint8)(header[idx] >> 8);
  24862     encap_config->oui[1] = (uint8)(header[idx]);
  24863     idx--;
  24864     encap_config->oui[2] = (uint8)(header[idx] >> 24);
  24865     encap_config->oui_ethertype = (uint16)(header[idx] >> 8);
  24866 
  24867     return BCM_E_NONE;
  24868 }
  24869 
  24870 /*
  24871  * Function:
  24872  *      _bcm_port_l2_tunnel_header_set
  24873  * Purpose:
  24874  *      Prepares and sets L2 tunnel header for Embedded higig
  24875  * Parameters:
  24876  *      unit            - (IN) device id
  24877  *      port            - (IN) Physical port
  24878  *      encap_config    - (IN) structure describes port encapsulation configuration
  24879  * Returns:
  24880  *      BCM_E_XXX
  24881  */
  24882 STATIC int
  24883 _bcm_port_l2_tunnel_header_set(int unit, bcm_port_t port,
  24884                                bcm_port_encap_config_t *encap_config)
  24885 {
  24886     /*SW tunnel tx encap buffer.*/
  24887     uint32 tx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  24888     /*SW tunnel rx encap buffer.*/
  24889     uint32 rx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  24890     uint32      mask[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  24891     int     idx;  /* Headers offset iterator.*/
  24892     int     adjust_rx_offset = 0;
  24893 
  24894     sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  24895     sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  24896     sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  24897 
  24898     idx = _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ - 1;
  24899 
  24900     _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx,
  24901                                           encap_config);
  24902 
  24903     /* Set tpid & vlan id. */
  24904     if (BCM_VLAN_VALID(encap_config->vlan)) {
  24905         /* Tpid. Priority,  Cfi, Vlan id. */
  24906         tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \
  24907                            ((uint32)(encap_config->vlan)));
  24908         /*rx_buffer should not have the VLAN and TPID included*/
  24909         idx--;
  24910         adjust_rx_offset = 1;
  24911     }
  24912 
  24913     /* Set ether type to OUI and TX OUI */
  24914     tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype)) << 16 | \
  24915                        ((uint32)(encap_config->oui)[0]) << 8 | \
  24916                        ((uint32)(encap_config->oui)[1]));
  24917     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24918     mask[idx + adjust_rx_offset] = 0x0000FFFF; /*TUNNEL_TYPE=0:The first 14 bytes will be compared against the rx table data*/
  24919     sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset));
  24920     idx--;
  24921     /* Set TX OUI and HG ether type */
  24922     tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \
  24923                        ((uint32)(encap_config->oui_ethertype)) << 8);
  24924     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24925 
  24926     return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask,
  24927                                        _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ);
  24928 }
  24929 
  24930 
  24931 /*
  24932  * Function:
  24933  *      _bcm_port_l2_tunnel_header_parse
  24934  * Purpose:
  24935  *      Parse L2 tunnel header for Embedded higig and updates encap_config
  24936  *      structure accordingly
  24937  * Parameters:
  24938  *      unit            - (IN) device id
  24939  *      port            - (IN) Physical port
  24940  *      header          - (IN) Buffer contains EHG header to parse
  24941  *      encap_config    - (OUT) structure describes port encapsulation configuration
  24942  * Returns:
  24943  *      BCM_E_XXX
  24944  */
  24945 STATIC int
  24946 _bcm_port_l2_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header,
  24947                                  bcm_port_encap_config_t *encap_config)
  24948 {
  24949     /* Headers offset iterator, begins at end of header */
  24950     int  idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1;
  24951 
  24952     BCM_IF_ERROR_RETURN
  24953         (_bcm_port_ehg_ethernet_header_parse(unit, port, header,
  24954                                              encap_config, &idx));
  24955 
  24956     encap_config->higig_ethertype = (uint16)(header[idx] >> 16);
  24957     encap_config->oui[0] = (uint8)(header[idx] >> 8);
  24958     encap_config->oui[1] = (uint8)(header[idx]);
  24959     idx--;
  24960     encap_config->oui[2] = (uint8)(header[idx] >> 24);
  24961     encap_config->oui_ethertype = (uint16)(header[idx] >> 8);
  24962 
  24963     return BCM_E_NONE;
  24964 }
  24965 
  24966 /*
  24967  * Function:
  24968  *      _bcm_port_encap_ehg_xport_update
  24969  * Purpose:
  24970  *      Updates XPORT higig config for EHG
  24971  * Parameters:
  24972  *      unit            - (IN) device id
  24973  *      port            - (IN) Physical port
  24974  * Returns:
  24975  */
  24976 STATIC int
  24977 _bcm_port_encap_ehg_xport_update(int unit, bcm_port_t port)
  24978 {
  24979 #if defined(BCM_TRIUMPH3_SUPPORT)
  24980     if (SOC_IS_TRIUMPH3(unit)) {
  24981         
  24982         soc_field_t ept_fields[2] = { HIGIG2f, PORT_TYPEf };
  24983         uint32 ept_vals[2] = { BCM_EGR_PORT_HIGIG2, BCM_EGR_PORT_TYPE_EHG };
  24984 
  24985         /* Ingress port table */
  24986         BCM_IF_ERROR_RETURN
  24987             (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24988                                    HIGIG2f, 1));
  24989         BCM_IF_ERROR_RETURN
  24990             (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24991                                    PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  24992 
  24993         /* Egress port table */
  24994         BCM_IF_ERROR_RETURN
  24995             (soc_mem_fields32_modify(unit, EGR_PORTm, port, 2,
  24996                                      ept_fields, ept_vals));
  24997 
  24998         /* Egress ingress port table */
  24999         BCM_IF_ERROR_RETURN
  25000             (soc_mem_fields32_modify(unit, EGR_ING_PORTm, port, 2,
  25001                                      ept_fields, ept_vals));
  25002 
  25003         BCM_IF_ERROR_RETURN
  25004             (soc_reg_field32_modify(unit, PORT_CONFIGr, port,
  25005                                     HIGIG2_MODEf, 1));
  25006 
  25007         if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  25008             icontrol_opcode_bitmap_entry_t entry;
  25009             soc_pbmp_t pbmp;
  25010 
  25011             BCM_IF_ERROR_RETURN
  25012                 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  25013 
  25014             SOC_PBMP_CLEAR(pbmp);
  25015 
  25016             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  25017 
  25018             soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  25019                     BITMAPf, &pbmp);
  25020 
  25021             BCM_IF_ERROR_RETURN
  25022                 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  25023         }
  25024 
  25025         return (BCM_E_NONE);
  25026     }
  25027 #endif /* BCM_TRIUMPH3_SUPPORT  */
  25028 
  25029 #ifdef BCM_GXPORT_SUPPORT
  25030     {
  25031         soc_reg_t   egr_port_reg;
  25032 
  25033         if (IS_GX_PORT(unit, port) || IS_XQ_PORT(unit,port)) {
  25034 
  25035             egr_port_reg =
  25036                 (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  25037                  SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) ||
  25038                  SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  25039                  EGR_PORT_64r : EGR_PORTr;
  25040 
  25041             BCM_IF_ERROR_RETURN
  25042                 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  25043                                        HIGIG2f, 1));
  25044 
  25045             BCM_IF_ERROR_RETURN
  25046                 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  25047                                        PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  25048             BCM_IF_ERROR_RETURN
  25049                 (soc_reg_field32_modify(unit, egr_port_reg, port, HIGIG2f,
  25050                                         BCM_EGR_PORT_HIGIG2));
  25051             BCM_IF_ERROR_RETURN
  25052                 (soc_reg_field32_modify(unit, egr_port_reg, port,
  25053                                         PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  25054 
  25055             if(SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) {
  25056                 BCM_IF_ERROR_RETURN
  25057                     (soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  25058                                             HIGIG2_MODEf, 1));
  25059             }
  25060         }
  25061     }
  25062 #endif /* BCM_GXPORT_SUPPORT */
  25063     return (BCM_E_NONE);
  25064 }
  25065 
  25066 /*
  25067  * Function:
  25068  *      _bcm_port_ehg_transport_mode_set
  25069  * Purpose:
  25070  *      Set the port into embedded higig transport mode
  25071  * Parameters:
  25072  *      unit            - (IN) device id
  25073  *      port            - (IN) Physical port
  25074  *      encap_config    - (IN) structure describes port encapsulation configuration
  25075  * Returns:
  25076  *      BCM_E_XXX
  25077  */
  25078 STATIC int
  25079 _bcm_port_ehg_transport_mode_set(int unit, bcm_port_t port,
  25080                                  bcm_port_encap_config_t *encap_config)
  25081 {
  25082     int         vlan_valid;
  25083     uint32      val;
  25084     soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  25085     soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  25086     soc_reg_t   ehg_tpid_reg = EHG_TPID_REG(unit);
  25087 
  25088     if (IS_HG_PORT(unit, port)) {
  25089         return BCM_E_CONFIG;
  25090     }
  25091 
  25092     BCM_IF_ERROR_RETURN
  25093         (_bcm_port_encap_ehg_xport_update(unit, port));
  25094 
  25095     vlan_valid = BCM_VLAN_VALID(encap_config->vlan);
  25096 
  25097     /* Configure TX control */
  25098     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  25099     soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1);
  25100     soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 0);
  25101     soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf,
  25102                       vlan_valid);
  25103     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf,
  25104                       vlan_valid);
  25105     soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf,
  25106                       0);
  25107     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 0);
  25108     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 0);
  25109     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val));
  25110 
  25111     /* Configure RX control */
  25112     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  25113     soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 0);
  25114     soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1);
  25115     soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf,
  25116                       vlan_valid);
  25117     soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf,
  25118                       vlan_valid);
  25119     soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf,
  25120                       (vlan_valid) ? encap_config->vlan : 0);
  25121     soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 0);
  25122     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val));
  25123 
  25124     /* Configure EHG-tpid */
  25125     if (vlan_valid) {
  25126         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val));
  25127         soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf,
  25128                           encap_config->tpid);
  25129         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val));
  25130     }
  25131 
  25132     return _bcm_port_l2_tunnel_header_set(unit, port, encap_config);
  25133 }
  25134 
  25135 /*
  25136  * Function:
  25137  *      _bcm_port_ehg_tunnel_mode_set
  25138  * Purpose:
  25139  *      Set the port into embedded higig tunnel mode
  25140  * Parameters:
  25141  *      unit            - (IN) device id
  25142  *      port            - (IN) Physical port
  25143  *      encap_config    - (IN) structure describes port encapsulation configuration
  25144  * Returns:
  25145  *      BCM_E_XXX
  25146  */
  25147 STATIC int
  25148 _bcm_port_ehg_tunnel_mode_set(int unit, bcm_port_t port,
  25149                                  bcm_port_encap_config_t *encap_config)
  25150 {
  25151     int         vlan_valid;
  25152     uint32      val;
  25153     soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  25154     soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  25155     soc_reg_t   ehg_tpid_reg = EHG_TPID_REG(unit);
  25156 
  25157     if (IS_HG_PORT(unit, port)) {
  25158         return BCM_E_CONFIG;
  25159     }
  25160 
  25161     BCM_IF_ERROR_RETURN
  25162         (_bcm_port_encap_ehg_xport_update(unit, port));
  25163 
  25164     vlan_valid = BCM_VLAN_VALID(encap_config->vlan);
  25165 
  25166     /* Configure TX control */
  25167     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  25168     soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1);
  25169     soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 1);
  25170     soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf,
  25171                       vlan_valid);
  25172     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf,
  25173                       vlan_valid);
  25174     soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf,
  25175          vlan_valid ? (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ) - 1):
  25176                  (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1) - 1));
  25177     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 1);
  25178     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 1);
  25179     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val));
  25180 
  25181     /* Configure RX control */
  25182     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  25183     soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1);
  25184     soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 1);
  25185     soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf,
  25186                       vlan_valid);
  25187     soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf,
  25188                       vlan_valid);
  25189     soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf,
  25190                       (vlan_valid) ? encap_config->vlan : 0);
  25191     soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 1);
  25192     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val));
  25193 
  25194     /* Configure EHG-tpid */
  25195     if (vlan_valid) {
  25196         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val));
  25197         soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf,
  25198                           encap_config->tpid);
  25199         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val));
  25200     }
  25201 
  25202     return _bcm_port_ip4_tunnel_header_set(unit, port, encap_config);
  25203 }
  25204 
  25205 /*
  25206  * Function:
  25207  *      _bcm_port_hgoe_transport_mode_set
  25208  * Purpose:
  25209  *      Set the port into Higig over Ethernet transport mode
  25210  * Parameters:
  25211  *      unit            - (IN) device id
  25212  *      port            - (IN) Physical port
  25213  *      encap_config    - (IN) structure describes port encapsulation configuration
  25214  * Returns:
  25215  *      BCM_E_XXX
  25216  */
  25217 STATIC int
  25218 _bcm_port_hgoe_transport_mode_set(int unit, bcm_port_t port,
  25219                                  bcm_port_encap_config_t *encap_config)
  25220 {
  25221     uint64 val64;
  25222     uint32 val;
  25223 
  25224 
  25225     if (IS_HG_PORT(unit, port)) {
  25226         return BCM_E_CONFIG;
  25227     }
  25228 #if defined(BCM_TRIDENT3_SUPPORT)
  25229     if (SOC_IS_TRIDENT3X(unit)) {
  25230         if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap) {
  25231             return bcm_td3_port_hgoe_mode_set(unit, port);
  25232         } else {
  25233             return BCM_E_UNAVAIL;
  25234         }
  25235     }
  25236 #endif
  25237     /* Configure HGoE TX control */
  25238     if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) {
  25239         BCM_IF_ERROR_RETURN
  25240             (soc_mem_field32_modify(unit, EGR_PORTm, port, PORT_TYPEf,
  25241                                     encap_config->encap ==
  25242                                     BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  25243                                     1 : 0));
  25244         BCM_IF_ERROR_RETURN
  25245             (soc_mem_field32_modify(unit, EGR_PORTm, port, HG_TYPEf,
  25246                                     BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  25247     }
  25248 
  25249     if (SOC_REG_IS_VALID(unit, EGR_EHG_ETHERTYPEr)) {
  25250         BCM_IF_ERROR_RETURN
  25251             (soc_reg32_get(unit, EGR_EHG_ETHERTYPEr, port, 0, &val));
  25252         soc_reg_field_set(unit, EGR_EHG_ETHERTYPEr,
  25253                           &val, ETHERTYPEf, encap_config->higig_ethertype);
  25254         BCM_IF_ERROR_RETURN
  25255             (soc_reg32_set(unit, EGR_EHG_ETHERTYPEr, port, 0, val));
  25256     }
  25257 
  25258     if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) {
  25259         BCM_IF_ERROR_RETURN
  25260             (soc_reg32_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val));
  25261         soc_reg_field_set(unit, EGR_EHG_HEADER_CONTROLr,
  25262                           &val, EHG_RESERVEDf, encap_config->hgoe_reserved);
  25263         BCM_IF_ERROR_RETURN
  25264             (soc_reg32_set(unit, EGR_EHG_HEADER_CONTROLr, port, 0, val));
  25265     }
  25266 
  25267     /* Configure HGoE RX control */
  25268     if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, HG_TYPEf)) {
  25269         BCM_IF_ERROR_RETURN
  25270             (_bcm_esw_port_tab_set(unit, port,
  25271                                    _BCM_CPU_TABS_NONE, PORT_TYPEf,
  25272                                    encap_config->encap ==
  25273                                    BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  25274                                    1 : 0));
  25275 
  25276         BCM_IF_ERROR_RETURN
  25277             (_bcm_esw_port_tab_set(unit, port,
  25278                                    _BCM_CPU_TABS_NONE, HG_TYPEf,
  25279                                    BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  25280     }
  25281 
  25282     if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) {
  25283         BCM_IF_ERROR_RETURN
  25284             (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf,
  25285                                     encap_config->encap ==
  25286                                     BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  25287                                     1 : 0));
  25288         BCM_IF_ERROR_RETURN
  25289             (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, HG_TYPEf,
  25290                                     BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  25291     }
  25292 
  25293     if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) {
  25294         uint64 v64;
  25295         COMPILER_64_SET(v64, 0, encap_config->higig_ethertype);
  25296         BCM_IF_ERROR_RETURN
  25297             (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0,
  25298                          &val64));
  25299         soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr,
  25300                             &val64, ETHERTYPEf, v64);
  25301         BCM_IF_ERROR_RETURN
  25302             (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0,
  25303                          val64));
  25304     }
  25305 
  25306     /* Enable HGoE */
  25307     if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) {
  25308         uint64 one = COMPILER_64_INIT(0, 1);
  25309         BCM_IF_ERROR_RETURN
  25310             (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  25311                          &val64));
  25312         soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r,
  25313                             &val64, TRANSPORT_ENf, one);
  25314         BCM_IF_ERROR_RETURN
  25315             (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  25316                          val64));
  25317     }
  25318 #ifdef BCM_TRX_SUPPORT
  25319     /* Set the vlan default action */
  25320     if (soc_feature(unit, soc_feature_vlan_action) &&
  25321         (!SOC_IS_TRIDENT3X(unit))) {
  25322         bcm_vlan_action_set_t action;
  25323 
  25324         BCM_IF_ERROR_RETURN
  25325             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  25326                                                         port, &action));
  25327         /* Backward compatible defaults */
  25328         action.ot_outer = bcmVlanActionDelete;
  25329         action.dt_outer = bcmVlanActionDelete;
  25330         BCM_IF_ERROR_RETURN
  25331             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  25332                                                         port, &action));
  25333     }
  25334 #endif
  25335 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_TX_HGOE_LIMITED_SOLUTION)
  25336     if (SOC_IS_TRIDENT2PLUS(unit)
  25337         && SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  25338         icontrol_opcode_bitmap_entry_t entry;
  25339         soc_pbmp_t pbmp;
  25340 
  25341         SOC_IF_ERROR_RETURN
  25342             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  25343         SOC_PBMP_CLEAR(pbmp);
  25344         SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  25345         soc_mem_pbmp_field_set(unit,
  25346                             ICONTROL_OPCODE_BITMAPm, &entry, BITMAPf, &pbmp);
  25347         SOC_IF_ERROR_RETURN
  25348             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  25349     }
  25350 #endif /* BCM_TRIDENT2PLUS_SUPPORT && BCM_TX_HGOE_LIMITED_SOLUTION */
  25351 
  25352     return BCM_E_NONE;
  25353 }
  25354 
  25355 
  25356 /*
  25357  * Function:
  25358  *      _bcm_esw_port_encap_higig_lite_set
  25359  * Purpose:
  25360  *      Helper function to force a port into HIGIG2_LITE mode
  25361  * Parameters:
  25362  *      unit            - (IN) device id
  25363  *      port            - (IN) port number
  25364  * Returns:
  25365  *      BCM_E_XXX
  25366  */
  25367 STATIC int
  25368 _bcm_esw_port_encap_higig_lite_set(int unit, bcm_port_t port)
  25369 {
  25370     soc_port_ability_t  ability;
  25371     int                 an, an_done;
  25372     int rv = BCM_E_CONFIG;
  25373 
  25374     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  25375         return bcmi_esw_portctrl_encap_higig_lite_set(unit, port);
  25376     }
  25377 
  25378     sal_memset(&ability, 0, sizeof(soc_port_ability_t));
  25379 
  25380     if (soc_feature(unit, soc_feature_hg_no_speed_change)) {
  25381         /* HG-Lite process without 2.5G speed setting can calls to
  25382             * _bcm_port_encap_xport_set() directly.
  25383             */
  25384         return _bcm_port_encap_xport_set(unit, port,
  25385                                          BCM_PORT_ENCAP_HIGIG2_LITE, TRUE);
  25386     } else {
  25387         if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port) ||
  25388                 (SOC_IS_METROLITE(unit) && IS_XL_PORT(unit, port))) {
  25389             /* Restrict the speed to <= 2.5G and set the encap to HG2 */
  25390             if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  25391                 rv = _bcm_port_encap_xport_set(unit, port,
  25392                                                BCM_PORT_ENCAP_HIGIG2_LITE,
  25393                                                TRUE);
  25394                 if (rv != BCM_E_NONE) {
  25395                     return rv;
  25396                 }
  25397                 SOC_IF_ERROR_RETURN
  25398                          (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500));
  25399             }
  25400             if((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && IS_XE_PORT(unit, port)) {
  25401                /*Restrict the speed to <= 2.5G and set the encap to HG_LITE*/
  25402                 rv = _bcm_port_encap_xport_set(unit, port,
  25403                                                BCM_PORT_ENCAP_HIGIG2_LITE,
  25404                                                TRUE);
  25405                 if (rv != BCM_E_NONE) {
  25406                     return rv;
  25407                 }
  25408                 SOC_IF_ERROR_RETURN
  25409                          (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500));
  25410             }
  25411             BCM_IF_ERROR_RETURN(
  25412                 soc_phyctrl_ability_local_get(unit, port, &ability));
  25413 
  25414             ability.speed_full_duplex &= ~(SOC_PA_SPEED_10GB |
  25415                     SOC_PA_SPEED_12GB | SOC_PA_SPEED_13GB | SOC_PA_SPEED_15GB |
  25416                     SOC_PA_SPEED_16GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB |
  25417                     SOC_PA_SPEED_25GB | SOC_PA_SPEED_30GB | SOC_PA_SPEED_40GB);
  25418 
  25419             BCM_IF_ERROR_RETURN(
  25420                 soc_phyctrl_ability_advert_set(unit, port, &ability));
  25421             BCM_IF_ERROR_RETURN(
  25422                 soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  25423             if (!an) {
  25424                 BCM_IF_ERROR_RETURN(
  25425                     soc_phyctrl_speed_set(unit, port, 2500));
  25426             }
  25427             if (!SOC_IS_SABER2(unit) && !SOC_IS_KATANA2(unit) && !SOC_IS_HURRICANE2(unit)) {
  25428                 return _bcm_port_encap_xport_set(unit, port,
  25429                                                  BCM_PORT_ENCAP_HIGIG2, TRUE);
  25430             }
  25431         } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) {
  25432             return _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_HIGIG2);
  25433         }
  25434     } /* if soc_feature(soc_feature_hg_no_speed_change) */
  25435 
  25436     return rv;
  25437 }
  25438 
  25439 
  25440 /*
  25441  * Function:
  25442  *      bcm_esw_port_encap_config_set
  25443  * Purpose:
  25444  *      Set the port encapsulation
  25445  * Parameters:
  25446  *      unit            - (IN) device id
  25447  *      gport           - (IN) Generic port
  25448  *      encap_config    - (IN) structure describes port encapsulation configuration
  25449  * Returns:
  25450  *      BCM_E_XXX
  25451  */
  25452 int
  25453 bcm_esw_port_encap_config_set(int unit, bcm_gport_t gport,
  25454                                   bcm_port_encap_config_t *encap_config)
  25455 {
  25456     bcm_port_t  port;
  25457     int         rv = BCM_E_UNAVAIL, curr_mode=0;
  25458     soc_info_t  *si = &SOC_INFO(unit);
  25459     bcm_stg_t        stg = 0;
  25460 
  25461     if (NULL == encap_config) {
  25462         return BCM_E_PARAM;
  25463     }
  25464     /* Make sure port module is initialized. */
  25465     PORT_INIT(unit);
  25466 
  25467     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port));
  25468     if(bcm_common_oamp_port_enable_get(unit, port)) {
  25469         LOG_ERROR(BSL_LS_BCM_PORT,
  25470                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  25471                    port));
  25472         return BCM_E_PARAM;
  25473     }
  25474 
  25475 
  25476     if (encap_config->encap != BCM_PORT_ENCAP_HIGIG2_L2 &&
  25477         encap_config->encap != BCM_PORT_ENCAP_HIGIG2_LITE &&
  25478         encap_config->encap != BCM_PORT_ENCAP_HIGIG2_IP_GRE &&
  25479         encap_config->encap != BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  25480         return bcm_esw_port_encap_set(unit, port, encap_config->encap);
  25481     }
  25482 
  25483     if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE &&
  25484         (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || SOC_IS_RAVEN(unit)
  25485         || SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit))) {
  25486         return bcm_esw_port_encap_set(unit, port, encap_config->encap);
  25487     }
  25488 
  25489     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  25490         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  25491         return (BCM_E_UNAVAIL);
  25492     }
  25493 
  25494 #if defined(BCM_SABER2_SUPPORT)
  25495     if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) {
  25496         if(!IS_XL_PORT(unit, port)) {
  25497             /* On saber2 non XL port, shouldn't have reached till here */
  25498             return BCM_E_UNAVAIL;
  25499         }
  25500     }
  25501 #endif
  25502 #if defined(BCM_TRIDENT3_SUPPORT)
  25503     if (SOC_IS_TRIDENT3X(unit)
  25504         && encap_config->encap == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  25505 
  25506         if (!soc_feature(unit, soc_feature_higig_over_ethernet)) {
  25507             return BCM_E_UNAVAIL;
  25508         }
  25509     }
  25510 #endif
  25511     PORT_LOCK(unit);
  25512 
  25513     if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE) {
  25514         rv = _bcm_esw_port_encap_higig_lite_set(unit, port);
  25515     } else {
  25516         if ((IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))) {
  25517             if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) {
  25518                 rv = BCM_E_NONE;
  25519                 rv = bcm_esw_port_encap_get(unit, port, &curr_mode);
  25520                 if ((BCM_SUCCESS(rv)) && (curr_mode != BCM_PORT_ENCAP_IEEE)) {
  25521                     rv = _bcm_port_encap_xport_set(unit, port,
  25522                                                    BCM_PORT_ENCAP_IEEE, TRUE);
  25523                 }
  25524             } else {
  25525                 rv = _bcm_port_encap_xport_set(unit, port,
  25526                                                BCM_PORT_ENCAP_IEEE, TRUE);
  25527             }
  25528             /* Update soc_info_t after changing port to ethernet */
  25529             soc_xport_type_update(unit, port, 0);
  25530         } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) {
  25531             rv = _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_IEEE);
  25532         }
  25533     }
  25534 
  25535     if (BCM_SUCCESS(rv)) {
  25536         if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) {
  25537             rv = _bcm_port_ehg_transport_mode_set(unit, port, encap_config);
  25538         } else if (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config->encap){
  25539             rv = _bcm_port_ehg_tunnel_mode_set(unit, port, encap_config);
  25540         } else if (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config->encap){
  25541             rv = soc_reg_field32_modify(unit, EHG_RX_REG(unit),
  25542                                         port, MODEf, 2);
  25543         } else if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap){
  25544             rv = _bcm_port_hgoe_transport_mode_set(unit, port, encap_config);
  25545         }
  25546     }
  25547 
  25548     /* Embedded Higig ports should be configured and marked as ST ports */
  25549     if (BCM_SUCCESS(rv)) {
  25550         rv = bcm_esw_port_pause_set(unit, port, 0, 0);
  25551     }
  25552     if (BCM_SUCCESS(rv)) {
  25553         /* Stack ports to forwarding */
  25554         rv = bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD);
  25555     }
  25556     if (BCM_SUCCESS(rv)) {
  25557         /* Set untagged state in default VLAN properly */
  25558         rv = _bcm_esw_vlan_untag_update(unit, port, TRUE);
  25559     }
  25560     if (BCM_SUCCESS(rv)) {
  25561         /* Resolve STG 0 */
  25562         rv = bcm_esw_stg_default_get(unit, &stg);
  25563     }
  25564     if (BCM_SUCCESS(rv)) {
  25565         rv = bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD);
  25566     }
  25567     if (BCM_SUCCESS(rv)) {
  25568         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  25569         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  25570         SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port);
  25571     }
  25572 
  25573     PORT_UNLOCK(unit);
  25574 
  25575     return (rv);
  25576 }
  25577 
  25578 /*
  25579  * Function:
  25580  *      bcm_esw_port_encap_config_get
  25581  * Purpose:
  25582  *      Get the port encapsulation
  25583  * Parameters:
  25584  *      unit            - (IN) device id
  25585  *      gport           - (IN) Generic port
  25586  *      encap_config    - (OUT) structure describes port encapsulation configuration
  25587  * Returns:
  25588  *      BCM_E_XXX
  25589  */
  25590 int
  25591 bcm_esw_port_encap_config_get(int unit, bcm_gport_t gport,
  25592                                   bcm_port_encap_config_t *encap_config)
  25593 {
  25594     bcm_port_t      port;
  25595     uint32          val, buffer[16];   /* 64 bytes max EHG header size */
  25596     uint64          val64;
  25597     int             rv = BCM_E_NONE, mode = 0;
  25598     soc_reg_t       ehg_tx_reg = EHG_TX_REG(unit);
  25599     soc_reg_t       ehg_rx_reg = EHG_RX_REG(unit);
  25600 
  25601     if (NULL == encap_config) {
  25602         return (BCM_E_PARAM);
  25603     }
  25604     /* Make sure port module is initialized. */
  25605     PORT_INIT(unit);
  25606 
  25607     sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t));
  25608 
  25609     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port));
  25610     if(bcm_common_oamp_port_enable_get(unit, port)) {
  25611         LOG_ERROR(BSL_LS_BCM_PORT,
  25612                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  25613                    port));
  25614         return BCM_E_PARAM;
  25615     }
  25616 
  25617     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  25618         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  25619 
  25620         rv = bcm_esw_port_encap_get(unit, port, &mode);
  25621         if (BCM_SUCCESS(rv)) {
  25622             encap_config->encap = (bcm_port_encap_t)mode;
  25623         }
  25624         return rv;
  25625     }
  25626 
  25627     if (soc_feature(unit, soc_feature_embedded_higig)) {
  25628         /* Check for Raptor-style stacking */
  25629         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  25630         if (soc_reg_field_get(unit, ehg_rx_reg, val, MODEf) == 2) {
  25631             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_LITE;
  25632             return rv;
  25633         }
  25634 
  25635         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  25636         /* If no EHG was programmed the just read port encapsulation */
  25637         if (!soc_reg_field_get(unit, ehg_tx_reg, val, ENABLEf)) {
  25638             rv = bcm_esw_port_encap_get(unit, port, &mode);
  25639             if (BCM_SUCCESS(rv)) {
  25640                 encap_config->encap = (bcm_port_encap_t)mode;
  25641             }
  25642             return rv;
  25643         }
  25644 
  25645         /* EHG is enabled. */
  25646         if (!IS_ST_PORT(unit, port)) {
  25647             return (BCM_E_CONFIG);
  25648         }
  25649 
  25650         BCM_IF_ERROR_RETURN(_bcm_port_ehg_header_read(unit, port, buffer));
  25651 
  25652         if (!soc_reg_field_get(unit, ehg_tx_reg, val, TUNNEL_TYPEf)) {
  25653             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_L2;
  25654             rv = _bcm_port_l2_tunnel_header_parse(unit, port, buffer,
  25655                                                   encap_config);
  25656         } else {
  25657             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_IP_GRE;
  25658             rv = _bcm_port_ipv4_tunnel_header_parse(unit, port, buffer,
  25659                                                     encap_config);
  25660         }
  25661     } else if(soc_feature(unit, soc_feature_higig_over_ethernet)) {
  25662         uint64 v64 = COMPILER_64_INIT(0, 0);
  25663         uint32 v32=0;
  25664 
  25665         /* If HGoE disabled and then just read port encapsulation */
  25666         if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) {
  25667             BCM_IF_ERROR_RETURN
  25668              (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  25669                     &val64));
  25670             v64 = soc_reg64_field_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r,
  25671                                     val64, TRANSPORT_ENf);
  25672         }
  25673 #ifdef BCM_TRIDENT3_SUPPORT
  25674         if (SOC_IS_TRIDENT3X(unit)) {
  25675             uint8 is_hgoe = 0;
  25676             BCM_IF_ERROR_RETURN(bcm_td3_port_hgoe_mode_get(
  25677                         unit, port, &is_hgoe));
  25678             if (is_hgoe) {
  25679                 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET;
  25680                 encap_config->higig_ethertype = BCM_TD3_HGOE_HDR_TYPE;
  25681                 return BCM_E_NONE;
  25682             } else {
  25683                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  25684                 if (BCM_SUCCESS(rv)) {
  25685                     encap_config->encap = (bcm_port_encap_t)mode;
  25686                 }
  25687                 return rv;
  25688             }
  25689         } else
  25690 #endif
  25691         if (COMPILER_64_IS_ZERO(v64)) {
  25692             rv = bcm_esw_port_encap_get(unit, port, &mode);
  25693             if (BCM_SUCCESS(rv)) {
  25694                 encap_config->encap = (bcm_port_encap_t)mode;
  25695             }
  25696             return rv;
  25697         }
  25698 
  25699         if (!IS_ST_PORT(unit, port)) {
  25700             return (BCM_E_CONFIG);
  25701         }
  25702 
  25703         sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t));
  25704         encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET;
  25705 
  25706         if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) {
  25707             BCM_IF_ERROR_RETURN
  25708                 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port,
  25709                     0, &val64));
  25710             v64 = soc_reg64_field_get(unit,
  25711                    PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, val64, ETHERTYPEf);
  25712             encap_config->higig_ethertype = (uint16) COMPILER_64_LO(v64);
  25713         }
  25714 
  25715         if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) {
  25716             BCM_IF_ERROR_RETURN
  25717                 (soc_reg_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val64));
  25718             v32 = COMPILER_64_LO(val64);
  25719             encap_config->hgoe_reserved = soc_reg_field_get(unit,
  25720                                 EGR_EHG_HEADER_CONTROLr, v32, EHG_RESERVEDf);
  25721         }
  25722     }
  25723 
  25724     return (rv);
  25725 }
  25726 
  25727 /*
  25728  * Function:
  25729  *      _bcm_esw_port_mirror_lock
  25730  * Purpose:
  25731  *      Take the mirror and port mutexes
  25732  * Parameters:
  25733  *      unit - unit #
  25734  * Returns:
  25735  *      None
  25736  */
  25737 void
  25738 _bcm_esw_port_mirror_lock(int unit) {
  25739     bcm_esw_mirror_lock(unit);
  25740     PORT_LOCK(unit);
  25741 }
  25742 
  25743 /*
  25744  * Function:
  25745  *      _bcm_esw_port_mirror_unlock
  25746  * Purpose:
  25747  *      Give up the mirror and port mutexes
  25748  * Parameters:
  25749  *      unit - unit #
  25750  * Returns:
  25751  *      None
  25752  */
  25753 void
  25754 _bcm_esw_port_mirror_unlock(int unit) {
  25755     PORT_UNLOCK(unit);
  25756     bcm_esw_mirror_unlock(unit);
  25757 }
  25758 
  25759 /*
  25760  * Function:
  25761  *      bcmi_esw_port_encap_set
  25762  * Purpose:
  25763  *      Set the port encapsulation mode
  25764  * Parameters:
  25765  *      unit - StrataSwitch unit #
  25766  *      port - StrataSwitch port #
  25767  *      mode - One of BCM_PORT_ENCAP_xxx (see port.h)
  25768  * Returns:
  25769  *      BCM_E_XXX
  25770  */
  25771 int
  25772 bcmi_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  25773 {
  25774     int         rv=BCM_E_NONE, xport_swap = FALSE;
  25775     int         stport_swap = FALSE;
  25776 #if defined(BCM_KATANA2_SUPPORT)
  25777     uint64      rval64;
  25778     ing_physical_port_table_entry_t ing_entry={{0}};
  25779     ing_physical_port_table_entry_t ing_entry_dup={{0}};
  25780     egr_physical_port_entry_t       egr_entry={{0}};
  25781     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  25782 #endif
  25783 #ifdef BCM_HELIX4_SUPPORT
  25784     uint16 dev_id = 0;
  25785     uint8 rev_id = 0;
  25786 #endif
  25787     /* Make sure port module is initialized. */
  25788     PORT_INIT(unit);
  25789 
  25790     if(bcm_common_oamp_port_enable_get(unit, port)) {
  25791         LOG_ERROR(BSL_LS_BCM_PORT,
  25792                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  25793                    port));
  25794         return BCM_E_PARAM;
  25795     }
  25796 
  25797 #ifdef BCM_HELIX4_SUPPORT
  25798     soc_cm_get_id(unit, &dev_id, &rev_id);
  25799     if ((BCM56548H_DEVICE_ID == dev_id) &&
  25800         (mode == BCM_PORT_ENCAP_IEEE) && ((port >= 46) && (port <= 53))) {
  25801         /* IEEE encap mode shouldn't be supported on WC1 and WC2 for BCM56548H*/
  25802         return BCM_E_UNAVAIL;
  25803     }
  25804 #endif
  25805 
  25806 #if defined(BCM_KATANA2_SUPPORT)
  25807 #if defined(BCM_SABER2_SUPPORT)
  25808     if(SOC_IS_SABER2(unit)) {
  25809         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  25810     }
  25811 #endif
  25812     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  25813         (!((port >= 1) && (port <= max_phy_port)))) {
  25814          return BCM_E_PORT;
  25815     }
  25816 #endif
  25817 
  25818     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25819     LOG_INFO(BSL_LS_BCM_PORT,
  25820              (BSL_META_U(unit,
  25821                          "bcm_esw_port_encap_set: u=%d p=%d mode=%d\n"),
  25822               unit, port, mode));
  25823 #if defined(BCM_METROLITE_SUPPORT)
  25824     if (SOC_IS_METROLITE(unit)){
  25825     if (!BCM_GPORT_IS_SET(port)) {
  25826         if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) {
  25827             return BCM_E_UNAVAIL;
  25828 	}
  25829         if((0 == SOC_PORT_BLOCK_NUMBER(unit, port)) &&
  25830             (mode != BCM_PORT_ENCAP_IEEE)) {
  25831             return BCM_E_UNAVAIL;
  25832         }
  25833     }
  25834 }else
  25835 #endif
  25836 #if defined(BCM_SABER2_SUPPORT)
  25837     if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) {
  25838         if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) {
  25839             return BCM_E_UNAVAIL;
  25840         }
  25841     }
  25842 #endif
  25843 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||\
  25844     defined (BCM_SABER2_SUPPORT)
  25845     if (SOC_IS_GREYHOUND(unit) || SOC_IS_TOMAHAWKX(unit) ||
  25846         SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) ||
  25847         SOC_IS_TRIDENT3X(unit) || SOC_IS_GREYHOUND2(unit)) {
  25848         int encap_mode;
  25849         BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap_mode));
  25850         if (encap_mode == mode) {
  25851             /* no encap set is required */
  25852             return BCM_E_NONE;
  25853         }
  25854     }
  25855 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT || BCM_SABER2_SUPPORT */
  25856 
  25857 #if defined(BCM_HURRICANE3_SUPPORT)
  25858     if (soc_feature(unit, soc_feature_wh2)){
  25859         return bcmi_wh2_port_encap_set(unit, port, mode);
  25860     }
  25861 #endif /* BCM_HURRICANE3_SUPPORT */
  25862     _bcm_esw_port_mirror_lock(unit);
  25863 
  25864     if ((IS_HG_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25865         ((IS_XE_PORT(unit,port) || IS_CE_PORT(unit,port)) &&
  25866          (mode != BCM_PORT_ENCAP_IEEE))) {
  25867         if (soc_feature(unit, soc_feature_xport_convertible)) {
  25868             xport_swap =  TRUE;
  25869         } else {
  25870             /* Ether <=> Higig not allowed on all systems */
  25871             _bcm_esw_port_mirror_unlock(unit);
  25872             return BCM_E_UNAVAIL;
  25873         }
  25874     }
  25875 #if defined(BCM_GREYHOUND_SUPPORT)
  25876     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  25877         SOC_IS_GREYHOUND2(unit)) {
  25878         if ((IS_HG_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) ||
  25879                 (IS_HL_PORT(unit, port) && (mode == BCM_PORT_ENCAP_IEEE))) {
  25880             /* HG port encap swap between HG/HG2/HG-Lite and
  25881              * HG-Lite encap swap to IEEE.
  25882              */
  25883             xport_swap = TRUE;
  25884         } else if (IS_GE_PORT(unit, port)) {
  25885             if ((IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) &&
  25886                     (mode == BCM_PORT_ENCAP_IEEE ||
  25887                     mode == BCM_PORT_ENCAP_HIGIG2_LITE)){
  25888                 /* GE+XL/CL port encap set between IEEE/HG-Lite */
  25889                 xport_swap = TRUE;
  25890             } else {
  25891                 /* unavail encap configuration :
  25892                  *  1. QSGMII port for HG/HG2/HG2-Lite related encap
  25893                  *  2. GE(+XL) port for HG/HG2
  25894                  */
  25895                 _bcm_esw_port_mirror_unlock(unit);
  25896                 return BCM_E_UNAVAIL;
  25897             }
  25898         }
  25899     }
  25900 #endif  /* BCM_GREYHOUND_SUPPORT */
  25901 #if defined(BCM_KATANA_SUPPORT)
  25902     if (SOC_IS_KATANA(unit) && IS_MXQ_PORT(unit,port) &&
  25903                                 IS_GE_PORT(unit,port)) {
  25904         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25905             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  25906                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  25907             stport_swap =  TRUE;
  25908         }
  25909     }
  25910 #endif
  25911 #if defined(BCM_KATANA2_SUPPORT)
  25912     if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) &&
  25913                                  (port >= 25 && port <= 40)) {
  25914         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25915             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  25916                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  25917              stport_swap =  TRUE;
  25918         }
  25919     }
  25920 #endif
  25921 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  25922     /* There could be hg to hg (hg2 -> hg2 lite) which require special processing */
  25923     if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  25924         xport_swap = TRUE;
  25925     }
  25926 #endif
  25927     if (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) {
  25928         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25929             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  25930                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  25931                 stport_swap =  TRUE;
  25932         }
  25933     }
  25934 #ifdef BCM_TRIUMPH3_SUPPORT
  25935     if (SOC_IS_TRIUMPH3(unit) && IS_XT_PORT(unit,port) &&
  25936         !((mode == BCM_PORT_ENCAP_IEEE) || (mode == BCM_PORT_ENCAP_HIGIG2_L2))) {
  25937         /* Ether => Higig not allowed on XT ports */
  25938             _bcm_esw_port_mirror_unlock(unit);
  25939             return BCM_E_UNAVAIL;
  25940     }
  25941     if (SOC_IS_TRIUMPH3(unit) && (mode != BCM_PORT_ENCAP_IEEE) &&
  25942         !IS_HG_PORT(unit, port)) {
  25943         int hp, hgc = 0;
  25944 
  25945         PBMP_HG_ITER(unit, hp) {
  25946             if (!SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit, port), hp)) {
  25947                 hgc++;
  25948             }
  25949         }
  25950         if (hgc+1 > _SOC_TR3_MAX_HG_PORT_COUNT) {
  25951             LOG_ERROR(BSL_LS_BCM_PORT, \
  25952                       (BSL_META_U(unit, \
  25953                                   "Error: Port %d config error "\
  25954                                   "(Higig port count(%d) exceeded) !!\n"),
  25955                        port, hgc));
  25956             _bcm_esw_port_mirror_unlock(unit);
  25957             return BCM_E_RESOURCE;
  25958         }
  25959     }
  25960 #endif /* BCM_TRIUMPH3_SUPPORT */
  25961 
  25962     if (xport_swap) {
  25963         COUNTER_LOCK(unit);
  25964         if ((BCM_PORT_ENCAP_HIGIG2_LITE == mode)) {
  25965             rv = _bcm_esw_port_encap_higig_lite_set(unit, port);
  25966         } else {
  25967             rv = _bcm_port_encap_xport_set(unit, port, mode, TRUE);
  25968         }
  25969 
  25970         COUNTER_UNLOCK(unit);
  25971     } else if (stport_swap) {
  25972         rv = _bcm_port_encap_stport_set(unit, port, mode);
  25973     } else if (IS_HG_PORT(unit, port)) {
  25974         rv = MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode);
  25975     } else if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) {
  25976         if (mode == BCM_PORT_ENCAP_IEEE) {
  25977             bcm_port_encap_config_t encap_config;
  25978 
  25979             rv = bcm_esw_port_encap_config_get(unit, port,
  25980                                                &encap_config);
  25981             if (BCM_SUCCESS(rv)) {
  25982                 if ((BCM_PORT_ENCAP_HIGIG2_L2 == encap_config.encap) ||
  25983                     (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config.encap) ||
  25984                     (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config.encap) ||
  25985                     (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config.encap)) {
  25986                     rv = _bcm_port_encap_stport_set(unit, port,
  25987                                                     BCM_PORT_ENCAP_IEEE);
  25988                 } else {
  25989                     rv = BCM_E_UNAVAIL;
  25990                 }
  25991             }
  25992         } else {
  25993             if ((mode == BCM_PORT_ENCAP_HIGIG2) ||
  25994                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE &&
  25995                  (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) ||
  25996                   SOC_IS_HURRICANEX( unit) || SOC_IS_GREYHOUND(unit) ||
  25997                   SOC_IS_GREYHOUND2(unit)))) {
  25998                 rv = BCM_E_NONE;
  25999             } else {
  26000                 rv = BCM_E_UNAVAIL;
  26001             }
  26002         }
  26003 #if defined(BCM_TRIUMPH3_SUPPORT)
  26004      } else if (IS_CE_PORT(unit, port))  {
  26005          if ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG)
  26006                || (mode == BCM_PORT_ENCAP_IEEE)) {
  26007                     rv = _bcm_port_encap_stport_set(unit, port, mode);
  26008          } else {
  26009              rv = BCM_E_UNAVAIL;
  26010          }
  26011 #endif
  26012     } else if (mode == BCM_PORT_ENCAP_IEEE) {
  26013         rv = BCM_E_NONE;
  26014     } else {
  26015         rv = BCM_E_UNAVAIL;
  26016     }
  26017 
  26018 #ifdef BCM_GXPORT_SUPPORT
  26019     if ( IS_GX_PORT(unit, port)
  26020       || IS_XG_PORT(unit,port)
  26021       || (IS_XQ_PORT(unit, port) &&
  26022          (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)))
  26023       || (IS_XL_PORT(unit, port) &&
  26024          (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  26025           (SOC_IS_SABER2(unit) || SOC_IS_HURRICANE3(unit)) ||
  26026            SOC_IS_GREYHOUND2(unit)))
  26027       || (IS_CL_PORT(unit, port) && (SOC_IS_GREYHOUND2(unit)))
  26028       || (IS_MXQ_PORT(unit, port) && (SOC_IS_KATANAX(unit) && !SOC_IS_SABER2(unit)))
  26029       || ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) ||
  26030            IS_CE_PORT(unit, port)) &&
  26031           (SOC_IS_TRIUMPH3(unit)
  26032            || (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) ||
  26033            SOC_IS_TOMAHAWKX(unit))) ) {
  26034         int hg2 = FALSE;
  26035         soc_reg_t port_config_reg;
  26036         uint32 regval, new_hg_pbm;
  26037         int blk, blk_num, bindex;
  26038 
  26039         if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  26040             hg2 = TRUE;
  26041         }
  26042         if (BCM_SUCCESS(rv)) {
  26043             rv = _bcm_esw_port_higig2_mode_set(unit, port, hg2);
  26044         }
  26045 
  26046         if (IS_CL_PORT(unit, port) &&
  26047             SOC_REG_IS_VALID(unit, CLPORT_CONFIGr)) {
  26048             port_config_reg = CLPORT_CONFIGr;
  26049         } else if (IS_C_PORT(unit, port) &&
  26050             SOC_REG_IS_VALID(unit, CPORT_CONFIGr)) {
  26051             port_config_reg = CPORT_CONFIGr;
  26052         } else if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) {
  26053             port_config_reg = XLPORT_CONFIGr;
  26054         } else if (SOC_REG_IS_VALID(unit, PORT_CONFIGr)) {
  26055             port_config_reg = PORT_CONFIGr;
  26056         } else {
  26057             port_config_reg = XPORT_CONFIGr;
  26058         }
  26059         if (BCM_SUCCESS(rv)) {
  26060 #if defined(BCM_GREYHOUND_SUPPORT)||defined(BCM_GREYHOUND2_SUPPORT)
  26061             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  26062                 SOC_IS_GREYHOUND2(unit)){
  26063                 uint32  port_hg_mode;
  26064 
  26065                 /* XLPORT/CLPORT and PGW register for HIGIG_MODEf is confirmed
  26066                     *  will be '1' for HG/HG+ setting only and '0' for other
  26067                     *  encap mode{IEEE/HG2/HG2-LITE}
  26068                     */
  26069                 port_hg_mode = (mode == BCM_PORT_ENCAP_HIGIG) ? 1 : 0;
  26070                 rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26071                         HIGIG_MODEf, port_hg_mode);
  26072                 if (BCM_FAILURE(rv)) {
  26073                     _bcm_esw_port_mirror_unlock(unit);
  26074                     return rv;
  26075                 }
  26076 
  26077                 /* only port available for HG2 configuration allows PGW encap
  26078                 * setting below
  26079                 */
  26080 #if defined(BCM_GREYHOUND2_SUPPORT)
  26081                 if (SOC_IS_GREYHOUND2(unit)) {
  26082 #ifdef BCM_FIRELIGHT_SUPPORT
  26083                     if (soc_feature(unit, soc_feature_fl)) {
  26084                         rv = soc_firelight_pgw_encap_field_modify(unit,
  26085                                 port, HIGIG_MODEf, port_hg_mode);
  26086                     } else
  26087 #endif /* BCM_FIRELIGHT_SUPPORT */
  26088                     {
  26089                         rv = soc_greyhound2_pgw_encap_field_modify(unit,
  26090                                 port, HIGIG_MODEf, port_hg_mode);
  26091                     }
  26092                 } else
  26093 #endif /* BCM_GREYHOUND2_SUPPORT */
  26094                 {
  26095                     rv = soc_greyhound_pgw_encap_field_modify(unit,
  26096                             port, HIGIG_MODEf, port_hg_mode);
  26097                 }
  26098                 if (BCM_FAILURE(rv)) {
  26099                     _bcm_esw_port_mirror_unlock(unit);
  26100                     return rv;
  26101                 }
  26102             } else
  26103 #endif /* BCM_GREYHOUND_SUPPORT||BCM_GREYHOUND2_SUPPORT */
  26104             {
  26105 #if defined(BCM_SABER2_SUPPORT)
  26106                 if(SOC_IS_SABER2(unit)) {
  26107                     /* For Saber2, configure IECELL along with XLPORT */
  26108                     if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) {
  26109                         if ((mode == BCM_PORT_ENCAP_HIGIG2) ||
  26110                                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) ||
  26111                                 (mode == BCM_PORT_ENCAP_HIGIG)) {
  26112                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  26113                                     HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  26114                                     1 : 0);
  26115                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  26116                                     HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  26117                                     0 : 1);
  26118                         } else {
  26119                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  26120                                     HIGIG2_MODEf, 0);
  26121                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  26122                                     HIGIG_MODEf, 0);
  26123                         }
  26124                     }
  26125                 }
  26126 #endif
  26127 #ifdef BCM_KATANA2_SUPPORT
  26128                 if (SOC_IS_KATANA2(unit)) {
  26129                     if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) {
  26130                         if ((mode == BCM_PORT_ENCAP_HIGIG2) ||
  26131                                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) ||
  26132                                 (mode == BCM_PORT_ENCAP_HIGIG)) {
  26133 
  26134                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26135                                     HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  26136                                     1 : 0);
  26137                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26138                                     HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  26139                                     0 : 1);
  26140                         } else {
  26141                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26142                                     HIGIG2_MODEf, 0);
  26143                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26144                                     HIGIG_MODEf, 0);
  26145                         }
  26146                     }
  26147                 } else
  26148 #endif
  26149                 {
  26150                     if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) {
  26151                         rv = soc_reg_field32_modify(unit, port_config_reg, port,
  26152                                         HIGIG_MODEf, mode == BCM_PORT_ENCAP_IEEE ?
  26153                                         0 : 1);
  26154                     }
  26155                     if (SOC_IS_TOMAHAWKX(unit)) {
  26156                         if (IS_CL_PORT(unit, port) &&
  26157                             (mode == BCM_PORT_ENCAP_HIGIG)) {
  26158                             if (SOC_REG_FIELD_VALID(unit, port_config_reg,
  26159                                 HIGIG2_MODEf)) {
  26160                                 rv = soc_reg_field32_modify(unit,
  26161                                         port_config_reg, port, HIGIG2_MODEf, 1);
  26162                             }
  26163                         }
  26164                     }
  26165                 }
  26166             }
  26167         }
  26168         if (BCM_SUCCESS(rv)) {
  26169             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  26170                     soc_mem_field_valid(unit, EGR_PORTm, PORT_TYPEf)) {
  26171                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  26172                                             PORT_TYPEf, mode == BCM_PORT_ENCAP_IEEE ?
  26173                                             0 : 1);
  26174             }
  26175         }
  26176         if (SOC_IS_TRIUMPH3(unit) && (mode == BCM_PORT_ENCAP_IEEE)) {
  26177             /* Disable E2ECC */
  26178             if (soc_feature(unit, soc_feature_logical_port_num)) {
  26179                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  26180                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  26181             } else{
  26182                 blk = SOC_PORT_BLOCK(unit, port);
  26183                 bindex = SOC_PORT_BINDEX(unit, port);
  26184             }
  26185             blk_num = SOC_BLOCK_INFO(unit, blk).number;
  26186             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  26187             if (IS_CL_PORT(unit, port) || (blk == 13)) {
  26188                 if (IS_CL_PORT(unit, port)) {
  26189                     blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  26190                     bindex = bindex%4;
  26191                 } else {
  26192                     blk_num = 3;
  26193                 }
  26194 #if defined(BCM_KATANA2_SUPPORT)
  26195                 if (SOC_IS_KATANA2(unit)) {
  26196                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  26197                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  26198                 }
  26199 #endif
  26200                 rv = READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, &regval);
  26201                 if (BCM_FAILURE(rv)) {
  26202                     _bcm_esw_port_mirror_unlock(unit);
  26203                     return rv;
  26204                 }
  26205                 if (regval & (1 << bindex)) {
  26206                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  26207                                                    TX_ENABLE_BMPf);
  26208                     new_hg_pbm &= ~(1 << bindex);
  26209                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  26210                                       TX_ENABLE_BMPf, new_hg_pbm);
  26211                     rv = WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval);
  26212                 }
  26213             }
  26214         }
  26215     }
  26216 #endif /* BCM_GXPORT_SUPPORT */
  26217 
  26218     if (soc_feature(unit, soc_feature_embedded_higig)) {
  26219         /* Clear embedded Higig regs, if present */
  26220         soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  26221         soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  26222 
  26223         if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_tx_reg)) {
  26224             rv = soc_reg32_set(unit, ehg_tx_reg, port, 0, 0);
  26225         }
  26226         if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_rx_reg)) {
  26227             rv = soc_reg32_set(unit, ehg_rx_reg, port, 0, 0);
  26228         }
  26229     }
  26230 
  26231 #ifdef BCM_HIGIG2_SUPPORT
  26232     /* Update cached version of HiGig2 encapsulation */
  26233     if (BCM_SUCCESS(rv)) {
  26234         if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  26235             SOC_HG2_ENABLED_PORT_ADD(unit, port);
  26236 
  26237             if(SOC_IS_SABER2(unit)){
  26238                 if(mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  26239                     SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  26240                 } else {
  26241                     SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  26242                 }
  26243             }
  26244         } else {
  26245             SOC_HG2_ENABLED_PORT_REMOVE(unit, port);
  26246             if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  26247                 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  26248             }
  26249         }
  26250     }
  26251 #endif /* BCM_HIGIG2_SUPPORT */
  26252 
  26253 #ifdef BCM_KATANA2_SUPPORT
  26254     if (BCM_SUCCESS(rv)) {
  26255         if (SOC_IS_KATANA2(unit)) {
  26256             int hdr_mode = 0;
  26257 
  26258             do {
  26259                 rv = soc_mem_read(unit, ING_PHYSICAL_PORT_TABLEm,
  26260                                   MEM_BLOCK_ANY, port, &ing_entry);
  26261                 sal_memcpy(&ing_entry_dup,&ing_entry,
  26262                            sizeof(ing_physical_port_table_entry_t));
  26263                 if (BCM_FAILURE(rv)) {
  26264                     LOG_ERROR(BSL_LS_BCM_PORT,
  26265                               (BSL_META_U(unit,
  26266                                           "Error: Encap Set: "
  26267                                           "ING_PHYSICAL_PORT_TABLEm read failure")));
  26268                     break;
  26269                 }
  26270                 rv = soc_mem_read(unit, EGR_PHYSICAL_PORTm,
  26271                                   MEM_BLOCK_ANY, port, &egr_entry);
  26272                 if (BCM_FAILURE(rv)) {
  26273                     LOG_ERROR(BSL_LS_BCM_PORT,
  26274                               (BSL_META_U(unit,
  26275                                           "Error: Encap Set: "
  26276                                           "EGR_PHYSICAL_PORTm read failure")));
  26277                     break;
  26278                 }
  26279                 /* Initialize */
  26280                 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  26281                                     &ing_entry, PORT_TYPEf, 0);
  26282                 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  26283                                     &ing_entry, HIGIG2f, 0);
  26284                 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  26285                                     &egr_entry, PORT_TYPEf, 0);
  26286                 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  26287                                     &egr_entry, HIGIG2f, 0);
  26288                 if ((mode == BCM_PORT_ENCAP_HIGIG) ||
  26289                     (mode == BCM_PORT_ENCAP_HIGIG2) ||
  26290                     (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) {
  26291                      if (((mode == BCM_PORT_ENCAP_HIGIG2) ||
  26292                           (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) &&
  26293                            soc_feature(unit, soc_feature_higig2)) {
  26294                          if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  26295                              hdr_mode = 0; /* Ieee mode */
  26296                          } else {
  26297                              hdr_mode = 2; /* Higig2 */
  26298                          }
  26299                          soc_mem_field32_set(unit,
  26300                                              ING_PHYSICAL_PORT_TABLEm,
  26301                                              &ing_entry, HIGIG2f, 1);
  26302                          soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  26303                                              &egr_entry, HIGIG2f, 1);
  26304                     } else {
  26305                         hdr_mode = 1; /* HG, hg+ */
  26306                     }
  26307                     soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  26308                             &ing_entry, PORT_TYPEf, 1);
  26309                     soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  26310                             &egr_entry, PORT_TYPEf, 1);
  26311                 } else {
  26312                     hdr_mode = 0; /* Ieee mode */
  26313                 }
  26314                 if (SOC_REG_IS_VALID(unit, XMAC_MODEr)) {
  26315                     rv = READ_XMAC_MODEr(unit,port, &rval64);
  26316                     if (BCM_FAILURE(rv)) {
  26317                         _bcm_esw_port_mirror_unlock(unit);
  26318                         return rv;
  26319                     }
  26320                     soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf, hdr_mode);
  26321                     rv = WRITE_XMAC_MODEr(unit, port, rval64);
  26322                     if (BCM_FAILURE(rv)) {
  26323                         _bcm_esw_port_mirror_unlock(unit);
  26324                         return rv;
  26325                     }
  26326                 }
  26327                 if (SOC_REG_IS_VALID(unit, XLMAC_MODEr)) {
  26328                     rv = READ_XLMAC_MODEr(unit,port, &rval64);
  26329                     if (BCM_FAILURE(rv)) {
  26330                         _bcm_esw_port_mirror_unlock(unit);
  26331                         return rv;
  26332                     }
  26333                     soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64,HDR_MODEf, hdr_mode);
  26334                     rv = WRITE_XLMAC_MODEr(unit, port, rval64);
  26335                     if (BCM_FAILURE(rv)) {
  26336                         _bcm_esw_port_mirror_unlock(unit);
  26337                         return rv;
  26338                     }
  26339                 }
  26340 
  26341                 if (sal_memcmp(&ing_entry_dup,&ing_entry,
  26342                                sizeof(ing_physical_port_table_entry_t)) == 0) {
  26343                     LOG_VERBOSE(BSL_LS_BCM_PORT,
  26344                                 (BSL_META_U(unit,
  26345                                             "##No Change in  entry so skipping write##\n")));
  26346                     rv = BCM_E_NONE;
  26347                 } else {
  26348                     LOG_ERROR(BSL_LS_BCM_PORT,
  26349                               (BSL_META_U(unit,
  26350                                           "##Change in  entry so Need to update##\n")));
  26351                     rv = soc_mem_write(unit, ING_PHYSICAL_PORT_TABLEm,
  26352                                        MEM_BLOCK_ALL, port, &ing_entry);
  26353                 }
  26354                 if (BCM_FAILURE(rv)) {
  26355                     LOG_ERROR(BSL_LS_BCM_PORT,
  26356                               (BSL_META_U(unit,
  26357                                           "Error: Encap Set: "
  26358                                           "ING_PHYSICAL_PORT_TABLEm write failure")));
  26359                     break;
  26360                 }
  26361                 rv = soc_mem_write(unit, EGR_PHYSICAL_PORTm,
  26362                                    MEM_BLOCK_ALL, port, &egr_entry);
  26363                 if (BCM_FAILURE(rv)) {
  26364                     LOG_ERROR(BSL_LS_BCM_PORT,
  26365                               (BSL_META_U(unit,
  26366                                           "Error: Encap Set: "
  26367                                           "EGR_PHYSICAL_PORTm write failure")));
  26368                     break;
  26369                 }
  26370 
  26371 #ifdef BCM_KATANA2_SUPPORT
  26372                 if (SOC_IS_KATANA2(unit )) {
  26373                     rv =  _bcm_kt2_cosq_dynamic_port_encap_change(unit,port);
  26374                     if (BCM_FAILURE(rv)) {
  26375                     LOG_ERROR(BSL_LS_BCM_PORT,
  26376                               (BSL_META_U(unit,
  26377                                  "Error: Encap Set: "
  26378                                  "MMU config failure")));
  26379                         break;
  26380                     }
  26381                 }
  26382 #endif
  26383 
  26384             }while (0);
  26385         }
  26386     }
  26387 #endif
  26388 
  26389 #if defined(BCM_XMAC_SUPPORT)
  26390    if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  26391       SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  26392        uint32          vco_disturbed = 0;
  26393        phy_ctrl_t      *int_pc;
  26394        if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  26395                    IS_XE_PORT(unit, port))) {
  26396 
  26397            int_pc = INT_PHY_SW_STATE(unit, port);
  26398            rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  26399            if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  26400                _bcm_esw_port_mirror_unlock(unit);
  26401                return rv;
  26402            }
  26403            if (vco_disturbed) {
  26404                rv = _mac_x_reinit(unit, port);
  26405                if (BCM_FAILURE(rv)) {
  26406                    _bcm_esw_port_mirror_unlock(unit);
  26407                    return rv;
  26408                }
  26409            }
  26410        }
  26411    }
  26412 #endif
  26413     _bcm_esw_port_mirror_unlock(unit);
  26414 
  26415     return rv;
  26416 }
  26417 
  26418 
  26419 /*
  26420  * Function:
  26421  *      bcmi_esw_port_encap_validate
  26422  * Purpose:
  26423  *      Check if the encap change for this port can be acceptable or not.
  26424  * Parameters:
  26425  *      unit     - (IN) Unit number
  26426  *      port     - (IN) Logical port number
  26427  *      encap    - (IN) encap mode
  26428  *      speed    - (IN) speed
  26429  * Returns:
  26430  *      BCM_E_NONE
  26431  *      BCM_E_XXX
  26432  * Notes:
  26433  */
  26434 STATIC int
  26435 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed)
  26436 {
  26437 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  26438     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26439 
  26440     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  26441         if (BCM_ESW_PORT_DRV(unit)->encap_speed_check != NULL) {
  26442             BCM_IF_ERROR_RETURN
  26443                 (BCM_ESW_PORT_DRV(unit)->encap_speed_check(unit, port,
  26444                                                            mode, speed));
  26445         }
  26446     }
  26447     return BCM_E_NONE;
  26448 #else
  26449     return BCM_E_NONE;
  26450 #endif
  26451 }
  26452 
  26453 STATIC int
  26454 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  26455 {
  26456     int rv;
  26457 #if defined(BCM_TOMAHAWK2_SUPPORT)
  26458     int asf_mode;
  26459 #endif /* BCM_TOMAHAWK2_SUPPORT */
  26460 
  26461 
  26462 #if defined(BCM_TOMAHAWK3_SUPPORT)
  26463     if (SOC_IS_TOMAHAWK3(unit)) {
  26464         return BCM_E_NONE;
  26465     }
  26466 #endif /* BCM_TOMAHAWK3_SUPPORT */
  26467 
  26468 #if defined(BCM_TOMAHAWK2_SUPPORT)
  26469     if (SOC_IS_TOMAHAWK2(unit)) {
  26470         BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &asf_mode));
  26471         if (asf_mode != _SOC_TH_ASF_MODE_SAF) {
  26472             BCM_IF_ERROR_RETURN
  26473                 (bcm_esw_port_asf_mode_set(unit, port, _SOC_TH_ASF_MODE_SAF));
  26474         }
  26475     }
  26476 #endif /* BCM_TOMAHAWK2_SUPPORT */
  26477 
  26478     /* Call Port Control module */
  26479     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  26480         rv = bcmi_esw_portctrl_encap_set(unit, port, mode, FALSE);
  26481     } else {
  26482         rv = bcmi_esw_port_encap_set(unit, port, mode);
  26483     }
  26484 
  26485 #if defined(BCM_TOMAHAWK2_SUPPORT)
  26486     if (SOC_IS_TOMAHAWK2(unit)) {
  26487         if (asf_mode != _SOC_TH_ASF_MODE_SAF) {
  26488             BCM_IF_ERROR_RETURN
  26489                 (bcm_esw_port_asf_mode_set(unit, port, asf_mode));
  26490         }
  26491     }
  26492 #endif /* BCM_TOMAHAWK2_SUPPORT */
  26493 
  26494     return rv;
  26495 }
  26496 
  26497 /*
  26498  * Function:
  26499  *      bcm_port_encap_set
  26500  * Purpose:
  26501  *      Set the port encapsulation mode
  26502  * Parameters:
  26503  *      unit - StrataSwitch unit #
  26504  *      port - StrataSwitch port #
  26505  *      mode - One of BCM_PORT_ENCAP_xxx (see port.h)
  26506  * Returns:
  26507  *      BCM_E_XXX
  26508  */
  26509 int
  26510 bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  26511 {
  26512     /* Make sure port module is initialized. */
  26513     PORT_INIT(unit);
  26514 
  26515     BCM_IF_ERROR_RETURN(bcmi_esw_port_encap_validate(unit, port, mode, 0));
  26516     BCM_IF_ERROR_RETURN(_bcm_esw_port_encap_set(unit, port, mode));
  26517 
  26518     return BCM_E_NONE;
  26519 }
  26520 
  26521 /*
  26522  * Function:
  26523  *      bcm_port_encap_get
  26524  * Purpose:
  26525  *      Get the port encapsulation mode
  26526  * Parameters:
  26527  *      unit - StrataSwitch unit #
  26528  *      port - StrataSwitch port #
  26529  *      mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h)
  26530  * Returns:
  26531  *      BCM_E_XXX
  26532  */
  26533 
  26534 int
  26535 bcm_esw_port_encap_get(int unit, bcm_port_t port, int *mode)
  26536 {
  26537 
  26538 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_KATANA_SUPPORT)
  26539    int speed_mode = 0;
  26540    uint64 rval64;
  26541 #endif
  26542 
  26543 #if defined(BCM_KATANA2_SUPPORT)
  26544    int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  26545 #endif
  26546 
  26547     *mode = -1;
  26548 
  26549     /* Make sure port module is initialized. */
  26550     PORT_INIT(unit);
  26551 
  26552     /* Call Port Control module */
  26553     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  26554         return (bcmi_esw_portctrl_encap_get(unit, port, mode));
  26555     }
  26556     if(bcm_common_oamp_port_enable_get(unit, port)) {
  26557         LOG_ERROR(BSL_LS_BCM_PORT,
  26558                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  26559                    port));
  26560         return BCM_E_PARAM;
  26561     }
  26562 
  26563 
  26564 #if defined(BCM_KATANA2_SUPPORT)
  26565 #if defined(BCM_SABER2_SUPPORT)
  26566    if(SOC_IS_SABER2(unit)) {
  26567        max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  26568    }
  26569 #endif
  26570     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  26571         (!((port >= 1) && (port <= max_phy_port)))) {
  26572          return BCM_E_PORT;
  26573     }
  26574 #endif
  26575 
  26576     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26577 
  26578 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT)
  26579     if (SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit) ||
  26580         SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) {
  26581         if (IS_HL_PORT(unit, port)) {
  26582             *mode = BCM_PORT_ENCAP_HIGIG2;
  26583 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  26584             if (SOC_IS_KATANAX(unit)) {
  26585                 if (SOC_REG_PORT_VALID(unit, XMAC_MODEr, port)) {
  26586                     SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval64));
  26587                     speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64,
  26588                                                        SPEED_MODEf);
  26589 
  26590                 } else if (SOC_REG_PORT_VALID(unit, XLMAC_MODEr, port)) {
  26591 
  26592                     SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval64));
  26593                     speed_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval64,
  26594                                                        SPEED_MODEf);
  26595                 }
  26596 #if defined(BCM_METROLITE_SUPPORT)
  26597                 if (SOC_IS_METROLITE(unit)) {
  26598                     /* 2.5G and 1G speed in HIGIG2_LITE */
  26599                     if ((speed_mode == 3)||(speed_mode == 2)) {
  26600                         *mode = BCM_PORT_ENCAP_HIGIG2_LITE;
  26601                     }
  26602                 } else
  26603 #endif
  26604                 if (speed_mode == 3) {
  26605                     *mode = BCM_PORT_ENCAP_HIGIG2_LITE;
  26606                  }
  26607              }
  26608 #endif
  26609         } else {
  26610             SOC_IF_ERROR_RETURN
  26611                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  26612         }
  26613     } else
  26614 #endif  /* BCM_ENDURO_SUPPORT */
  26615 #ifdef BCM_GREYHOUND_SUPPORT
  26616     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  26617         SOC_IS_GREYHOUND2(unit)) {
  26618         int     rv;
  26619         uint32  hg2_mode = 0;
  26620 
  26621 #if defined(BCM_HURRICANE3_SUPPORT)
  26622         if (soc_feature(unit, soc_feature_wh2)) {
  26623             return bcmi_wh2_port_encap_get(unit, port, mode);
  26624         }
  26625 #endif /* BCM_HURRICANE3_SUPPORT */
  26626         /* MAC encap can report the proper encap type but special setting
  26627         * in port marcro for HG2-Lite case.
  26628         *
  26629         * For HG2-Lite condition :
  26630         *   - in Port Macro(MAC is included in PM), the encap will be IEEE.
  26631         *   - Out of Port Macro, the encap will be HG2
  26632         */
  26633         BCM_IF_ERROR_RETURN
  26634                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  26635         if (*mode == BCM_PORT_ENCAP_IEEE) {
  26636 #ifdef  BCM_GREYHOUND2_SUPPORT
  26637             if (SOC_IS_GREYHOUND2(unit)) {
  26638 #ifdef BCM_FIRELIGHT_SUPPORT
  26639                 if (soc_feature(unit, soc_feature_fl)) {
  26640                     rv = soc_firelight_pgw_encap_field_get(unit,
  26641                             port, HIGIG2_MODEf, &hg2_mode);
  26642                 } else
  26643 #endif /* BCM_FIRELIGHT_SUPPORT */
  26644                 {
  26645                     rv = soc_greyhound2_pgw_encap_field_get(unit,
  26646                             port, HIGIG2_MODEf, &hg2_mode);
  26647                 }
  26648             } else
  26649 #endif  /* GREYHOUDN2 */
  26650             {
  26651                 /* only port in XLMAC allows PGW encap setting below */
  26652                 rv = soc_greyhound_pgw_encap_field_get(unit,
  26653                         port, HIGIG2_MODEf, &hg2_mode);
  26654              }
  26655 
  26656             if (BCM_SUCCESS(rv)){
  26657                 *mode = (hg2_mode) ? BCM_PORT_ENCAP_HIGIG2_LITE : *mode;
  26658             } else if (rv != BCM_E_UNAVAIL) {
  26659                 /* BCM_E_UNAVAIL can be occurred on the port at QSGMII */
  26660                 return rv;
  26661             }
  26662         }
  26663     } else
  26664 #endif  /* BCM_GREYHOUND_SUPPORT */
  26665     if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) {
  26666         if (soc_feature(unit, soc_feature_embedded_higig)) {
  26667             *mode = BCM_PORT_ENCAP_IEEE;
  26668         } else {
  26669             uint32 rval;
  26670             soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1,
  26671                                     HGIG2_EN_S3f, HGIG2_EN_S4f};
  26672            /* The port number check is for Coverity.  No port > 6 will
  26673             * reach this logic on Raven. */
  26674             if (SOC_IS_RAVEN(unit) && (port < 6)) {
  26675                 BCM_IF_ERROR_RETURN(READ_GPORT_CONFIGr(unit, port, &rval));
  26676 
  26677                 if (SOC_REG_FIELD_VALID(unit, GPORT_CONFIGr, hg_en[port])) {
  26678                     *mode = soc_reg_field_get(unit, GPORT_CONFIGr, rval,
  26679                                               hg_en[port]) ?
  26680                         BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE;
  26681                 } else {
  26682                     return (BCM_E_CONFIG);
  26683                 }
  26684             }
  26685         }
  26686 #if defined(BCM_TRIUMPH3_SUPPORT)
  26687     } else if (SOC_IS_TRIUMPH3(unit) && IS_CE_PORT(unit, port)) {
  26688         uint32 regval;
  26689         BCM_IF_ERROR_RETURN(READ_PORT_CONFIGr(unit, port, &regval));
  26690         if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG2_MODEf)) {
  26691           *mode = BCM_PORT_ENCAP_HIGIG2;
  26692         } else if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG_MODEf)) {
  26693           *mode = BCM_PORT_ENCAP_HIGIG;
  26694         } else {
  26695            SOC_IF_ERROR_RETURN
  26696                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  26697         }
  26698 #endif
  26699     } else {
  26700         SOC_IF_ERROR_RETURN
  26701             (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  26702     }
  26703 
  26704     if(*mode == -1) {
  26705         /* Default : Return MAC encap mode */
  26706         SOC_IF_ERROR_RETURN
  26707             (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  26708     }
  26709 
  26710     LOG_INFO(BSL_LS_BCM_PORT,
  26711              (BSL_META_U(unit,
  26712                          "bcm_esw_port_encap_get: u=%d p=%d mode=%d\n"),
  26713               unit, port, *mode));
  26714     return BCM_E_NONE;
  26715 }
  26716 
  26717 /*
  26718  * Function:
  26719  *      bcm_port_queued_count_get
  26720  * Purpose:
  26721  *      Returns the count of packets (or cells) currently buffered
  26722  *      for a port.  Useful to know when a port has drained all
  26723  *      data and can then be re-configured.
  26724  * Parameters:
  26725  *      unit - StrataSwitch unit #
  26726  *      port - StrataSwitch port #
  26727  *      count (OUT) - count of packets currently buffered
  26728  * Returns:
  26729  *      BCM_E_XXX
  26730  * Notes:
  26731  *      "packets" may actually be cells on most chips,
  26732  *      If no packets are buffered, the cell count is 0,
  26733  *      If some packets are buffered the cell count will be
  26734  *      greater than or equal to the packet count.
  26735  */
  26736 
  26737 int
  26738 bcm_esw_port_queued_count_get(int unit, bcm_port_t port, uint32 *count)
  26739 {
  26740     uint32      regval;
  26741     int         cos;
  26742 
  26743     *count = 0;
  26744 
  26745     /* Make sure port module is initialized. */
  26746     PORT_INIT(unit);
  26747     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26748 
  26749     if (SOC_IS_FB_FX_HX(unit) || SOC_IS_HURRICANE2(unit) ||
  26750         SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  26751         SOC_IS_GREYHOUND2(unit)) {
  26752         for (cos = 0; cos < NUM_COS(unit); cos++) {
  26753             regval = 0;
  26754             SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, &regval));
  26755             *count += soc_reg_field_get(unit, COSLCCOUNTr, regval, LCCOUNTf);
  26756         }
  26757         return BCM_E_NONE;
  26758     }
  26759 
  26760 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  26761     if (SOC_IS_XGS12_FABRIC(unit)) {
  26762         regval = 0;
  26763         SOC_IF_ERROR_RETURN(READ_MMU_CELLCNTTOTALr(unit, port, &regval));
  26764         *count += soc_reg_field_get(unit, MMU_CELLCNTTOTALr, regval, COUNTf);
  26765         return BCM_E_NONE;
  26766     }
  26767 #endif /* BCM_XGS12_FABRIC_SUPPORT */
  26768 
  26769 #if defined(BCM_BRADLEY_SUPPORT)
  26770     if (SOC_IS_HBX(unit)) {
  26771         regval = 0;
  26772         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNTr(unit, port, &regval));
  26773         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNTr,
  26774                                     regval, OP_PORT_TOTAL_COUNTf);
  26775         return BCM_E_NONE;
  26776     }
  26777 #endif /* BCM_BRADLEY_SUPPORT  */
  26778 
  26779 #if defined(BCM_TRIDENT_SUPPORT)
  26780     if (SOC_IS_TD_TT(unit)) {
  26781         return soc_egress_cell_count(unit, port, count);
  26782     }
  26783 #endif /* BCM_TRIDENT_SUPPORT */
  26784 
  26785 #if defined(BCM_TRIUMPH3_SUPPORT)
  26786     if (SOC_IS_TRIUMPH3(unit)) {
  26787         regval = 0;
  26788         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &regval));
  26789         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,
  26790                                     regval, TOTAL_COUNTf);
  26791         return BCM_E_NONE;
  26792     }
  26793 #endif /* BCM_TRIUMPH3_SUPPORT  */
  26794 
  26795     return BCM_E_UNAVAIL;
  26796 }
  26797 
  26798     /*
  26799  * Function:
  26800  *      bcm_port_protocol_vlan_add
  26801  * Purpose:
  26802  *      Adds a protocol based vlan to a port.  The protocol
  26803  *      is matched by frame type and ether type.  Returns an
  26804  *      error if hardware does not support protocol vlans
  26805  *      (Strata and Hercules).
  26806  * Parameters:
  26807  *      unit - StrataSwitch unit #
  26808  *      port - StrataSwitch port #
  26809  *      frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC}
  26810  *      ether - 16 bit Ethernet type field
  26811  *      vid - VLAN ID
  26812  * Returns:
  26813  *      BCM_E_XXX
  26814  */
  26815 
  26816 int
  26817 bcm_esw_port_protocol_vlan_add(int unit,
  26818                            bcm_port_t port,
  26819                            bcm_port_frametype_t frame,
  26820                            bcm_port_ethertype_t ether,
  26821                            bcm_vlan_t vid)
  26822 {
  26823     int rv = BCM_E_UNAVAIL;
  26824 
  26825     /* Make sure port module is initialized. */
  26826     PORT_INIT(unit);
  26827 #ifdef  BCM_XGS_SWITCH_SUPPORT
  26828 
  26829     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26830     PORT_SWITCHED_CHECK(unit, port);
  26831 
  26832     PORT_LOCK(unit);
  26833 #ifdef BCM_TRX_SUPPORT
  26834     if (SOC_IS_TRX(unit)) {
  26835         bcm_vlan_action_set_t action;
  26836 
  26837         if (!soc_feature(unit, soc_feature_vlan_action)) {
  26838             PORT_UNLOCK(unit);
  26839             return BCM_E_UNAVAIL;
  26840         }
  26841 
  26842         bcm_vlan_action_set_t_init(&action);
  26843         action.new_outer_vlan = vid;
  26844         action.new_inner_vlan = 0;
  26845         action.priority = PORT(unit, port).p_ut_prio;
  26846         action.ut_outer = bcmVlanActionAdd;
  26847         action.it_outer = bcmVlanActionAdd;
  26848         action.it_inner = bcmVlanActionDelete;
  26849         action.it_inner_prio = bcmVlanActionNone;
  26850         action.ot_outer_prio = bcmVlanActionReplace;
  26851         action.dt_outer_prio = bcmVlanActionReplace;
  26852 
  26853         rv = _bcm_trx_vlan_port_protocol_action_add(unit, port, frame,
  26854                                                      ether, &action);
  26855         PORT_UNLOCK(unit);
  26856         return rv;
  26857     }
  26858 #endif /* BCM_TRX_SUPPORT */
  26859 
  26860 #if defined(BCM_FIREBOLT_SUPPORT)
  26861     if (SOC_IS_FBX(unit)) {
  26862         rv = _bcm_fb_port_protocol_vlan_add(unit, port, frame, ether, vid);
  26863         PORT_UNLOCK(unit);
  26864         return rv;
  26865     }
  26866 #endif /* BCM_FIREBOLT_SUPPORT */
  26867     PORT_UNLOCK(unit);
  26868 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26869     /* not supported on STRATA and HERCULES */
  26870     return rv;
  26871 }
  26872 
  26873 /*
  26874  * Function:
  26875  *      bcm_port_protocol_vlan_delete
  26876  * Purpose:
  26877  *      Remove an already created proto protocol based vlan
  26878  *      on a port.
  26879  * Parameters:
  26880  *      unit - StrataSwitch unit #
  26881  *      port - StrataSwitch port #
  26882  *      frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC}
  26883  *      ether - 16 bit Ethernet type field
  26884  * Returns:
  26885  *      BCM_E_XXX
  26886  */
  26887 
  26888 int
  26889 bcm_esw_port_protocol_vlan_delete(int unit,
  26890                               bcm_port_t port,
  26891                               bcm_port_frametype_t frame,
  26892                               bcm_port_ethertype_t ether)
  26893 {
  26894     int rv = BCM_E_UNAVAIL;
  26895     /* Make sure port module is initialized. */
  26896     PORT_INIT(unit);
  26897 #ifdef  BCM_XGS_SWITCH_SUPPORT
  26898     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26899     PORT_SWITCHED_CHECK(unit, port);
  26900 
  26901     PORT_LOCK(unit);
  26902 
  26903 #ifdef BCM_TRX_SUPPORT
  26904     if (SOC_IS_TRX(unit)) {
  26905         if (!soc_feature(unit, soc_feature_vlan_action)) {
  26906             PORT_UNLOCK(unit);
  26907             return BCM_E_UNAVAIL;
  26908         }
  26909         rv = _bcm_trx_vlan_port_protocol_delete(unit, port, frame, ether);
  26910         PORT_UNLOCK(unit);
  26911         return rv;
  26912     }
  26913 #endif /* BCM_TRX_SUPPORT */
  26914 
  26915 #if defined(BCM_FIREBOLT_SUPPORT)
  26916     if (SOC_IS_FBX(unit)) {
  26917         rv = _bcm_fb_port_protocol_vlan_delete(unit, port, frame, ether);
  26918         PORT_UNLOCK(unit);
  26919         return rv;
  26920 
  26921     }
  26922 #endif /* BCM_FIREBOLT_SUPPORT */
  26923 
  26924     PORT_UNLOCK(unit);
  26925 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26926     /* not supported on STRATA and HERCULES */
  26927     return rv;
  26928 }
  26929 
  26930 /*
  26931  * Function:
  26932  *      bcm_port_protocol_vlan_delete_all
  26933  * Purpose:
  26934  *      Remove all protocol based vlans on a port.
  26935  * Parameters:
  26936  *      unit - StrataSwitch unit #
  26937  *      port - StrataSwitch port #
  26938  * Returns:
  26939  *      BCM_E_XXX
  26940  */
  26941 
  26942 int
  26943 bcm_esw_port_protocol_vlan_delete_all(int unit, bcm_port_t port)
  26944 {
  26945 #ifdef  BCM_XGS_SWITCH_SUPPORT
  26946     int         i;
  26947 
  26948     /* Make sure port module is initialized. */
  26949     PORT_INIT(unit);
  26950 
  26951     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26952     PORT_SWITCHED_CHECK(unit, port);
  26953 
  26954 #ifdef BCM_TRX_SUPPORT
  26955     if (SOC_IS_TRX(unit)) {
  26956         int rv;
  26957         if (!soc_feature(unit, soc_feature_vlan_action)) {
  26958             return BCM_E_UNAVAIL;
  26959         }
  26960         PORT_LOCK(unit);
  26961         rv = _bcm_trx_vlan_port_protocol_delete_all(unit, port);
  26962         PORT_UNLOCK(unit);
  26963         return rv;
  26964     }
  26965 #endif /* BCM_TRX_SUPPORT */
  26966 
  26967 #if defined(BCM_FIREBOLT_SUPPORT)
  26968     if (SOC_IS_FBX(unit)) {
  26969         vlan_protocol_entry_t        vpe;
  26970         vlan_protocol_data_entry_t   vde;
  26971         bcm_vlan_t                   cvid, defvid;
  26972         int                          idxmin, idxmax;
  26973         int                          vlan_prot_entries;
  26974         int                          vdentry, p, valid;
  26975         _bcm_port_info_t             *pinfo;
  26976         bcm_pbmp_t                   switched_pbm;
  26977 
  26978         idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  26979         idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  26980         vlan_prot_entries = idxmax + 1;
  26981 
  26982         for (i = idxmin; i <= idxmax; i++) {
  26983             vdentry = (port * vlan_prot_entries) + i;
  26984             SOC_IF_ERROR_RETURN
  26985                 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  26986                                           vdentry, &vde));
  26987             cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, VLAN_IDf);
  26988             BCM_IF_ERROR_RETURN
  26989                 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid));
  26990             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  26991             if (cvid == 0 ||
  26992                 (cvid == defvid && (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)))) {
  26993                 continue;
  26994             }
  26995             sal_memset(&vde, 0, sizeof(vde));
  26996             soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, VLAN_IDf, defvid);
  26997             SOC_IF_ERROR_RETURN
  26998                 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, vdentry, &vde));
  26999             _BCM_PORT_VD_PBVL_CLEAR(pinfo, i);
  27000             /*
  27001              * see if any vlan_protocol_data entries are still valid
  27002              * for the current protocol.
  27003              */
  27004             valid = 0;
  27005             switched_pbm = PBMP_E_ALL(unit);
  27006             if (soc_feature(unit, soc_feature_cpuport_switched)) {
  27007                 BCM_PBMP_OR(switched_pbm, PBMP_CMIC(unit));
  27008             }
  27009 
  27010             BCM_PBMP_ITER(switched_pbm, p) {
  27011                 if (p == port) {    /* skip the entry we just "defaulted" */
  27012                     continue;
  27013                 }
  27014                 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  27015                 /* entry valid if programmed VLAN ID for port */
  27016                 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) {
  27017                     valid = 1;
  27018                     break;
  27019                 }
  27020             }
  27021             if (!valid) {
  27022                 /*
  27023                  * Clear all VLAN_PROTOCOL_DATA entries associated
  27024                  * with this protocol.
  27025                  */
  27026                 BCM_PBMP_ITER(switched_pbm, p) {
  27027                     vdentry = (p * vlan_prot_entries) + i;
  27028                     sal_memset(&vde, 0, sizeof(vde));
  27029                     SOC_IF_ERROR_RETURN
  27030                         (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL,
  27031                                                    vdentry, &vde));
  27032                     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  27033                     _BCM_PORT_VD_PBVL_CLEAR(pinfo, i);
  27034                 }
  27035                 /* clear VLAN_PROTOCOL entry */
  27036                 sal_memset(&vpe, 0, sizeof(vpe));
  27037                 SOC_IF_ERROR_RETURN
  27038                     (WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, i, &vpe));
  27039             }
  27040         }
  27041         return BCM_E_NONE;
  27042     }
  27043 #endif /* BCM_FIREBOLT_SUPPORT */
  27044 
  27045 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27046 
  27047     /* not supported on STRATA and HERCULES */
  27048 
  27049     return BCM_E_UNAVAIL;
  27050 }
  27051 
  27052 /*
  27053  * Differentiated Services Code Point Mapping
  27054  */
  27055 
  27056 /*
  27057  * Function:
  27058  *      bcm_esw_port_dscp_map_mode_set
  27059  * Purpose:
  27060  *      Set DSCP mapping for the port.
  27061  * Parameters:
  27062  *      unit - switch device
  27063  *      port - switch port      or -1 to apply on all the ports.
  27064  *      mode - BCM_PORT_DSCP_MAP_NONE
  27065  *           - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0
  27066  *           - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping.
  27067  * Returns:
  27068  *      BCM_E_XXX
  27069  */
  27070 static int
  27071 _bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode)
  27072 {
  27073     bcm_port_cfg_t      pcfg;
  27074 
  27075     BCM_IF_ERROR_RETURN
  27076         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  27077     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  27078         return BCM_E_UNAVAIL;
  27079     }
  27080     switch (mode) {
  27081         case BCM_PORT_DSCP_MAP_NONE:
  27082             pcfg.pc_dse_mode = 0;
  27083             pcfg.pc_dse_mode_ipv6 = 0;
  27084 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27085             pcfg.pc_dscp_prio = 0;
  27086 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27087             break;
  27088         case BCM_PORT_DSCP_MAP_ZERO:
  27089             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27090                 return BCM_E_UNAVAIL;
  27091             }
  27092             pcfg.pc_dse_mode = 1;
  27093 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27094             pcfg.pc_dscp_prio = 1;
  27095 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27096             break;
  27097         case BCM_PORT_DSCP_MAP_ALL:
  27098             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27099                 pcfg.pc_dse_mode = 1;
  27100                 pcfg.pc_dse_mode_ipv6 = 1;
  27101             } else {
  27102                 pcfg.pc_dse_mode = 2;
  27103             }
  27104 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27105             pcfg.pc_dscp_prio = 1;
  27106 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27107             break;
  27108         case BCM_PORT_DSCP_MAP_IPV4_ONLY:
  27109             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27110                 return BCM_E_UNAVAIL;
  27111             }
  27112             pcfg.pc_dse_mode = 1;
  27113 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27114             pcfg.pc_dscp_prio = 1;
  27115 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27116             break;
  27117         case BCM_PORT_DSCP_MAP_IPV6_ONLY:
  27118             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27119                 return BCM_E_UNAVAIL;
  27120             }
  27121             pcfg.pc_dse_mode_ipv6 = 1;
  27122 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27123             pcfg.pc_dscp_prio = 1;
  27124 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27125             break;
  27126         case BCM_PORT_DSCP_MAP_IPV4_NONE:
  27127             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27128                 return BCM_E_UNAVAIL;
  27129             }
  27130             pcfg.pc_dse_mode = 0;
  27131 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27132             if (!pcfg.pc_dse_mode_ipv6) {
  27133                 pcfg.pc_dscp_prio = 0;
  27134             }
  27135 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27136             break;
  27137         case BCM_PORT_DSCP_MAP_IPV6_NONE:
  27138             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27139                 return BCM_E_UNAVAIL;
  27140             }
  27141             pcfg.pc_dse_mode_ipv6 = 0;
  27142 #if defined(BCM_XGS_SWITCH_SUPPORT)
  27143             if (!pcfg.pc_dse_mode) {
  27144                 pcfg.pc_dscp_prio = 0;
  27145             }
  27146 #endif /* BCM_XGS_SWITCH_SUPPORT */
  27147             break;
  27148         default:
  27149             return BCM_E_PARAM;
  27150     }
  27151     BCM_IF_ERROR_RETURN
  27152         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  27153 
  27154     return BCM_E_NONE;
  27155 }
  27156 
  27157 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27158 static int
  27159 _bcm_esw_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode) {
  27160     if (SOC_IS_KATANAX(unit) ||
  27161         SOC_IS_TD_TT(unit)||
  27162         soc_feature(unit, soc_feature_vp_dscp_map)) {
  27163         return _bcm_tr2_vp_dscp_map_mode_set(unit, port, mode);
  27164     }
  27165     return BCM_E_UNAVAIL;
  27166 }
  27167 
  27168 STATIC int
  27169 _bcm_esw_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp,
  27170                          int prio)
  27171 {
  27172     if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) {
  27173         return _bcm_tr2_vp_dscp_map_set(unit, port, srccp, mapcp, prio);
  27174     }
  27175     return BCM_E_UNAVAIL;
  27176 }
  27177 #endif
  27178 
  27179 int
  27180 bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode)
  27181 {
  27182     int rv;
  27183     bcm_port_config_t port_conf;
  27184     bcm_pbmp_t pbmp;
  27185 
  27186     /* Make sure port module is initialized. */
  27187     PORT_INIT(unit);
  27188 
  27189     if (!soc_feature(unit, soc_feature_dscp)) {
  27190         return BCM_E_UNAVAIL;
  27191     }
  27192 
  27193 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27194     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  27195         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  27196         return _bcm_esw_vp_dscp_map_mode_set(unit, port, mode);
  27197     }
  27198 #endif
  27199 
  27200     if (port != -1) {
  27201         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27202     }
  27203 
  27204     PORT_LOCK(unit);
  27205 
  27206     /* Get device port configuration. */
  27207     rv = bcm_esw_port_config_get(unit, &port_conf);
  27208     if (BCM_FAILURE(rv)) {
  27209         PORT_UNLOCK(unit);
  27210         return rv;
  27211     }
  27212     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27213     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  27214         BCM_PBMP_OR(pbmp, port_conf.cpu);
  27215     }
  27216 #ifdef BCM_KATANA2_SUPPORT
  27217     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27218         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27219         if (BCM_FAILURE(rv)) {
  27220             PORT_UNLOCK(unit);
  27221             return (rv);
  27222         }
  27223     }
  27224     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27225         soc_feature(unit, soc_feature_subtag_coe)) {
  27226         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27227     }
  27228 #endif
  27229 
  27230     if (port == -1) {
  27231         PBMP_ITER(pbmp, port) {
  27232             rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode);
  27233             if (BCM_FAILURE(rv)) {
  27234                 PORT_UNLOCK(unit);
  27235                 return rv;
  27236             }
  27237         }
  27238     } else {
  27239         if (BCM_PBMP_MEMBER(pbmp, port)) {
  27240             rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode);
  27241         } else {
  27242             rv = BCM_E_PORT;
  27243         }
  27244     }
  27245     PORT_UNLOCK(unit);
  27246     return rv;
  27247 }
  27248 
  27249 /*
  27250  * Function:
  27251  *      bcm_esw_port_dscp_map_mode_get
  27252  * Purpose:
  27253  *      DSCP mapping status for the port.
  27254  * Parameters:
  27255  *      unit - switch device
  27256  *      port - switch port or -1 to get mode from first available port
  27257  *      mode - (OUT)
  27258  *           - BCM_PORT_DSCP_MAP_NONE
  27259  *           - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0
  27260  *           - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping.
  27261  * Returns:
  27262  *      BCM_E_XXX
  27263  */
  27264 
  27265 static int
  27266 _bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode)
  27267 {
  27268     bcm_port_cfg_t      pcfg;
  27269 
  27270     BCM_IF_ERROR_RETURN
  27271         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  27272     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  27273         return BCM_E_UNAVAIL;
  27274     }
  27275     switch (pcfg.pc_dse_mode) {
  27276         case 1:
  27277             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27278                 if (pcfg.pc_dse_mode_ipv6) {
  27279                     *mode = BCM_PORT_DSCP_MAP_ALL;
  27280                 } else {
  27281                     *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY;
  27282                 }
  27283             } else {
  27284                 *mode = BCM_PORT_DSCP_MAP_ZERO;
  27285             }
  27286             break;
  27287         case 2:
  27288             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  27289                 if (pcfg.pc_dse_mode_ipv6) {
  27290                     *mode = BCM_PORT_DSCP_MAP_ALL;
  27291                 } else {
  27292                     *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY;
  27293                 }
  27294             } else {
  27295                 *mode = BCM_PORT_DSCP_MAP_ALL;
  27296             }
  27297             break;
  27298         case 0:
  27299             if (pcfg.pc_dse_mode_ipv6) {
  27300                 *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY;
  27301             } else {
  27302                 *mode = BCM_PORT_DSCP_MAP_NONE;
  27303             }
  27304             break;
  27305 
  27306         default:
  27307             *mode = BCM_PORT_DSCP_MAP_NONE;
  27308             break;
  27309     }
  27310 
  27311     return BCM_E_NONE;
  27312 }
  27313 
  27314 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27315 static int
  27316 _bcm_esw_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode) {
  27317     if (SOC_IS_KATANAX(unit) ||
  27318         SOC_IS_TD_TT(unit) ||
  27319         soc_feature(unit, soc_feature_vp_dscp_map)) {
  27320         return _bcm_tr2_vp_dscp_map_mode_get(unit, port, mode);
  27321     }
  27322     return BCM_E_UNAVAIL;
  27323 }
  27324 
  27325 STATIC int
  27326 _bcm_esw_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp,
  27327                          int *prio)
  27328 {
  27329     if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) {
  27330         return _bcm_tr2_vp_dscp_map_get(unit, port, srccp, mapcp, prio);
  27331     }
  27332     return BCM_E_UNAVAIL;
  27333 }
  27334 #endif
  27335 
  27336 int
  27337 bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode)
  27338 {
  27339     int rv;
  27340     bcm_port_config_t port_conf;
  27341     bcm_pbmp_t pbmp;
  27342 
  27343     /* Make sure port module is initialized. */
  27344     PORT_INIT(unit);
  27345 
  27346     if (!soc_feature(unit, soc_feature_dscp)) {
  27347         return BCM_E_UNAVAIL;
  27348     }
  27349 
  27350 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27351     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  27352         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  27353         return _bcm_esw_vp_dscp_map_mode_get(unit, port, mode);
  27354     }
  27355 #endif
  27356 
  27357     if (port != -1) {
  27358         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27359     }
  27360 
  27361     PORT_LOCK(unit);
  27362 
  27363     /* Get device port configuration. */
  27364     rv = bcm_esw_port_config_get(unit, &port_conf);
  27365     if (BCM_FAILURE(rv)) {
  27366         PORT_UNLOCK(unit);
  27367         return rv;
  27368     }
  27369     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27370     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  27371         BCM_PBMP_OR(pbmp, port_conf.cpu);
  27372     }
  27373 #ifdef BCM_KATANA2_SUPPORT
  27374     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27375         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27376         if (BCM_FAILURE(rv)) {
  27377             PORT_UNLOCK(unit);
  27378             return (rv);
  27379         }
  27380     }
  27381     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27382         soc_feature(unit, soc_feature_subtag_coe)) {
  27383         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27384     }
  27385 #endif
  27386 
  27387     if (port == -1) {
  27388         PBMP_ITER(pbmp, port) {
  27389             break;
  27390         }
  27391     }
  27392 
  27393     /* coverity[overrun-local : FALSE] */
  27394     if (BCM_PBMP_MEMBER(pbmp, port)) {
  27395         rv = _bcm_esw_port_dscp_map_mode_get(unit, port, mode);
  27396     } else {
  27397         rv = BCM_E_PORT;
  27398     }
  27399     PORT_UNLOCK(unit);
  27400     return rv;
  27401 }
  27402 
  27403 /*
  27404  * Function:
  27405  *      _bcm_port_dscp_map_set
  27406  * Purpose:
  27407  *      Internal implementation for bcm_port_dscp_map_set
  27408  * Parameters:
  27409  *      unit - switch device
  27410  *      port - switch port or -1 for global table
  27411  *      srccp - src code point or -1
  27412  *      mapcp - mapped code point or -1
  27413  *      prio - priority value for mapped code point
  27414  *              -1 to use port default untagged priority
  27415  *              BCM_PRIO_RED    can be or'ed into the priority
  27416  *              BCM_PRIO_YELLOW can be or'ed into the priority
  27417  * Returns:
  27418  *      BCM_E_XXX
  27419  */
  27420 
  27421 STATIC int
  27422 _bcm_port_dscp_map_set(int unit, bcm_port_t port,
  27423                        int srccp, int mapcp, int prio)
  27424 {
  27425 #define DSCP_CODE_POINT_CNT 64
  27426 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1)
  27427     bcm_port_cfg_t      pcfg;
  27428 
  27429     if (mapcp < -1 || mapcp > DSCP_CODE_POINT_MAX) {
  27430         return BCM_E_PARAM;
  27431     }
  27432 
  27433 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  27434     if (SOC_IS_XGS3_SWITCH(unit)) {
  27435         int                  i, cng;
  27436         dscp_table_entry_t   de;
  27437         phb_mapping_tbl_2_entry_t  phb_tbl_2;
  27438         int                  max_index;
  27439         int                  min_index;
  27440         int                  field_len;
  27441 
  27442         if (SOC_IS_TRIDENT3X(unit)) {
  27443             field_len = soc_mem_field_length(unit, PHB_MAPPING_TBL_2m, INT_PRIf);
  27444         } else {
  27445             field_len = soc_mem_field_length(unit, DSCP_TABLEm, PRIf);
  27446         }
  27447 
  27448         if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX) {
  27449             return BCM_E_PARAM;
  27450         }
  27451         /* Extract cng bits and check for valid priority. */
  27452         
  27453         cng = 0; /* Green */
  27454         if (prio < BCM_PRIO_MIN) {
  27455             return BCM_E_PARAM;
  27456         }
  27457         if (prio & BCM_PRIO_RED) {
  27458             cng = 0x01;  /* Red */
  27459             prio &= ~BCM_PRIO_RED;
  27460         } else if (prio & BCM_PRIO_YELLOW) {
  27461             cng = 0x03;  /* Yellow  */
  27462             prio &= ~BCM_PRIO_YELLOW;
  27463         }
  27464         if ((prio & ~BCM_PRIO_MASK) != 0) {
  27465             return BCM_E_PARAM;
  27466         }
  27467         if (prio >= (1 << field_len)) {
  27468             return BCM_E_PARAM;
  27469         }
  27470         if (srccp < 0 && mapcp < 0) {
  27471             /* No mapping */
  27472             return BCM_E_NONE;
  27473         } else if (srccp < 0) {
  27474             /* Map all DSCPs to a new DSCP */
  27475             /* fill all entries in DSCP_TABLEm with mapcp */
  27476 
  27477 #ifdef BCM_TRIDENT2_SUPPORT
  27478             if (SOC_IS_TD2_TT2(unit)) {
  27479                 return (bcm_td2_port_dscp_map_set(unit,
  27480                     port, srccp, mapcp, prio, cng));
  27481             }
  27482 #endif
  27483 #ifdef BCM_KATANA2_SUPPORT
  27484             if (SOC_IS_KATANA2(unit)) {
  27485                 return (bcm_kt2_port_dscp_map_set(unit, port,
  27486                     srccp, mapcp, prio, cng));
  27487             }
  27488 #endif
  27489 
  27490             if (SOC_IS_TRIDENT3X(unit)) {
  27491                 sal_memset(&phb_tbl_2, 0, sizeof(phb_tbl_2));
  27492                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp);
  27493                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio);
  27494                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng);
  27495             } else {
  27496                 sal_memset(&de, 0, sizeof(de));
  27497                 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp);
  27498                 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio);
  27499                 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng);
  27500             }
  27501             if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  27502                 min_index = port * DSCP_CODE_POINT_CNT;
  27503                 max_index = min_index + DSCP_CODE_POINT_MAX;
  27504             } else {
  27505                 if (SOC_IS_TRIDENT3X(unit)) {
  27506                     max_index = soc_mem_index_max(unit, PHB_MAPPING_TBL_2m);
  27507                 } else {
  27508                     max_index = soc_mem_index_max(unit, DSCP_TABLEm);
  27509                 }
  27510                 min_index = 0;
  27511             }
  27512 
  27513             for (i = min_index; i <= max_index; i++) {
  27514                 if (SOC_IS_TRIDENT3X(unit)) {
  27515                     SOC_IF_ERROR_RETURN
  27516                     (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, i, &phb_tbl_2));
  27517                 } else {
  27518                     SOC_IF_ERROR_RETURN
  27519                     (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, i, &de));
  27520                 }
  27521             }
  27522         } else {
  27523             int num_cosq;
  27524 
  27525 #ifdef BCM_TRIDENT2_SUPPORT
  27526             if (SOC_IS_TD2_TT2(unit)) {
  27527                 return (bcm_td2_port_dscp_map_set(unit, port,
  27528                     srccp, mapcp, prio, cng));
  27529             }
  27530 #endif
  27531 #ifdef BCM_KATANA2_SUPPORT
  27532             if (SOC_IS_KATANA2(unit)) {
  27533                 return (bcm_kt2_port_dscp_map_set(unit, port,
  27534                     srccp, mapcp, prio, cng));
  27535             }
  27536 #endif
  27537 
  27538             num_cosq = 1; /* For all cosqs */
  27539             /* Map a specific DSCP to a new DSCP */
  27540             sal_memset(&de, 0, sizeof(de));
  27541             /* fill specific srccp entry/entries in DSCP_TABLEm with mapcp */
  27542             if (SOC_IS_TRIDENT3X(unit)) {
  27543                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp);
  27544                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio);
  27545                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng);
  27546             } else {
  27547                 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp);
  27548                 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio);
  27549                 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng);
  27550             }
  27551 
  27552             if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  27553                 if (SOC_IS_TRIDENT3X(unit)) {
  27554                     SOC_IF_ERROR_RETURN
  27555                       (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL,
  27556                                          (port * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2));
  27557                 } else {
  27558                     SOC_IF_ERROR_RETURN
  27559                       (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL,
  27560                                          (port * DSCP_CODE_POINT_CNT) + srccp, &de));
  27561                 }
  27562 
  27563             } else {
  27564                 for (i = 0; i < num_cosq ; i++) {
  27565                     if (SOC_IS_TRIDENT3X(unit)) {
  27566                         SOC_IF_ERROR_RETURN
  27567                           (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL,
  27568                                          (i * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2));
  27569                     } else {
  27570                         SOC_IF_ERROR_RETURN
  27571                           (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL,
  27572                                          (i * DSCP_CODE_POINT_CNT) + srccp, &de));
  27573                     }
  27574                 }
  27575             }
  27576         }
  27577         return BCM_E_NONE;
  27578     }
  27579 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  27580 
  27581     /* all other switches */
  27582     if (srccp < -1 || srccp > 0) {
  27583         return BCM_E_PARAM;
  27584     }
  27585 
  27586     pcfg.pc_dse_mode = -1;
  27587     BCM_IF_ERROR_RETURN
  27588         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  27589     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  27590         return BCM_E_UNAVAIL;
  27591     }
  27592 
  27593     if (mapcp >= 0) {
  27594         pcfg.pc_dscp = mapcp;
  27595 
  27596         BCM_IF_ERROR_RETURN
  27597             (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  27598     }
  27599 
  27600     return BCM_E_NONE;
  27601 }
  27602 
  27603 /*
  27604  * Function:
  27605  *      bcm_port_dscp_map_set
  27606  * Purpose:
  27607  *      Define a mapping for diffserv code points
  27608  *      The mapping enable/disable is controlled by a seperate API
  27609  *      bcm_port_dscp_map_enable_set/get
  27610  *      Also Enable/Disable control for DSCP mapping for tunnels
  27611  *      are available in the respective tunnel create APIs.
  27612  * Parameters:
  27613  *      unit - switch device
  27614  *      port - switch port      or -1 to setup global mapping table.
  27615  *      srccp - src code point or -1
  27616  *      mapcp - mapped code point or -1
  27617  *      prio - priority value for mapped code point
  27618  *              -1 to use port default untagged priority
  27619  *              BCM_PRIO_DROP_FIRST can be or'ed into the priority
  27620  * Returns:
  27621  *      BCM_E_XXX
  27622  * Notes:
  27623  *      On most xgs switches there are a limited set
  27624  *      of mappings that are possible:
  27625  *              srccp -1, mapcp -1:     no mapping
  27626  *              srccp -1, mapcp 0..63:  map all packets
  27627  *              srccp 0, mapcp 0..63:   map packets with cp 0
  27628  *      On Firebolt/Helix/Felix, there is no per port mapping table.
  27629  *      Only a global mapping table is available.
  27630  */
  27631 
  27632 int
  27633 bcm_esw_port_dscp_map_set(int unit, bcm_port_t port, int srccp, int mapcp,
  27634                       int prio)
  27635 {
  27636     int rv;
  27637     bcm_port_config_t port_conf;
  27638     bcm_pbmp_t pbmp;
  27639 
  27640     /* Make sure port module is initialized. */
  27641     PORT_INIT(unit);
  27642 
  27643     if (!soc_feature(unit, soc_feature_dscp)) {
  27644         return BCM_E_UNAVAIL;
  27645     }
  27646 
  27647 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27648     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  27649         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  27650         return _bcm_esw_vp_dscp_map_set(unit, port, srccp, mapcp, prio);
  27651     }
  27652 #endif
  27653 
  27654     if (port != -1) {
  27655         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27656         if (!soc_feature(unit, soc_feature_dscp_map_per_port)) {
  27657             return BCM_E_PORT;
  27658         }
  27659     }
  27660 
  27661     PORT_LOCK(unit);
  27662 
  27663     /* Get device port configuration. */
  27664     rv = bcm_esw_port_config_get(unit, &port_conf);
  27665     if (BCM_FAILURE(rv)) {
  27666         PORT_UNLOCK(unit);
  27667         return rv;
  27668     }
  27669     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27670     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  27671         BCM_PBMP_OR(pbmp, port_conf.cpu);
  27672     }
  27673 #ifdef BCM_KATANA2_SUPPORT
  27674     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27675         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27676         if (BCM_FAILURE(rv)) {
  27677             PORT_UNLOCK(unit);
  27678             return (rv);
  27679         }
  27680     }
  27681     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27682         soc_feature(unit, soc_feature_subtag_coe)) {
  27683         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27684     }
  27685 #endif
  27686 
  27687     if ((port == -1) && (soc_feature(unit, soc_feature_dscp_map_per_port))) {
  27688         PBMP_ITER(pbmp, port) {
  27689             /* coverity[stack_use_callee] */
  27690             /* coverity[stack_use_overflow] */
  27691             rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio);
  27692             if (BCM_FAILURE(rv)) {
  27693                 PORT_UNLOCK(unit);
  27694                 return rv;
  27695             }
  27696         }
  27697     } else {
  27698         if (BCM_PBMP_MEMBER(pbmp, port) || (port == -1)) {
  27699             rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio);
  27700         } else {
  27701             rv = BCM_E_PORT;
  27702         }
  27703     }
  27704     PORT_UNLOCK(unit);
  27705 
  27706     return rv;
  27707 }
  27708 
  27709 /*
  27710  * Function:
  27711  *      _bcm_port_dscp_map_get
  27712  * Purpose:
  27713  *      Get a mapping for diffserv code points
  27714  * Parameters:
  27715  *      unit - switch device
  27716  *      port - switch port
  27717  *      srccp - src code point or -1
  27718  *      mapcp - (OUT) pointer to returned mapped code point
  27719  *      prio - (OUT) Priority value for mapped code point or -1
  27720  *                      May have BCM_PRIO_DROP_FIRST or'ed into it
  27721  * Returns:
  27722  *      BCM_E_XXX
  27723  */
  27724 
  27725 STATIC int
  27726 _bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp,
  27727                       int *prio)
  27728 {
  27729     bcm_port_cfg_t      pcfg;
  27730     port_tab_entry_t    pent;
  27731 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  27732     int                      index = 0;
  27733 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  27734     int                      rv = BCM_E_NONE;
  27735 
  27736     if (SOC_IS_TRIDENT3X(unit)) {
  27737         BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port,
  27738                             TRUST_DSCP_PTRf, &index));
  27739     } else if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) {
  27740         /* Get profile index from port table. */
  27741         rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  27742                           port, &pent);
  27743         if (BCM_FAILURE(rv)) {
  27744             return rv;
  27745         }
  27746 
  27747 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  27748         index = soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf);
  27749 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  27750     }
  27751 
  27752     if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX ||
  27753         mapcp == NULL || prio == NULL) {
  27754         return BCM_E_PARAM;
  27755     }
  27756 
  27757 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  27758     if (SOC_IS_XGS3_SWITCH(unit)) {
  27759         int                     base;
  27760         int                     cng;
  27761         dscp_table_entry_t      de;
  27762         phb_mapping_tbl_2_entry_t phb_tbl_2;
  27763 
  27764         /* look up in DSCP_TABLEm */
  27765         if (srccp < 0) {
  27766             srccp = 0;
  27767         }
  27768         if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  27769             base = (port * DSCP_CODE_POINT_CNT);
  27770 
  27771             if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) {
  27772                 base = (index * DSCP_CODE_POINT_CNT);
  27773             }
  27774         } else {
  27775             base = 0;
  27776         }
  27777 
  27778         if (SOC_IS_TRIDENT3X(unit)) {
  27779             SOC_IF_ERROR_RETURN
  27780                 (READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &phb_tbl_2));
  27781             *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, DSCPf);
  27782             *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, INT_PRIf);
  27783 
  27784              cng   = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, CNGf);
  27785         } else {
  27786             SOC_IF_ERROR_RETURN
  27787                 (READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de));
  27788             *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf);
  27789             *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf);
  27790 
  27791             cng   = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf);
  27792         }
  27793         if (cng == 1) {
  27794             *prio |= BCM_PRIO_RED;
  27795         } else if (cng == 3) {
  27796             *prio |= BCM_PRIO_YELLOW;
  27797         } else if (cng != 0) {
  27798             *prio |= BCM_PRIO_DROP_FIRST;
  27799         }
  27800 
  27801         return BCM_E_NONE;
  27802     }
  27803 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  27804 
  27805     /* all other switches */
  27806 
  27807     pcfg.pc_dse_mode = -1;
  27808     BCM_IF_ERROR_RETURN
  27809         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  27810     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  27811         return BCM_E_UNAVAIL;
  27812     }
  27813 
  27814     /*
  27815      * The mapping table is set independently of the mapping mode.
  27816      * So the _get API will return the mapping table setup and not
  27817      * necessarily the actual mapping that will be applied to the packet.
  27818      * The mapping applied to the packet is determined by mapping mode
  27819      * set using bcm_port_dscp_map_mode_set
  27820      */
  27821     *mapcp = pcfg.pc_dscp;
  27822 
  27823     *prio = -1;
  27824 
  27825     return BCM_E_NONE;
  27826 }
  27827 
  27828 /*
  27829  * Function:
  27830  *      bcm_port_dscp_map_get
  27831  * Purpose:
  27832  *      Get a mapping for diffserv code points
  27833  * Parameters:
  27834  *      unit - switch device
  27835  *      port - switch port
  27836  *      srccp - src code point or -1
  27837  *      mapcp - (OUT) pointer to returned mapped code point
  27838  *      prio - (OUT) Priority value for mapped code point or -1
  27839  *                      May have BCM_PRIO_DROP_FIRST or'ed into it
  27840  * Returns:
  27841  *      BCM_E_XXX
  27842  */
  27843 
  27844 int
  27845 bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp,
  27846                       int *prio)
  27847 {
  27848     int rv;
  27849     bcm_port_config_t port_conf;
  27850     bcm_pbmp_t pbmp;
  27851 
  27852     /* Make sure port module is initialized. */
  27853     PORT_INIT(unit);
  27854 
  27855     if (!soc_feature(unit, soc_feature_dscp)) {
  27856         return BCM_E_UNAVAIL;
  27857     }
  27858 
  27859 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  27860     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  27861         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  27862         return _bcm_esw_vp_dscp_map_get(unit, port, srccp, mapcp, prio);
  27863     }
  27864 #endif
  27865 
  27866     if (port != -1) {
  27867         if (0 == soc_feature(unit, soc_feature_dscp_map_per_port)) {
  27868             return BCM_E_PORT;
  27869         }
  27870         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27871     }
  27872 
  27873     PORT_LOCK(unit);
  27874 
  27875     /* Get device port configuration. */
  27876     rv = bcm_esw_port_config_get(unit, &port_conf);
  27877     if (BCM_FAILURE(rv)) {
  27878         PORT_UNLOCK(unit);
  27879         return rv;
  27880     }
  27881     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27882     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  27883         BCM_PBMP_OR(pbmp, port_conf.cpu);
  27884     }
  27885 #ifdef BCM_KATANA2_SUPPORT
  27886     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27887         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27888         if (BCM_FAILURE(rv)) {
  27889             PORT_UNLOCK(unit);
  27890             return (rv);
  27891         }
  27892     }
  27893     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27894         soc_feature(unit, soc_feature_subtag_coe)) {
  27895         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27896     }
  27897 #endif
  27898 
  27899     if (port == -1) {
  27900         PBMP_ITER(pbmp, port) {
  27901             break;
  27902         }
  27903     }
  27904 
  27905     if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  27906         rv = _bcm_esw_port_dscp_map_get(unit, port, srccp, mapcp, prio);
  27907     } else {
  27908         rv = BCM_E_PORT;
  27909     }
  27910 
  27911     PORT_UNLOCK(unit);
  27912     return rv;
  27913 }
  27914 
  27915 #ifdef BCM_TRIDENT_SUPPORT
  27916 STATIC int
  27917 _bcm_td_egr_l3_intf_dscp_map_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id)
  27918 {
  27919     char *egr_intf_tbl_ptr = NULL;   /* EGR_L3_INTF dma table pointer.  */
  27920     int rv;
  27921     uint32 *egr_intf_entry_ptr;        /* EGR_L3_INTF entry pointer. */
  27922     int ifindex;
  27923     uint32 dscp_map_ptr;
  27924     int tbl_size;
  27925     int alloc_size;
  27926 
  27927     if (dscp_map_id == new_dscp_map_id) {
  27928         return BCM_E_NONE;
  27929     }
  27930 
  27931     /* Calculate table size. */
  27932     tbl_size =  soc_mem_index_count(unit, EGR_L3_INTFm);
  27933     if (!tbl_size) {
  27934         return (BCM_E_NOT_FOUND);
  27935     }
  27936     alloc_size = sizeof(egr_l3_intf_entry_t) * tbl_size;
  27937 
  27938     /* Allocate memory buffer. */
  27939     egr_intf_tbl_ptr = soc_cm_salloc(unit, alloc_size, "egr_l3_intf_tbl");
  27940     if (egr_intf_tbl_ptr == NULL) {
  27941         return (BCM_E_MEMORY);
  27942     }
  27943 
  27944     /* Reset allocated buffer. */
  27945     sal_memset(egr_intf_tbl_ptr, 0, alloc_size);
  27946 
  27947     /* Read table to the buffer. */
  27948     rv = soc_mem_read_range(unit, EGR_L3_INTFm, MEM_BLOCK_ANY,
  27949                             soc_mem_index_min(unit, EGR_L3_INTFm),
  27950                             soc_mem_index_max(unit, EGR_L3_INTFm), egr_intf_tbl_ptr);
  27951     if (BCM_FAILURE(rv)) {
  27952         goto cleanup;
  27953     }
  27954     for (ifindex = 0; ifindex < tbl_size; ifindex++) {
  27955         egr_intf_entry_ptr =
  27956         soc_mem_table_idx_to_pointer(unit, EGR_L3_INTFm,
  27957                                      uint32 *, egr_intf_tbl_ptr,
  27958                                      ifindex);
  27959         dscp_map_ptr = soc_mem_field32_get(unit, EGR_L3_INTFm,
  27960                                            egr_intf_entry_ptr, DSCP_MAPPING_PTRf);
  27961         if (dscp_map_ptr == dscp_map_id) {
  27962 
  27963             soc_mem_field32_set(unit, EGR_L3_INTFm,
  27964                                 egr_intf_entry_ptr, DSCP_MAPPING_PTRf,
  27965                                 new_dscp_map_id);
  27966         }
  27967     }
  27968     rv = soc_mem_write_range(unit, EGR_L3_INTFm, MEM_BLOCK_ALL,
  27969                              soc_mem_index_min(unit, EGR_L3_INTFm),
  27970                              soc_mem_index_max(unit, EGR_L3_INTFm),
  27971                              egr_intf_tbl_ptr);
  27972     if (SOC_FAILURE(rv)) {
  27973         goto cleanup;
  27974     }
  27975 
  27976     _bcm_tr2_qos_id_update(unit, dscp_map_id, new_dscp_map_id);
  27977 
  27978 cleanup:
  27979 
  27980     if (egr_intf_tbl_ptr) {
  27981         soc_cm_sfree(unit, egr_intf_tbl_ptr);
  27982     }
  27983     return rv;
  27984 
  27985 }
  27986 #endif
  27987 
  27988 /*
  27989  * Function:
  27990  *      _bcm_port_dscp_unmap_set
  27991  * Purpose:
  27992  *      Internal implementation for bcm_port_dscp_unmap_set
  27993  * Returns:
  27994  *      BCM_E_XXX
  27995  */
  27996 STATIC int
  27997 _bcm_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri,
  27998                          bcm_color_t color, int pkt_dscp)
  27999 {
  28000     int index, port_shift = 6;
  28001     egr_dscp_table_entry_t  dscp_unmap;
  28002     egr_zone_4_qos_mapping_table_entry_t z4_qos_unmap;
  28003 #if defined(BCM_TRIDENT_SUPPORT)
  28004     egr_dscp_table_entry_t egr_dscp_map_entries[64];
  28005     void *entries[1];
  28006     uint32 dscp_index = 0;
  28007     uint32 new_dscp_index;
  28008     int ref_count;
  28009     void *entry;
  28010     int port_dscp_map_set;
  28011     int old_pkt_dscp;
  28012 #endif
  28013     if (pkt_dscp < 0 || pkt_dscp > DSCP_CODE_POINT_MAX) {
  28014         return BCM_E_PARAM;
  28015     }
  28016     if ((internal_pri < 0) || (internal_pri > 15) ||
  28017         ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  28018          (color != bcmColorRed))) {
  28019         return BCM_E_PARAM;
  28020     }
  28021 
  28022     /* EGR_DSCP_TABLE table is indexed with
  28023      * port[5:0] priority[3:0] CNG [1:0]
  28024      */
  28025 
  28026     index = (port << port_shift) | (internal_pri << 2) |
  28027          _BCM_COLOR_ENCODING(unit, color);
  28028 
  28029     if (SOC_IS_TRIDENT3X(unit)) {
  28030         /* This function is obselete - put in the right register for readability*/
  28031         sal_memset(&z4_qos_unmap, 0, sizeof(z4_qos_unmap));
  28032         soc_mem_field32_set(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp);
  28033         SOC_IF_ERROR_RETURN
  28034         (WRITE_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap));
  28035 
  28036         soc_mem_field32_set(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp);
  28037         SOC_IF_ERROR_RETURN
  28038         (WRITE_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap));
  28039     } else
  28040 #ifdef BCM_TRIDENT_SUPPORT
  28041     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
  28042         dscp_index = port << port_shift;
  28043         index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color);
  28044 
  28045         sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries));
  28046         entries[0] = &egr_dscp_map_entries;
  28047 
  28048         entry = &egr_dscp_map_entries[index];
  28049         BCM_IF_ERROR_RETURN(
  28050             _bcm_egr_dscp_table_entry_ref_count_get(unit, dscp_index, &ref_count));
  28051         port_dscp_map_set = PORT(unit, port).port_dscp_map_set;
  28052         if (ref_count > 0) {
  28053             BCM_IF_ERROR_RETURN(
  28054                 _bcm_egr_dscp_table_entry_get(unit, dscp_index,
  28055                                               _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries));
  28056             old_pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, entry, DSCPf);
  28057             if (pkt_dscp != old_pkt_dscp) {
  28058                 int i;
  28059                 int port_dscp_map_count = port_dscp_map_set;
  28060                 /* If this profile is only used by port */
  28061                 if ((ref_count == 1) && (port_dscp_map_set == 1)) {
  28062                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  28063                     BCM_IF_ERROR_RETURN(
  28064                         _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));
  28065                     BCM_IF_ERROR_RETURN(
  28066                         _bcm_egr_dscp_table_entry_delete(unit, dscp_index));
  28067                 } else { /* If this profile is used not only by port */
  28068                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf,
  28069                                         old_pkt_dscp);
  28070                     BCM_IF_ERROR_RETURN(
  28071                         _bcm_egr_dscp_table_entry_add(unit, entries,
  28072                                                       _BCM_QOS_MAP_CHUNK_EGR_DSCP,
  28073                                                       &new_dscp_index,
  28074                                                       SOC_PROFILE_MEM_F_NO_SHARE));
  28075                     for (i = 0; i < (ref_count - port_dscp_map_count - 1); i++) {
  28076                         BCM_IF_ERROR_RETURN(
  28077                             _bcm_egr_dscp_table_entry_reference(unit, new_dscp_index,
  28078                                                                 _BCM_QOS_MAP_CHUNK_EGR_DSCP));
  28079                     }
  28080                     BCM_IF_ERROR_RETURN(
  28081                         _bcm_td_egr_l3_intf_dscp_map_update(unit, port,
  28082                                                             (new_dscp_index >> port_shift)));
  28083                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  28084                     BCM_IF_ERROR_RETURN(
  28085                         _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));
  28086                     for (i = 0; i < ref_count; i++) {
  28087                         BCM_IF_ERROR_RETURN(
  28088                             _bcm_egr_dscp_table_entry_delete(unit, dscp_index));
  28089                     }
  28090                 }
  28091             }
  28092         } else {
  28093             soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  28094             _bcm_common_profile_mem_ref_cnt_update(unit, EGR_DSCP_TABLEm, port, 1);
  28095             BCM_IF_ERROR_RETURN(
  28096                 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));
  28097             BCM_IF_ERROR_RETURN(
  28098                 _bcm_egr_dscp_table_entry_delete(unit, dscp_index));
  28099         }
  28100         PORT(unit, port).port_dscp_map_set = 1;
  28101 
  28102     } else
  28103 #endif
  28104     {
  28105         sal_memset(&dscp_unmap, 0, sizeof(dscp_unmap));
  28106         soc_mem_field32_set(unit, EGR_DSCP_TABLEm, &dscp_unmap, DSCPf, pkt_dscp);
  28107         SOC_IF_ERROR_RETURN
  28108             (WRITE_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ALL, index, &dscp_unmap));
  28109     }
  28110     return BCM_E_NONE;
  28111 }
  28112 
  28113 /*
  28114  * Function:
  28115  *      bcm_port_dscp_unmap_set
  28116  * Purpose:
  28117  *      Define a mapping for diffserv code points
  28118  *      The mapping enable/disable is controlled by a seperate API
  28119  *      bcm_port_dscp_map_enable_set/get
  28120  *      Also Enable/Disable control for DSCP mapping for tunnels
  28121  *      are available in the respective tunnel create APIs.
  28122  * Parameters:
  28123  *      unit - switch device
  28124  *      port - switch port      or -1 to setup global mapping table.
  28125  *      internal_pri - internal priority
  28126  *      color - Red/Yellow/Green
  28127  *      pkt_dscp - DSCP marking on outgoing packet
  28128  * Returns:
  28129  *      BCM_E_XXX
  28130  */
  28131 int
  28132 bcm_esw_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri,
  28133                             bcm_color_t color, int pkt_dscp)
  28134 {
  28135     int rv;
  28136     bcm_port_config_t port_conf;
  28137     bcm_pbmp_t pbmp;
  28138 
  28139     /* Make sure port module is initialized. */
  28140     PORT_INIT(unit);
  28141     if (!soc_feature(unit, soc_feature_dscp) ||
  28142         !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  28143         return BCM_E_UNAVAIL;
  28144     }
  28145 
  28146     if (port != -1) {
  28147         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  28148         if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) {
  28149             return BCM_E_PORT;
  28150         }
  28151     }
  28152 
  28153     PORT_LOCK(unit);
  28154 
  28155     /* Get device port configuration. */
  28156     rv = bcm_esw_port_config_get(unit, &port_conf);
  28157     if (BCM_FAILURE(rv)) {
  28158         PORT_UNLOCK(unit);
  28159         return rv;
  28160     }
  28161     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  28162     BCM_PBMP_OR(pbmp, port_conf.cpu);
  28163 #ifdef BCM_KATANA2_SUPPORT
  28164     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  28165         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  28166         if (BCM_FAILURE(rv)) {
  28167             PORT_UNLOCK(unit);
  28168             return (rv);
  28169         }
  28170     }
  28171     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  28172         soc_feature(unit, soc_feature_subtag_coe)) {
  28173         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  28174     }
  28175 #endif
  28176 
  28177     if (port == -1) {
  28178         PBMP_ITER(pbmp, port) {
  28179             rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color,
  28180                                           pkt_dscp);
  28181             if (BCM_FAILURE(rv)) {
  28182                 PORT_UNLOCK(unit);
  28183                 return rv;
  28184             }
  28185         }
  28186     } else if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  28187         rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color,
  28188                                       pkt_dscp);
  28189     } else {
  28190         rv = BCM_E_PORT;
  28191     }
  28192     PORT_UNLOCK(unit);
  28193 
  28194     return rv;
  28195 }
  28196 
  28197 /*
  28198  * Function:
  28199  *      _bcm_port_dscp_unmap_get
  28200  * Purpose:
  28201  *      Internal implementation for bcm_port_dscp_unmap_get
  28202  * Returns:
  28203  *      BCM_E_XXX
  28204  */
  28205 STATIC int
  28206 _bcm_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri,
  28207                          bcm_color_t color, int *pkt_dscp)
  28208 {
  28209     int index, port_shift = 6;
  28210     egr_dscp_table_entry_t  dscp_unmap;
  28211 #if defined(BCM_TRIDENT_SUPPORT)
  28212     egr_dscp_table_entry_t egr_dscp_map_entries[64];
  28213     void *entries[1];
  28214     uint32 dscp_index = 0;
  28215     void *entry;
  28216 #endif
  28217     if ((internal_pri < 0) || (internal_pri > 15) ||
  28218         ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  28219          (color != bcmColorRed))) {
  28220         return BCM_E_PARAM;
  28221     }
  28222 
  28223     /* EGR_DSCP_TABLE table is indexed with
  28224      * port[5:0] priority[3:0] CNG [1:0]
  28225      */
  28226     index = (port << port_shift) | (internal_pri << 2) |
  28227                  _BCM_COLOR_ENCODING(unit, color);
  28228 
  28229     if (SOC_IS_TRIDENT3X(unit)) {
  28230         SOC_IF_ERROR_RETURN
  28231         (READ_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  28232         *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm,
  28233                                         &dscp_unmap, QOSf);
  28234 
  28235         SOC_IF_ERROR_RETURN
  28236         (READ_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  28237         *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm,
  28238                                         &dscp_unmap, QOSf);
  28239     } else
  28240 #if defined(BCM_TRIDENT_SUPPORT)
  28241     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
  28242         dscp_index = port << port_shift;
  28243         index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color);
  28244 
  28245         sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries));
  28246         entries[0] = &egr_dscp_map_entries;
  28247 
  28248         BCM_IF_ERROR_RETURN(
  28249             _bcm_egr_dscp_table_entry_get(unit, dscp_index,
  28250                                           _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries));
  28251         entry = &egr_dscp_map_entries[index];
  28252         *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm,
  28253                                         entry, DSCPf);
  28254     } else
  28255 #endif
  28256     {
  28257         SOC_IF_ERROR_RETURN
  28258             (READ_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  28259         *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm,
  28260                                         &dscp_unmap, DSCPf);
  28261     }
  28262     return BCM_E_NONE;
  28263 }
  28264 
  28265 /*
  28266  * Function:
  28267  *      bcm_port_dscp_unmap_get
  28268  * Purpose:
  28269  *      Retrieve a mapping for diffserv code points
  28270  *      The mapping enable/disable is controlled by a seperate API
  28271  *      bcm_port_dscp_map_enable_set/get
  28272  *      Also Enable/Disable control for DSCP mapping for tunnels
  28273  *      are available in the respective tunnel create APIs.
  28274  * Parameters:
  28275  *      unit - switch device
  28276  *      port - switch port.
  28277  *      internal_pri - internal priority
  28278  *      color - Red/Yellow/Green
  28279  *      pkt_dscp - DSCP marking on outgoing packet
  28280  * Returns:
  28281  *      BCM_E_XXX
  28282  */
  28283 int
  28284 bcm_esw_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri,
  28285                             bcm_color_t color, int *pkt_dscp)
  28286 {
  28287     int rv;
  28288     bcm_port_config_t port_conf;
  28289     bcm_pbmp_t pbmp;
  28290 
  28291     /* Make sure port module is initialized. */
  28292     PORT_INIT(unit);
  28293     if (!soc_feature(unit, soc_feature_dscp) ||
  28294         !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  28295         return BCM_E_UNAVAIL;
  28296     }
  28297 
  28298     if (port != -1) {
  28299         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  28300         if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) {
  28301             return BCM_E_PORT;
  28302         }
  28303     }
  28304 
  28305     PORT_LOCK(unit);
  28306 
  28307     /* Get device port configuration. */
  28308     rv = bcm_esw_port_config_get(unit, &port_conf);
  28309     if (BCM_FAILURE(rv)) {
  28310         PORT_UNLOCK(unit);
  28311         return rv;
  28312     }
  28313     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  28314     BCM_PBMP_OR(pbmp, port_conf.cpu);
  28315 #ifdef BCM_KATANA2_SUPPORT
  28316     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  28317         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  28318         if (BCM_FAILURE(rv)) {
  28319             PORT_UNLOCK(unit);
  28320             return (rv);
  28321         }
  28322     }
  28323     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  28324         soc_feature(unit, soc_feature_subtag_coe)) {
  28325         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  28326     }
  28327 #endif
  28328 
  28329     if (port == -1) {
  28330         PBMP_ITER(pbmp, port) {
  28331             break;
  28332         }
  28333     }
  28334 
  28335     if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  28336         rv = _bcm_port_dscp_unmap_get(unit, port, internal_pri, color,
  28337                                       pkt_dscp);
  28338     } else {
  28339         rv = BCM_E_PORT;
  28340     }
  28341 
  28342     PORT_UNLOCK(unit);
  28343     return rv;
  28344 }
  28345 
  28346 #undef DSCP_CODE_POINT_MAX
  28347 #undef DSCP_CODE_POINT_CNT
  28348 
  28349 STATIC int
  28350 _bcm_esw_port_modid_egress_resolve(int unit, _bcm_port_egr_dest_t *egr_dst)
  28351 {
  28352     int             port_adjst = 0, mod_adjust = 0;
  28353     int             isLocal = 0;
  28354     bcm_module_t    my_mod, modid;
  28355 
  28356     if (BCM_GPORT_IS_SET(egr_dst->in_port)) {
  28357         bcm_trunk_t     tid;
  28358         int             id;
  28359         bcm_port_t      port;
  28360 
  28361         BCM_IF_ERROR_RETURN(
  28362             _bcm_esw_gport_resolve(unit, egr_dst->in_port, &modid, &port,
  28363                                    &tid, &id));
  28364         if ((-1 != id) || (-1 != tid)) {
  28365             return BCM_E_PORT;
  28366         }
  28367         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod));
  28368         BCM_IF_ERROR_RETURN(
  28369             _bcm_esw_modid_is_local(unit, modid, &isLocal));
  28370 
  28371         if ((TRUE == isLocal) && (modid != my_mod)){
  28372             port_adjst = 32;
  28373             mod_adjust = 1;
  28374         }
  28375         egr_dst->out_min_port = egr_dst->out_max_port = port + port_adjst;
  28376         egr_dst->out_min_modid = egr_dst->out_max_modid = modid - mod_adjust;
  28377     } else {
  28378         if (egr_dst->in_modid < 0) {
  28379             egr_dst->out_min_modid = 0;
  28380             egr_dst->out_max_modid = SOC_MODID_MAX(unit);
  28381         } else if (!SOC_MODID_ADDRESSABLE(unit, egr_dst->in_modid)) {
  28382             return BCM_E_PARAM;
  28383         } else {
  28384             egr_dst->out_min_modid = egr_dst->out_max_modid = egr_dst->in_modid;
  28385         }
  28386 
  28387         if (egr_dst->in_port < 0) {
  28388             egr_dst->out_min_port = 0;
  28389             egr_dst->out_max_port = SOC_PORT_MAX(unit, all);
  28390         } else if (!SOC_PORT_ADDRESSABLE(unit, egr_dst->in_port)) {
  28391             return BCM_E_PORT;
  28392         } else {
  28393             egr_dst->out_min_port = egr_dst->out_max_port = egr_dst->in_port;
  28394         }
  28395     }
  28396 
  28397     return BCM_E_NONE;
  28398 }
  28399 
  28400 
  28401 /*
  28402  * Function:
  28403  *      bcm_port_egress_set
  28404  * Description:
  28405  *      Set switching only to indicated ports from given (modid, port).
  28406  * Parameters:
  28407  *      unit - StrataSwitch PCI device unit number (driver internal).
  28408  *      port  - ingress port number.
  28409  *      modid - source module ID index (in HiGig mod header).
  28410  *      pbmp - bitmap of ports to allow egress.
  28411  * Returns:
  28412  *      BCM_E_xxxx
  28413  * Note:
  28414  *      if port < 0, means all/any port
  28415  *      if modid < 0, means all/any modid
  28416  */
  28417 int
  28418 bcm_esw_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp)
  28419 {
  28420     egr_mask_entry_t        em_entry;
  28421     int                     em_index;
  28422     bcm_module_t            cur_mod, hw_mod;
  28423     bcm_pbmp_t              em_pbmp;
  28424     bcm_port_t              cur_port, hw_port;
  28425     int                     rv = BCM_E_NONE;
  28426     _bcm_port_egr_dest_t    egr_dst;
  28427     int                     mod_is_local = 0;
  28428     int                     mod_port_map_done = 0;
  28429 
  28430     /* Make sure port module is initialized. */
  28431     PORT_INIT(unit);
  28432 
  28433     if(bcm_common_oamp_port_enable_get(unit, port)) {
  28434         LOG_ERROR(BSL_LS_BCM_PORT,
  28435                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  28436                    port));
  28437         return BCM_E_PARAM;
  28438     }
  28439 
  28440 #ifdef BCM_TRIDENT_SUPPORT
  28441     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  28442         return bcm_td_port_egress_set(unit, port, modid, pbmp);
  28443     }
  28444 #endif /* BCM_TRIDENT_SUPPORT */
  28445 
  28446 #ifdef BCM_HURRICANE3_SUPPORT
  28447     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  28448         return bcm_hr3_port_egress_set(unit, port, modid, pbmp);
  28449     }
  28450 #endif /* BCM_HURRICANE3_SUPPORT */
  28451 
  28452     if (!SOC_IS_XGS_SWITCH(unit)) {
  28453         if (BCM_PBMP_EQ(pbmp, PBMP_ALL(unit))) {
  28454             return BCM_E_NONE;
  28455         } else {
  28456             return BCM_E_UNAVAIL;
  28457         }
  28458     }
  28459 
  28460     sal_memset(&em_entry, 0, sizeof(egr_mask_entry_t));
  28461 
  28462     BCM_PBMP_NEGATE(em_pbmp, pbmp);
  28463     BCM_PBMP_AND(em_pbmp, PBMP_ALL(unit));
  28464     BCM_PBMP_REMOVE(em_pbmp, PBMP_LB(unit));
  28465     soc_mem_pbmp_field_set(unit, EGR_MASKm, &em_entry, EGRESS_MASKf,
  28466                            &em_pbmp);
  28467 
  28468     egr_dst.in_modid = modid;
  28469     egr_dst.in_port = port;
  28470     BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28471     /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had
  28472      * already performed module and port mapping for devices with
  28473      * multiple module IDs.
  28474      */
  28475     mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0;
  28476 
  28477     soc_mem_lock(unit, EGR_MASKm);
  28478     for (cur_mod = egr_dst.out_min_modid; cur_mod <= egr_dst.out_max_modid; cur_mod++) {
  28479         rv = _bcm_esw_modid_is_local(unit, cur_mod, &mod_is_local);
  28480         if (BCM_FAILURE(rv)) {
  28481             break;
  28482         }
  28483         for (cur_port = egr_dst.out_min_port; cur_port <= egr_dst.out_max_port; cur_port++) {
  28484             if (mod_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) {
  28485                 if (cur_port <= SOC_MODPORT_MAX(unit)) {
  28486                     rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  28487                             cur_mod, cur_port, &hw_mod, &hw_port);
  28488                     if (BCM_FAILURE(rv)) {
  28489                         break;
  28490                     }
  28491                 } else {
  28492                     break;
  28493                 }
  28494             } else {
  28495                 hw_mod = cur_mod;
  28496                 hw_port = cur_port;
  28497             }
  28498 
  28499             em_index = (hw_mod & SOC_MODID_MAX(unit)) *
  28500                     (SOC_PORT_ADDR_MAX(unit) + 1) |
  28501                     (hw_port & SOC_PORT_ADDR_MAX(unit));
  28502             rv = soc_mem_write(unit, EGR_MASKm, MEM_BLOCK_ALL,
  28503                     em_index, &em_entry);
  28504             if (!BCM_SUCCESS(rv)) {
  28505                 break;
  28506             }
  28507         }
  28508         if (!BCM_SUCCESS(rv)) {
  28509             break;
  28510         }
  28511     }
  28512     soc_mem_unlock(unit, EGR_MASKm);
  28513 
  28514     return rv;
  28515 }
  28516 
  28517 /*
  28518  * Function:
  28519  *      bcm_port_egress_get
  28520  * Description:
  28521  *      Retrieve bitmap of ports for which switching is enabled
  28522  *      for (modid, port).
  28523  * Parameters:
  28524  *      unit - StrataSwitch PCI device unit number (driver internal).
  28525  *      port  - ingress port number.
  28526  *      modid - source module ID index (in HiGig mod header).
  28527  *      pbmp - (OUT) bitmap of ports where egress allowed.
  28528  * Returns:
  28529  *      BCM_E_xxxx
  28530  */
  28531 int
  28532 bcm_esw_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp)
  28533 {
  28534     egr_mask_entry_t    em_entry;
  28535     int                 em_index;
  28536     bcm_pbmp_t          em_pbmp, temp_pbmp;
  28537     _bcm_port_egr_dest_t    egr_dst;
  28538     int                 mod_port_map_done = 0;
  28539     bcm_module_t        hw_mod;
  28540     bcm_port_t          hw_port;
  28541 
  28542     /* Make sure port module is initialized. */
  28543     PORT_INIT(unit);
  28544 
  28545     if(bcm_common_oamp_port_enable_get(unit, port)) {
  28546         LOG_ERROR(BSL_LS_BCM_PORT,
  28547                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  28548                    port));
  28549         return BCM_E_PARAM;
  28550     }
  28551 
  28552 #ifdef BCM_TRIDENT_SUPPORT
  28553     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  28554         return bcm_td_port_egress_get(unit, port, modid, pbmp);
  28555     }
  28556 #endif /* BCM_TRIDENT_SUPPORT */
  28557 
  28558 #ifdef BCM_HURRICANE3_SUPPORT
  28559     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  28560         return bcm_hr3_port_egress_get(unit, port, modid, pbmp);
  28561     }
  28562 #endif /* BCM_HURRICANE3_SUPPORT */
  28563 
  28564     if (!SOC_IS_XGS_SWITCH(unit)) {
  28565         BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit));
  28566         return BCM_E_NONE;
  28567     }
  28568 
  28569     if ((modid < 0) || (port < 0) ){
  28570             return BCM_E_PARAM;
  28571     }
  28572 
  28573     egr_dst.in_modid = modid;
  28574     egr_dst.in_port = port;
  28575     BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28576     /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had
  28577      * already performed module and port mapping for devices with
  28578      * multiple module IDs.
  28579      */
  28580     mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0;
  28581 
  28582     if (!mod_port_map_done) {
  28583         PORT_DUALMODID_VALID(unit, egr_dst.out_min_port);
  28584         BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  28585                     egr_dst.out_min_modid, egr_dst.out_min_port,
  28586                     &hw_mod, &hw_port));
  28587     } else {
  28588         hw_mod = egr_dst.out_min_modid;
  28589         hw_port = egr_dst.out_min_port;
  28590     }
  28591     em_index = (hw_mod & SOC_MODID_MAX(unit)) *
  28592         (SOC_PORT_ADDR_MAX(unit) + 1) | (hw_port & SOC_PORT_ADDR_MAX(unit));
  28593 
  28594     BCM_IF_ERROR_RETURN
  28595         (READ_EGR_MASKm(unit, MEM_BLOCK_ALL, em_index, &em_entry));
  28596 
  28597     BCM_PBMP_CLEAR(em_pbmp);
  28598     soc_mem_pbmp_field_get(unit, EGR_MASKm, &em_entry, EGRESS_MASKf,
  28599                            &em_pbmp);
  28600     BCM_PBMP_NEGATE(temp_pbmp, em_pbmp);
  28601     BCM_PBMP_AND(temp_pbmp, PBMP_ALL(unit));
  28602     BCM_PBMP_REMOVE(temp_pbmp, PBMP_LB(unit));
  28603     BCM_PBMP_ASSIGN(*pbmp, temp_pbmp);
  28604 
  28605     return BCM_E_NONE;
  28606 }
  28607 
  28608 #ifdef BCM_TRIUMPH2_SUPPORT
  28609 STATIC int
  28610 _bcm_port_src_mod_egress_profile_add(int unit, bcm_port_t port,
  28611                                      int min_mod, int max_mod, pbmp_t pbmp)
  28612 {
  28613     int i, region, modid_cnt, new_region, empty_profile, alloc_size;
  28614     int rv = BCM_E_NONE;
  28615     uint32 val, add_index;
  28616     src_modid_egress_entry_t *srcmodegr_p, *sme_buf;
  28617     pbmp_t test_pbmp;
  28618     void   *entries[1];     /* for profile memories      */
  28619 
  28620     modid_cnt = SOC_MODID_MAX(unit) + 1;
  28621     region = PORT_SRC_MOD_EGR_PROF_PTR(unit, port);
  28622     empty_profile = TRUE;
  28623     new_region = -1;
  28624 
  28625     alloc_size = modid_cnt * sizeof(*srcmodegr_p);
  28626     sme_buf = sal_alloc(alloc_size, "SRC_MODID_EGRESS update buffer");
  28627     if (NULL == sme_buf) {
  28628         return BCM_E_MEMORY;
  28629     }
  28630     sal_memset(sme_buf, 0, alloc_size);
  28631     entries[0] = sme_buf;
  28632 
  28633     if (0 <= region) {
  28634         rv = soc_profile_mem_get(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  28635                                  region * modid_cnt, modid_cnt, entries);
  28636     } /* Else cleared by memset above.  Null entry is all 0's */
  28637 
  28638     if (BCM_SUCCESS(rv)) {
  28639         for (i = min_mod; i <= max_mod; i++) {
  28640             /* Profile memory is an array of entries, not a DMA buffer */
  28641             srcmodegr_p = sme_buf + i; /* Both same pointer type */
  28642             soc_mem_pbmp_field_set(unit, SRC_MODID_EGRESSm, srcmodegr_p,
  28643                                    PORT_BLOCK_MASK_BITMAPf, &pbmp);
  28644         }
  28645 
  28646         if (BCM_PBMP_IS_NULL(pbmp)) {
  28647             /* Check for empty bitmap */
  28648             for (i = 0; i < modid_cnt; i++) {
  28649                 srcmodegr_p = sme_buf + i; /* Both same pointer type */
  28650                 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, srcmodegr_p,
  28651                                        PORT_BLOCK_MASK_BITMAPf, &test_pbmp);
  28652                 if (BCM_PBMP_NOT_NULL(test_pbmp)) {
  28653                     empty_profile = FALSE;
  28654                     break;
  28655                 }
  28656             }
  28657         } else {
  28658             empty_profile = FALSE;
  28659         }
  28660 
  28661         if (!empty_profile) {
  28662             rv = soc_profile_mem_add(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  28663                                      entries, modid_cnt, &add_index);
  28664             if (BCM_SUCCESS(rv)) {
  28665                 new_region = add_index / modid_cnt;
  28666             }
  28667         }
  28668     }
  28669 
  28670     sal_free(sme_buf);
  28671     BCM_IF_ERROR_RETURN(rv);
  28672 
  28673     BCM_IF_ERROR_RETURN(READ_SRC_MODID_EGRESS_SELr(unit, port, &val));
  28674     if (empty_profile) {
  28675         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 0);
  28676         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val,
  28677                           SRCMOD_INDEXf, 0);
  28678     } else {
  28679         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 1);
  28680         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val,
  28681                           SRCMOD_INDEXf, new_region);
  28682     }
  28683     BCM_IF_ERROR_RETURN(WRITE_SRC_MODID_EGRESS_SELr(unit, port, val));
  28684 
  28685     if (-1 != region) {
  28686         BCM_IF_ERROR_RETURN
  28687             (soc_profile_mem_delete(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  28688                                     region * modid_cnt));
  28689     }
  28690 
  28691     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = new_region;
  28692     return BCM_E_NONE;
  28693 }
  28694 #endif
  28695 
  28696 /*
  28697  * Function:
  28698  *      bcm_port_modid_egress_set
  28699  * Description:
  28700  *      Set port bitmap of egress ports on which the incoming packets
  28701  *      will be forwarded.
  28702  * Parameters:
  28703  *      unit - StrataSwitch PCI device unit number (driver internal).
  28704  *      port  - ingress port number.
  28705  *      modid - source module ID index (in HiGig mod header).
  28706  *      pbmp - bitmap of ports to allow egress.
  28707  * Returns:
  28708  *      BCM_E_xxxx
  28709  * Note:
  28710  *      if port < 0, means all/any port
  28711  *      if modid < 0, means all/any modid
  28712  */
  28713 int
  28714 bcm_esw_port_modid_egress_set(int unit, bcm_port_t port,
  28715                               bcm_module_t modid, bcm_pbmp_t pbmp)
  28716 {
  28717 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  28718     int rv=BCM_E_UNAVAIL;
  28719 
  28720     /* Make sure port module is initialized. */
  28721     PORT_INIT(unit);
  28722 
  28723 #ifdef  BCM_HERCULES15_SUPPORT
  28724     if (SOC_IS_HERCULES15(unit)) {
  28725         mem_ing_srcmodblk_entry_t srcmod;
  28726         uint32 smf;
  28727         bcm_module_t mod_idx, min_mod, max_mod;
  28728         bcm_pbmp_t mod_pbmp;
  28729         int bk=-1, blk;
  28730 
  28731         if (port >= 0) {
  28732             if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) {
  28733                 return BCM_E_PORT;
  28734             }
  28735             bk = SOC_PORT_BLOCK(unit, port);
  28736         }
  28737 
  28738         if (modid < 0) {
  28739             min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm);
  28740             max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm);
  28741         } else if (modid > soc_mem_index_max(unit, MEM_ING_SRCMODBLKm)) {
  28742             return BCM_E_PARAM;
  28743         } else {
  28744             min_mod = max_mod = modid;
  28745         }
  28746 
  28747         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  28748         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28749         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28750             return BCM_E_PARAM;
  28751         }
  28752 
  28753         soc_mem_lock(unit, MEM_ING_SRCMODBLKm);
  28754         SOC_MEM_BLOCK_ITER(unit, MEM_ING_SRCMODBLKm, blk) {
  28755             if ((port >= 0) && (bk !=blk)) {
  28756                 continue;
  28757             }
  28758             for (mod_idx = min_mod; mod_idx <= max_mod; mod_idx++) {
  28759                  sal_memset(&srcmod, 0, sizeof(srcmod));
  28760                  rv = READ_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod);
  28761                  if (rv >= 0) {
  28762                      SOC_PBMP_WORD_SET(mod_pbmp, 0,
  28763                          soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf));
  28764                      if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28765                          smf = SOC_PBMP_WORD_GET(pbmp, 0);
  28766                          soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, &smf);
  28767                          rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod);
  28768                      }
  28769                  }
  28770             }
  28771         }
  28772         soc_mem_unlock(unit, MEM_ING_SRCMODBLKm);
  28773     }
  28774 #endif /* BCM_HERCULES15_SUPPORT */
  28775 
  28776 #ifdef BCM_TRIUMPH2_SUPPORT
  28777     if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  28778         src_modid_ingress_block_entry_t srcmoding;
  28779         _bcm_port_egr_dest_t egr_dst;
  28780         int all_st_ports;
  28781         int i;
  28782         bcm_port_t p;
  28783         pbmp_t mod_pbmp, all_pbmp;
  28784 
  28785         if ((port != -1) && (!SOC_PORT_VALID(unit, port))) {
  28786             return BCM_E_PORT;
  28787         }
  28788         egr_dst.in_port = port;
  28789         egr_dst.in_modid = modid;
  28790         BCM_IF_ERROR_RETURN(
  28791             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28792 
  28793         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  28794             all_st_ports = 0;
  28795         } else {
  28796             all_st_ports = 1;
  28797         }
  28798 
  28799         SOC_PBMP_CLEAR(all_pbmp);
  28800         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  28801 
  28802 #ifdef BCM_KATANA2_SUPPORT
  28803         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  28804             soc_feature(unit, soc_feature_subtag_coe)) {
  28805             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  28806         }
  28807 #endif
  28808         /* First program the ingress blocking */
  28809         soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm);
  28810         for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  28811             rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i,
  28812                                                &srcmoding);
  28813             if (BCM_FAILURE(rv)) {
  28814                 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  28815                 return rv;
  28816             }
  28817             if (!all_st_ports) {
  28818                 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  28819                                        &srcmoding, PORT_BITMAPf, &mod_pbmp);
  28820                 BCM_PBMP_PORT_REMOVE(mod_pbmp, egr_dst.out_min_port);
  28821             } else {
  28822                 BCM_PBMP_ASSIGN(mod_pbmp, all_pbmp);
  28823                 BCM_PBMP_OR(mod_pbmp, PBMP_LB(unit));
  28824                 PBMP_ST_ITER(unit, p) {
  28825                     BCM_PBMP_PORT_REMOVE(mod_pbmp, p);
  28826                 }
  28827             }
  28828             soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm,
  28829                                    &srcmoding, PORT_BITMAPf, &mod_pbmp);
  28830             rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i,
  28831                                                 &srcmoding);
  28832             if (BCM_FAILURE(rv)) {
  28833                 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  28834                 return rv;
  28835             }
  28836         }
  28837         soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  28838 
  28839         /* Deal with the egress blocking - use one of 8 profiles */
  28840         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  28841         BCM_PBMP_AND(mod_pbmp, all_pbmp);
  28842         BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit));
  28843         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28844             return BCM_E_PARAM;
  28845         }
  28846 
  28847         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  28848         BCM_PBMP_AND(mod_pbmp, all_pbmp);
  28849         BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit));
  28850 
  28851         soc_mem_lock(unit, SRC_MODID_EGRESSm);
  28852         if (!all_st_ports) {
  28853             /* Deal with a single stack port and its profile */
  28854             /* coverity[overrun-call : FALSE] */
  28855             rv = _bcm_port_src_mod_egress_profile_add(unit,
  28856                                                       egr_dst.out_min_port,
  28857                                                       egr_dst.out_min_modid,
  28858                                                       egr_dst.out_max_modid,
  28859                                                       mod_pbmp);
  28860             if (BCM_FAILURE(rv)) {
  28861                 soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  28862                 return rv;
  28863             }
  28864         } else {
  28865             /* Deal with all stack ports and their profiles */
  28866             PBMP_ST_ITER(unit, p) {
  28867                 /* coverity[overrun-local : FALSE] */
  28868                 rv = _bcm_port_src_mod_egress_profile_add(unit, p,
  28869                                                      egr_dst.out_min_modid,
  28870                                                      egr_dst.out_max_modid,
  28871                                                           mod_pbmp);
  28872                 if (BCM_FAILURE(rv)) {
  28873                     soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  28874                     return rv;
  28875                 }
  28876             }
  28877         }
  28878         soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  28879 
  28880         return rv;
  28881     }
  28882 #endif
  28883 
  28884 #ifdef BCM_TRX_SUPPORT
  28885     if (SOC_IS_TRX(unit)) {
  28886         src_modid_block_entry_t srcmod;
  28887         int modid_cnt, idx, i, j;
  28888         bcm_pbmp_t mod_pbmp;
  28889         _bcm_port_egr_dest_t    egr_dst;
  28890 
  28891         /* Number of supported MODIDs for this unit */
  28892         modid_cnt = SOC_MODID_MAX(unit) + 1;
  28893 
  28894         egr_dst.in_port = port;
  28895         egr_dst.in_modid = modid;
  28896         BCM_IF_ERROR_RETURN(
  28897             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28898 
  28899         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  28900             /* process to retrieve hg_port index from port */
  28901             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  28902                 SOC_IS_GREYHOUND2(unit)) {
  28903                 egr_dst.out_min_port = egr_dst.out_max_port;
  28904             } else {
  28905                 SOC_IF_ERROR_RETURN(
  28906                     soc_xgs3_port_num_to_higig_port_num(unit,
  28907                                 egr_dst.out_max_port, &egr_dst.out_min_port));
  28908             }
  28909 
  28910             egr_dst.out_max_port = egr_dst.out_min_port;
  28911         } else {
  28912             egr_dst.out_min_port = soc_mem_index_min(unit, SRC_MODID_BLOCKm) / modid_cnt;
  28913             egr_dst.out_max_port = soc_mem_index_max(unit, SRC_MODID_BLOCKm) / modid_cnt;
  28914         }
  28915 
  28916         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  28917         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28918         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28919             return BCM_E_PARAM;
  28920         }
  28921 
  28922         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  28923         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28924 
  28925         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  28926         for (i = egr_dst.out_min_port; i <= egr_dst.out_max_port; i++) {
  28927             for (j = egr_dst.out_min_modid; j <= egr_dst.out_max_modid; j++) {
  28928                 idx = i * modid_cnt + j;
  28929                 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  28930                 if (rv >= 0) {
  28931                     soc_SRC_MODID_BLOCKm_field_set(unit, &srcmod,
  28932                                                    PORT_BLOCK_MASK_BITMAPf,
  28933                                                    (uint32 *)&mod_pbmp);
  28934                     rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx,
  28935                                                 &srcmod);
  28936                 }
  28937                 if (rv < 0) {
  28938                     soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28939                     return rv;
  28940                 }
  28941             }
  28942         }
  28943         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28944         return rv;
  28945     }
  28946 #endif /* BCM_TRX_SUPPORT */
  28947 
  28948 #ifdef BCM_FIREBOLT_SUPPORT
  28949     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  28950         src_modid_block_entry_t srcmod;
  28951         bcm_module_t mod_idx;
  28952         int p_idx, min_p, max_p;
  28953         int tbl_size, modid_cnt, idx;
  28954         bcm_pbmp_t mod_pbmp, tst_pbmp, hg_pbmp;
  28955         int cpu=0, ether=0;
  28956         uint32 xge_val;
  28957         _bcm_port_egr_dest_t    egr_dst;
  28958 #if defined(BCM_RAPTOR_SUPPORT)
  28959         uint32  rp_val;
  28960 #endif /* BCM_RAPTOR_SUPPORT */
  28961         /* Number of supported MODIDs for this unit */
  28962         modid_cnt = SOC_MODID_MAX(unit) + 1;
  28963 
  28964 
  28965         egr_dst.in_port = port;
  28966         egr_dst.in_modid = modid;
  28967         BCM_IF_ERROR_RETURN(
  28968             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28969 
  28970         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  28971             min_p = max_p = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  28972         } else {
  28973             min_p = 0;
  28974             tbl_size = soc_mem_index_count(unit, SRC_MODID_BLOCKm);
  28975             max_p = (tbl_size / modid_cnt) - 1;
  28976             assert(max_p >= 0);
  28977         }
  28978 
  28979         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  28980         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28981         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28982             return BCM_E_PARAM;
  28983         }
  28984 
  28985         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  28986         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28987 
  28988         BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp);
  28989         BCM_PBMP_AND(tst_pbmp, PBMP_CMIC(unit));
  28990         if (BCM_PBMP_NOT_NULL(tst_pbmp)) {
  28991             cpu = 1;
  28992         }
  28993 
  28994         BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp);
  28995         BCM_PBMP_AND(tst_pbmp, PBMP_E_ALL(unit));
  28996         if (BCM_PBMP_NOT_NULL(tst_pbmp)) {
  28997             ether = 1;
  28998             BCM_PBMP_ASSIGN(tst_pbmp, PBMP_XE_ALL(unit));
  28999         }
  29000 
  29001         BCM_PBMP_ASSIGN(hg_pbmp, mod_pbmp);
  29002         BCM_PBMP_AND(hg_pbmp, PBMP_ST_ALL(unit));
  29003 
  29004         if (ether && BCM_PBMP_NOT_NULL(tst_pbmp)) {
  29005             BCM_PBMP_OR(hg_pbmp, tst_pbmp);
  29006         }
  29007         xge_val = SOC_PBMP_WORD_GET(hg_pbmp, 0) >> SOC_HG_OFFSET(unit);
  29008 
  29009         /* In Raven, port #3 is the GMII port and it introduces a hole in the ST pbmp */
  29010         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  29011         for (p_idx = min_p; p_idx <= max_p; p_idx++) {
  29012             if (SOC_IS_RAVEN(unit) && p_idx == 3) {
  29013                 continue;
  29014             }
  29015             for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) {
  29016                  sal_memset(&srcmod, 0, sizeof(srcmod));
  29017                  /* Table is 2-dimensional array */
  29018                  if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  29019                      idx = (p_idx - 1) * modid_cnt + mod_idx;
  29020                  } else {
  29021                      idx = (p_idx * modid_cnt) + mod_idx;
  29022                  }
  29023                  rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  29024                  if (rv >= 0) {
  29025                      soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  29026                                                       CPU_PORT_BLOCK_MASKf,
  29027                                                       (cpu) ? 1 : 0);
  29028                      if (SOC_IS_FB_FX_HX(unit)) {
  29029                          soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  29030                                                           GE_PORT_BLOCK_MASKf,
  29031                                                           (ether) ? 1 : 0);
  29032                      }
  29033                      soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  29034                                                       HIGIG_XGE_PORT_BLOCK_MASKf,
  29035                                                       xge_val);
  29036 #if defined(BCM_RAPTOR_SUPPORT)
  29037                      if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  29038                                              PORT_0_5_BLOCK_MASKf)) {
  29039                           rp_val = (SOC_PBMP_WORD_GET(mod_pbmp, 0)) &
  29040                               ((1 << soc_reg_field_length(unit, SRC_MODID_BLOCKm,
  29041                                                    PORT_0_5_BLOCK_MASKf )) - 1);
  29042                           soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  29043                                                            PORT_0_5_BLOCK_MASKf,
  29044                                                            rp_val);
  29045                      }
  29046 #endif /* BCM_RAPTOR_SUPPORT */
  29047                      rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL,
  29048                                                  idx, &srcmod);
  29049                  }
  29050             }
  29051         }
  29052         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  29053     }
  29054 #endif /* BCM_FIREBOLT_SUPPORT */
  29055 
  29056     return rv;
  29057 #else
  29058     return BCM_E_UNAVAIL;
  29059 #endif  /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */
  29060 }
  29061 
  29062 /*
  29063  * Function:
  29064  *      bcm_port_modid_egress_get
  29065  * Description:
  29066  *      Retrieve port bitmap of egress ports on which the incoming packets
  29067  *      will be forwarded.
  29068  * Parameters:
  29069  *      unit - StrataSwitch PCI device unit number (driver internal).
  29070  *      port  - ingress port number.
  29071  *      modid - source module ID index (in HiGig mod header).
  29072  *      pbmp - (OUT) bitmap of ports where egress allowed.
  29073  * Returns:
  29074  *      BCM_E_xxxx
  29075  */
  29076 int
  29077 bcm_esw_port_modid_egress_get(int unit, bcm_port_t port,
  29078                               bcm_module_t modid, bcm_pbmp_t *pbmp)
  29079 {
  29080 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  29081     int rv=BCM_E_UNAVAIL;
  29082 
  29083     /* Make sure port module is initialized. */
  29084     PORT_INIT(unit);
  29085 
  29086 #ifdef  BCM_HERCULES15_SUPPORT
  29087     if (SOC_IS_HERCULES15(unit)) {
  29088         mem_ing_srcmodblk_entry_t srcmod;
  29089         bcm_module_t min_mod, max_mod;
  29090         int blk, rv=BCM_E_NONE;
  29091 
  29092         if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) {
  29093             return BCM_E_PORT;
  29094         }
  29095 
  29096         min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm);
  29097         max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm);
  29098         if ((modid < min_mod) || (modid > max_mod))  {
  29099             return BCM_E_PARAM;
  29100         }
  29101 
  29102         blk = SOC_PORT_BLOCK(unit, port);
  29103         SOC_PBMP_CLEAR(*pbmp);
  29104         rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29105         if (rv >= 0) {
  29106             SOC_PBMP_WORD_SET(*pbmp, 0,
  29107                 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf));
  29108         }
  29109     }
  29110 #endif /* BCM_HERCULES15_SUPPORT */
  29111 
  29112 #ifdef BCM_TRIUMPH2_SUPPORT
  29113     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  29114         SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  29115         SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  29116         src_modid_egress_entry_t srcmodegr;
  29117         int idx;
  29118         _bcm_port_egr_dest_t    egr_dst;
  29119         bcm_pbmp_t all_pbmp;
  29120 
  29121         SOC_PBMP_CLEAR(all_pbmp);
  29122         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  29123 
  29124 #ifdef BCM_KATANA2_SUPPORT
  29125         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  29126             soc_feature(unit, soc_feature_subtag_coe)) {
  29127             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  29128         }
  29129 #endif
  29130 
  29131         egr_dst.in_port = port;
  29132         egr_dst.in_modid = modid;
  29133         BCM_IF_ERROR_RETURN(
  29134             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29135 
  29136         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  29137             return BCM_E_PARAM;
  29138         }
  29139         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29140             return BCM_E_PORT;
  29141         }
  29142 
  29143         idx = PORT_SRC_MOD_EGR_PROF_PTR(unit, egr_dst.out_min_port) *
  29144               (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  29145         SOC_IF_ERROR_RETURN(READ_SRC_MODID_EGRESSm(unit, MEM_BLOCK_ANY, idx,
  29146                                                    &srcmodegr));
  29147         soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, &srcmodegr,
  29148                                PORT_BLOCK_MASK_BITMAPf, pbmp);
  29149         BCM_PBMP_NEGATE(*pbmp, *pbmp);
  29150         BCM_PBMP_AND(*pbmp, all_pbmp);
  29151         BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit));
  29152         return SOC_E_NONE;
  29153     }
  29154 #endif
  29155 
  29156 #ifdef BCM_TRX_SUPPORT
  29157     if (SOC_IS_TRX(unit)) {
  29158         src_modid_block_entry_t srcmod;
  29159         int hg_port, idx;
  29160         _bcm_port_egr_dest_t    egr_dst;
  29161 
  29162         egr_dst.in_port = port;
  29163         egr_dst.in_modid = modid;
  29164         BCM_IF_ERROR_RETURN(
  29165             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29166 
  29167         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  29168             return BCM_E_PARAM;
  29169         }
  29170         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29171             return BCM_E_PORT;
  29172         }
  29173 
  29174         /* process to retrieve hg_port index from port */
  29175         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  29176             SOC_IS_GREYHOUND2(unit)) {
  29177             hg_port = egr_dst.out_min_port;
  29178         } else {
  29179             SOC_IF_ERROR_RETURN(
  29180                 soc_xgs3_port_num_to_higig_port_num(unit,
  29181                                         egr_dst.out_min_port, &hg_port));
  29182         }
  29183 
  29184         idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  29185         SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx,
  29186                                                   &srcmod));
  29187         soc_SRC_MODID_BLOCKm_field_get(unit, &srcmod, PORT_BLOCK_MASK_BITMAPf,
  29188                                        (uint32 *)pbmp);
  29189         BCM_PBMP_NEGATE(*pbmp, *pbmp);
  29190         BCM_PBMP_AND(*pbmp, PBMP_ALL(unit));
  29191 
  29192         return SOC_E_NONE;
  29193     }
  29194 #endif
  29195 
  29196 #ifdef BCM_FIREBOLT_SUPPORT
  29197     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  29198         src_modid_block_entry_t srcmod;
  29199         int modid_cnt, p_idx, idx;
  29200         _bcm_port_egr_dest_t    egr_dst;
  29201 
  29202         egr_dst.in_port = port;
  29203         egr_dst.in_modid = modid;
  29204         BCM_IF_ERROR_RETURN(
  29205             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29206 
  29207         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  29208             return BCM_E_PARAM;
  29209         }
  29210         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29211             return BCM_E_PORT;
  29212         }
  29213 
  29214         modid_cnt = SOC_MODID_MAX(unit) + 1;
  29215         p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  29216         if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  29217             idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid;
  29218         } else {
  29219             idx = (p_idx * modid_cnt) + egr_dst.out_min_modid;
  29220         }
  29221 
  29222         rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  29223         BCM_PBMP_CLEAR(*pbmp);
  29224         if (rv >= 0) {
  29225             int cpu, ether;
  29226             pbmp_t hg_pbmp;
  29227             uint32 xge_val;
  29228 #if defined(BCM_RAPTOR_SUPPORT)
  29229             uint32 rp_val;
  29230 #endif /* BCM_RAPTOR_SUPPORT */
  29231             cpu = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  29232                                                    CPU_PORT_BLOCK_MASKf);
  29233             if (SOC_IS_FB_FX_HX(unit)) {
  29234                 ether = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  29235                                                          GE_PORT_BLOCK_MASKf);
  29236             } else {
  29237                 ether = 0;
  29238             }
  29239             xge_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  29240                                                        HIGIG_XGE_PORT_BLOCK_MASKf);
  29241             SOC_PBMP_CLEAR(hg_pbmp);
  29242             SOC_PBMP_WORD_SET(hg_pbmp, 0, xge_val << SOC_HG_OFFSET(unit));
  29243 
  29244 #if defined(BCM_RAPTOR_SUPPORT)
  29245             if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  29246                                     PORT_0_5_BLOCK_MASKf)) {
  29247                 rp_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  29248                                                          PORT_0_5_BLOCK_MASKf);
  29249                 SOC_PBMP_WORD_SET(hg_pbmp, 0, rp_val);
  29250             }
  29251 #endif /* BCM_RAPTOR_SUPPORT */
  29252             BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit));
  29253             if (cpu) {
  29254                 BCM_PBMP_REMOVE(*pbmp, PBMP_CMIC(unit));
  29255             }
  29256             if (ether) {
  29257                 BCM_PBMP_REMOVE(*pbmp, PBMP_E_ALL(unit));
  29258             }
  29259             if (BCM_PBMP_NOT_NULL(hg_pbmp)) {
  29260                 BCM_PBMP_REMOVE(*pbmp, hg_pbmp);
  29261             }
  29262         }
  29263     }
  29264 #endif /* BCM_FIREBOLT_SUPPORT */
  29265 
  29266     return rv;
  29267 #else
  29268     return BCM_E_UNAVAIL;
  29269 #endif  /* BCM_HERCULES15_SUPPORT  || BCM_FIREBOLT_SUPPORT */
  29270 }
  29271 
  29272 /*
  29273  * Function:
  29274  *    bcm_port_modid_enable_set
  29275  * Purpose:
  29276  *    Enable/block packets from a specific module on a port.
  29277  * Parameters:
  29278  *    unit - StrataSwitch PCI device unit number (driver internal).
  29279  *    port - StrataSwitch port number.
  29280  *    modid - Which source module id to enable/disable
  29281  *    enable - TRUE/FALSE Enable/disable forwarding packets from
  29282  *             source module arriving on port.
  29283  * Returns:
  29284  *    BCM_E_XXX
  29285  */
  29286 int
  29287 bcm_esw_port_modid_enable_set(int unit, bcm_port_t port, int modid, int enable)
  29288 {
  29289     int max_mod;
  29290 #ifdef BCM_HERCULES_SUPPORT
  29291     uint32 smf, osmf;
  29292 #endif /* BCM_HERCULES_SUPPORT */
  29293 #ifdef BCM_HERCULES1_SUPPORT
  29294     uint32 mask;
  29295 #endif /* BCM_HERCULES1_SUPPORT */
  29296 #ifdef BCM_HERCULES15_SUPPORT
  29297     mem_ing_srcmodblk_entry_t srcmod;
  29298     int blk;
  29299 #endif /* BCM_HERCULES15_SUPPORT */
  29300 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  29301     int rv=BCM_E_NONE;
  29302 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */
  29303 
  29304     /* Make sure port module is initialized. */
  29305     PORT_INIT(unit);
  29306 
  29307     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29308 
  29309 #ifdef BCM_TRX_SUPPORT
  29310     if (SOC_IS_TRX(unit)) {
  29311         src_modid_ingress_block_entry_t srcmoding;
  29312         src_modid_block_entry_t srcmod;
  29313         int modid_cnt, hg_port, idx, i;
  29314         bcm_pbmp_t pbmp;
  29315         _bcm_port_egr_dest_t    egr_dst;
  29316 
  29317         egr_dst.in_port = port;
  29318         egr_dst.in_modid = modid;
  29319         BCM_IF_ERROR_RETURN(
  29320             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29321 
  29322         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29323             return BCM_E_PORT;
  29324         }
  29325 
  29326         if (!IS_E_PORT(unit, egr_dst.out_max_port) &&
  29327             !IS_ST_PORT(unit, egr_dst.out_max_port)) {
  29328             return BCM_E_PORT;
  29329         }
  29330 
  29331 
  29332         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  29333             SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  29334             SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  29335             soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm);
  29336             for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  29337                 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i,
  29338                                                    &srcmoding);
  29339                 if (rv >= 0) {
  29340                     soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  29341                                            &srcmoding, PORT_BITMAPf, &pbmp);
  29342                     if (enable) {
  29343                         BCM_PBMP_PORT_REMOVE(pbmp, egr_dst.out_max_port);
  29344                     } else {
  29345                         BCM_PBMP_PORT_ADD(pbmp, egr_dst.out_max_port);
  29346                     }
  29347                     soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm,
  29348                                            &srcmoding, PORT_BITMAPf, &pbmp);
  29349                     rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i,
  29350                                                         &srcmoding);
  29351                 }
  29352                 if (rv < 0) {
  29353                     soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  29354                     return rv;
  29355                 }
  29356             }
  29357             soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  29358         } else {
  29359             modid_cnt = SOC_MODID_MAX(unit) + 1;
  29360 
  29361             /* process to retrieve hg_port index from port */
  29362             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  29363                 SOC_IS_GREYHOUND2(unit)) {
  29364                 hg_port = port;
  29365             } else {
  29366                 SOC_IF_ERROR_RETURN(
  29367                     soc_xgs3_port_num_to_higig_port_num(unit, port, &hg_port));
  29368             }
  29369 
  29370             soc_mem_lock(unit, SRC_MODID_BLOCKm);
  29371             for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  29372                 idx = hg_port * modid_cnt + i;
  29373                 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  29374                 if (rv >= 0) {
  29375                     if (!enable) {
  29376                         SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  29377                     } else {
  29378                         SOC_PBMP_CLEAR(pbmp);
  29379                     }
  29380                     soc_mem_pbmp_field_set(unit, SRC_MODID_BLOCKm, &srcmod,
  29381                                            PORT_BLOCK_MASK_BITMAPf,&pbmp);
  29382                     rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, &srcmod);
  29383                 }
  29384                 if (rv < 0) {
  29385                     soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  29386                     return rv;
  29387                 }
  29388             }
  29389             soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  29390         }
  29391         return rv;
  29392     }
  29393 #endif  /* BCM_TRX_SUPPORT */
  29394 
  29395 #ifdef BCM_FIREBOLT_SUPPORT
  29396     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  29397         src_modid_block_entry_t src_mod;
  29398         int modid_cnt, mod_idx, p_idx, idx, val;
  29399         _bcm_port_egr_dest_t    egr_dst;
  29400 
  29401         egr_dst.in_port = port;
  29402         egr_dst.in_modid = modid;
  29403         BCM_IF_ERROR_RETURN(
  29404             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29405 
  29406         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29407             return BCM_E_PORT;
  29408         }
  29409 
  29410         modid_cnt = SOC_MODID_MAX(unit) + 1;
  29411         p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  29412         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  29413         for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) {
  29414              sal_memset(&src_mod, 0, sizeof(src_mod));
  29415              if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  29416                  idx = (p_idx - 1) * modid_cnt + mod_idx;
  29417              } else {
  29418                  idx = (p_idx * modid_cnt) + mod_idx;
  29419              }
  29420              rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &src_mod);
  29421              if (rv >= 0) {
  29422                  soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  29423                                                   CPU_PORT_BLOCK_MASKf,
  29424                                                   (enable) ? 0 : 1);
  29425                  if (SOC_IS_FB_FX_HX(unit)) {
  29426                      soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  29427                                                       GE_PORT_BLOCK_MASKf,
  29428                                                       (enable) ? 0 : 1);
  29429                  }
  29430 
  29431                  val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm,
  29432                                              HIGIG_XGE_PORT_BLOCK_MASKf)) - 1;
  29433 
  29434                  soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  29435                                                   HIGIG_XGE_PORT_BLOCK_MASKf,
  29436                                                   (enable) ? 0 : val);
  29437 #if defined(BCM_RAPTOR_SUPPORT)
  29438                  if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  29439                                          PORT_0_5_BLOCK_MASKf)) {
  29440 
  29441                      val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm,
  29442                                                  PORT_0_5_BLOCK_MASKf)) - 1;
  29443 
  29444                      soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  29445                                                       PORT_0_5_BLOCK_MASKf,
  29446                                                       (enable) ? 0 : val);
  29447 
  29448                  }
  29449 #endif /* BCM_RAPTOR_SUPPORT */
  29450                  rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL,
  29451                                              idx, &src_mod);
  29452              }
  29453         }
  29454         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  29455 
  29456         return rv;
  29457     }
  29458 #endif /* BCM_FIREBOLT_SUPPORT */
  29459 
  29460     if (!IS_PORT(unit, port)) {
  29461         return BCM_E_PORT;
  29462     }
  29463 
  29464     if (!soc_feature(unit, soc_feature_srcmod_filter)) {
  29465         if (enable) {
  29466             return BCM_E_NONE;
  29467         } else {
  29468             return BCM_E_UNAVAIL;
  29469         }
  29470     }
  29471 
  29472     max_mod = 128;
  29473     if (modid >= max_mod) {
  29474         return BCM_E_PARAM;
  29475     }
  29476 
  29477 #ifdef BCM_HERCULES15_SUPPORT
  29478     if (SOC_IS_HERCULES15(unit)) {
  29479         blk = SOC_PORT_BLOCK(unit, port);
  29480         soc_mem_lock(unit, MEM_ING_SRCMODBLKm);
  29481         if (modid < 0) {
  29482             for (modid = 0; modid < max_mod; modid++) {
  29483                 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29484                 if (rv < 0) {
  29485                     break;
  29486                 }
  29487                 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf,
  29488                                                  &osmf);
  29489                 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0;
  29490                 if (osmf != smf) {
  29491                     soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf,
  29492                                                      &smf);
  29493                     rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29494                     if (rv < 0) {
  29495                         break;
  29496                     }
  29497                 }
  29498             }
  29499         } else {
  29500             rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29501             if (rv >= 0) {
  29502                 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf,
  29503                                                  &osmf);
  29504                 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0;
  29505                 if (osmf != smf) {
  29506                     soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf,
  29507                                                      &smf);
  29508                     rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29509                 }
  29510             }
  29511         }
  29512         soc_mem_unlock(unit, MEM_ING_SRCMODBLKm);
  29513     }
  29514 #endif /* BCM_HERCULES15_SUPPORT */
  29515 
  29516     return BCM_E_NONE;
  29517 }
  29518 
  29519 /*
  29520  * Function:
  29521  *    bcm_port_modid_enable_get
  29522  * Purpose:
  29523  *    Return enable/block state for a specific module on a port.
  29524  * Parameters:
  29525  *    unit - StrataSwitch PCI device unit number (driver internal).
  29526  *    port - StrataSwitch port number.
  29527  *    modid - Which source module id to enable/disable
  29528  *    enable - (OUT) TRUE/FALSE Enable/disable forwarding packets from
  29529  *             source module arriving on port.
  29530  * Returns:
  29531  *    BCM_E_XXX
  29532  */
  29533 int
  29534 bcm_esw_port_modid_enable_get(int unit, bcm_port_t port, int modid, int *enable)
  29535 {
  29536     int max_mod;
  29537 #ifdef BCM_HERCULES_SUPPORT
  29538     uint32 smf;
  29539 #endif /* BCM_HERCULES_SUPPORT */
  29540 #ifdef BCM_HERCULES1_SUPPORT
  29541     uint32 mask;
  29542 #endif /* BCM_HERCULES1_SUPPORT */
  29543 #ifdef BCM_HERCULES15_SUPPORT
  29544     mem_ing_srcmodblk_entry_t srcmod;
  29545     int blk, rv;
  29546 #endif /* BCM_HERCULES15_SUPPORT */
  29547 
  29548     /* Make sure port module is initialized. */
  29549     PORT_INIT(unit);
  29550 
  29551     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29552 
  29553 #ifdef BCM_TRX_SUPPORT
  29554     if (SOC_IS_TRX(unit)) {
  29555         src_modid_ingress_block_entry_t srcmoding;
  29556         src_modid_block_entry_t srcmod;
  29557         int hg_port, idx;
  29558         bcm_pbmp_t pbmp;
  29559         _bcm_port_egr_dest_t    egr_dst;
  29560 
  29561         egr_dst.in_port = port;
  29562         egr_dst.in_modid = modid;
  29563         BCM_IF_ERROR_RETURN(
  29564             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29565 
  29566         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29567             return BCM_E_PORT;
  29568         }
  29569         if (egr_dst.out_max_modid != egr_dst.out_min_modid) {
  29570             return BCM_E_PARAM;
  29571         }
  29572 
  29573         if (!IS_E_PORT(unit, egr_dst.out_max_port) &&
  29574             !IS_ST_PORT(unit, egr_dst.out_max_port)) {
  29575             return BCM_E_PORT;
  29576         }
  29577 
  29578         SOC_PBMP_CLEAR(pbmp);
  29579         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  29580             SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  29581             SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  29582             SOC_IF_ERROR_RETURN(
  29583                 READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY,
  29584                                               egr_dst.out_min_modid, &srcmoding));
  29585             soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  29586                                    &srcmoding, PORT_BITMAPf, &pbmp);
  29587         } else {
  29588             /* process to retrieve hg_port index from port */
  29589             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  29590                 SOC_IS_GREYHOUND2(unit)) {
  29591                 hg_port = egr_dst.out_min_port;
  29592             } else {
  29593                 SOC_IF_ERROR_RETURN(soc_xgs3_port_num_to_higig_port_num(unit,
  29594                         egr_dst.out_min_port, &hg_port));
  29595             }
  29596 
  29597             idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  29598             SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx,
  29599                                                       &srcmod));
  29600             soc_mem_pbmp_field_get(unit, SRC_MODID_BLOCKm, &srcmod,
  29601                                    PORT_BLOCK_MASK_BITMAPf, &pbmp);
  29602         }
  29603 
  29604         *enable = !SOC_PBMP_MEMBER(pbmp, egr_dst.out_max_port);
  29605 
  29606         return BCM_E_NONE;
  29607     }
  29608 #endif /* BCM_TRIUMPH_SUPPORT */
  29609 
  29610 #ifdef BCM_FIREBOLT_SUPPORT
  29611     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  29612         uint32 config;
  29613         src_modid_block_entry_t src_mod;
  29614         int gable, modid_cnt, p_idx, idx;
  29615         _bcm_port_egr_dest_t    egr_dst;
  29616 
  29617         egr_dst.in_port = port;
  29618         egr_dst.in_modid = modid;
  29619         BCM_IF_ERROR_RETURN(
  29620             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  29621 
  29622         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  29623             return BCM_E_PORT;
  29624         }
  29625         if (egr_dst.out_max_modid != egr_dst.out_min_modid) {
  29626             return BCM_E_PARAM;
  29627         }
  29628 
  29629         SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, &config));
  29630         gable = !soc_reg_field_get(unit, ING_CONFIGr, config,
  29631                                    FB_A0_COMPATIBLEf);
  29632         if (gable) {
  29633             modid_cnt = SOC_MODID_MAX(unit) + 1;
  29634             p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  29635             if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  29636                 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid;
  29637             } else {
  29638                 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid;
  29639             }
  29640             SOC_IF_ERROR_RETURN
  29641                 (READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY,
  29642                                        idx, &src_mod));
  29643             *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  29644                                                         CPU_PORT_BLOCK_MASKf) |
  29645                        soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  29646                                                         HIGIG_XGE_PORT_BLOCK_MASKf)
  29647                                                         ) ? 0 : 1;
  29648             if (SOC_IS_FB_FX_HX(unit)) {
  29649                 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  29650                                                             GE_PORT_BLOCK_MASKf)
  29651                                                             ) ? 0 : 1;
  29652             }
  29653 
  29654 #if defined(BCM_RAPTOR_SUPPORT)
  29655             if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  29656                                     PORT_0_5_BLOCK_MASKf)) {
  29657                 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  29658                                                  PORT_0_5_BLOCK_MASKf)
  29659                                                  ) ? 0 : 1;
  29660             }
  29661 #endif /* BCM_RAPTOR_SUPPORT */
  29662 
  29663         } else {
  29664             *enable = gable;
  29665         }
  29666 
  29667         return BCM_E_NONE;
  29668     }
  29669 #endif /* BCM_FIREBOLT_SUPPORT */
  29670 
  29671     if (!IS_PORT(unit, port)) {
  29672         return BCM_E_PORT;
  29673     }
  29674 
  29675     if (!soc_feature(unit, soc_feature_srcmod_filter)) {
  29676         *enable = TRUE;
  29677         return BCM_E_NONE;
  29678     }
  29679 
  29680     max_mod = 128;
  29681     if (!((modid >= 0) && (modid < max_mod))) {
  29682         return BCM_E_PARAM;
  29683     }
  29684 
  29685 #ifdef BCM_HERCULES15_SUPPORT
  29686     if (SOC_IS_HERCULES15(unit)) {
  29687         blk = SOC_PORT_BLOCK(unit, port);
  29688         rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  29689         if (rv >= 0) {
  29690             soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, &smf);
  29691             *enable = (smf & SOC_PBMP_WORD_GET(PBMP_ALL(unit),0)) ? 1 : 0;
  29692         }
  29693     }
  29694 #endif /* BCM_HERCULES15_SUPPORT */
  29695 
  29696     return BCM_E_NONE;
  29697 }
  29698 
  29699 
  29700 /*
  29701  * Function:
  29702  *      _bcm_port_flood_block_op
  29703  * Purpose:
  29704  *      Set or get port membership in one of the egress block registers
  29705  * Parameters:
  29706  *      unit
  29707  *      set_op          - TRUE for set, FALSE for get
  29708  *      ingress_port    - ingress port on which the egress blocking
  29709  *                        will be enabled
  29710  *      egress_port     - port for which egress will be blocked
  29711  *      mode            - BCM_PORT_FLOOD_BLOCK_XXX
  29712  *      enable          - Whether blocking should be enabled or disabled
  29713  *                        This is also BCM_PORT_FLOOD_BLOCK_XXX
  29714  * Returns:
  29715  *      BCM_E_UNAVAIL   - This chip does not support this feature
  29716  *      BCM_E_NONE
  29717  */
  29718 STATIC int
  29719 _bcm_port_flood_block_op(int unit, int set_op,
  29720                          bcm_port_t ingress_port, bcm_port_t egress_port,
  29721                          uint32 mode, uint32 *enable)
  29722 {
  29723     soc_reg_t reg, mask_reg[2], mask_hi_reg[2];
  29724     soc_mem_t mem;
  29725     soc_field_t field;
  29726     uint64 rval;
  29727     uint32 fval;
  29728     uint32 entry[SOC_MAX_MEM_WORDS];
  29729     pbmp_t pbmp;
  29730     int index;
  29731     int cpu_hg_index = 0;
  29732 
  29733     mask_reg[0] = mask_reg[1] = INVALIDr;
  29734     mask_hi_reg[0] = mask_hi_reg[1] = INVALIDr;
  29735     mem = INVALIDm;
  29736     field = INVALIDf;
  29737 
  29738     switch (mode) {
  29739     case BCM_PORT_FLOOD_BLOCK_BCAST:
  29740         if (SOC_MEM_IS_VALID(unit, BCAST_BLOCK_MASKm)) {
  29741             mem = BCAST_BLOCK_MASKm;
  29742             field = BLK_BITMAPf;
  29743         /* coverity[result_independent_of_operands] */
  29744         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_64r)) {
  29745             mask_reg[0] = BCAST_BLOCK_MASK_64r;
  29746             mask_reg[1] = IBCAST_BLOCK_MASK_64r;
  29747         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_LO_64r)) {
  29748             mask_reg[0] = BCAST_BLOCK_MASK_LO_64r;
  29749             mask_reg[1] = IBCAST_BLOCK_MASK_LO_64r;
  29750             mask_hi_reg[0] = BCAST_BLOCK_MASK_HI_64r;
  29751             mask_hi_reg[1] = IBCAST_BLOCK_MASK_HI_64r;
  29752         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASKr)) {
  29753             mask_reg[0] = BCAST_BLOCK_MASKr;
  29754             mask_reg[1] = IBCAST_BLOCK_MASKr;
  29755         } else {
  29756             return BCM_E_UNAVAIL;
  29757         }
  29758         break;
  29759     case BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST:
  29760         if (SOC_MEM_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKm)) {
  29761             mem = UNKNOWN_UCAST_BLOCK_MASKm;
  29762             field = BLK_BITMAPf;
  29763         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_64r)) {
  29764             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_64r;
  29765             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_64r;
  29766         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_LO_64r)) {
  29767             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_LO_64r;
  29768             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_LO_64r;
  29769             mask_hi_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_HI_64r;
  29770             mask_hi_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_HI_64r;
  29771         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKr)) {
  29772             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASKr;
  29773             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASKr;
  29774         } else {
  29775             return BCM_E_UNAVAIL;
  29776         }
  29777         break;
  29778     case BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST:
  29779         if (SOC_MEM_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKm)) {
  29780             mem = UNKNOWN_MCAST_BLOCK_MASKm;
  29781             field = BLK_BITMAPf;
  29782         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_64r)) {
  29783             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_64r;
  29784             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_64r;
  29785         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_LO_64r)) {
  29786             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_LO_64r;
  29787             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_LO_64r;
  29788             mask_hi_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_HI_64r;
  29789             mask_hi_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_HI_64r;
  29790         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKr)) {
  29791             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASKr;
  29792             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASKr;
  29793         } else {
  29794             return BCM_E_UNAVAIL;
  29795         }
  29796         break;
  29797     case BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST:
  29798         if (SOC_MEM_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKm)) {
  29799             mem = KNOWN_MCAST_BLOCK_MASKm;
  29800             field = BLK_BITMAPf;
  29801         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_64r)) {
  29802             mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_64r;
  29803             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_64r;
  29804         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_LOr)) {
  29805             mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_LOr;
  29806             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_LOr;
  29807             mask_hi_reg[0] = KNOWN_MCAST_BLOCK_MASK_HIr;
  29808             mask_hi_reg[1] = IKNOWN_MCAST_BLOCK_MASK_HIr;
  29809         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKr)) {
  29810             mask_reg[0] = KNOWN_MCAST_BLOCK_MASKr;
  29811             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASKr;
  29812         } else {
  29813             return BCM_E_UNAVAIL;
  29814         }
  29815         break;
  29816     case BCM_PORT_FLOOD_BLOCK_ALL:
  29817         if (SOC_MEM_IS_VALID(unit, ING_EGRMSKBMAPm)) {
  29818             mem = ING_EGRMSKBMAPm;
  29819             field = BITMAPf;
  29820         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_64r)) {
  29821             mask_reg[0] = ING_EGRMSKBMAP_64r;
  29822             mask_reg[1] = IING_EGRMSKBMAP_64r;
  29823         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_LOr)) {
  29824             mask_reg[0] = ING_EGRMSKBMAP_LOr;
  29825             mask_reg[1] = IING_EGRMSKBMAP_LOr;
  29826             mask_hi_reg[0] = ING_EGRMSKBMAP_HIr;
  29827             mask_hi_reg[1] = IING_EGRMSKBMAP_HIr;
  29828         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAPr)) {
  29829             mask_reg[0] = ING_EGRMSKBMAPr;
  29830             mask_reg[1] = IING_EGRMSKBMAPr;
  29831         } else {
  29832             return BCM_E_UNAVAIL;
  29833         }
  29834         break;
  29835     default:
  29836         return BCM_E_INTERNAL;
  29837     }
  29838 
  29839     if (mem != INVALIDm) {
  29840         BCM_IF_ERROR_RETURN
  29841             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, ingress_port, entry));
  29842         soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp);
  29843         if (!set_op) {
  29844             *enable = SOC_PBMP_WORD_GET(pbmp, egress_port / 32) &
  29845                 (1 << (egress_port & 0x1f)) ? mode : 0;
  29846             return BCM_E_NONE;
  29847         }
  29848         if (*enable & mode) {
  29849             SOC_PBMP_PORT_ADD(pbmp, egress_port);
  29850         } else {
  29851             SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  29852         }
  29853         soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp);
  29854         BCM_IF_ERROR_RETURN
  29855             (soc_mem_write(unit, mem, MEM_BLOCK_ANY, ingress_port, entry));
  29856 
  29857         cpu_hg_index = SOC_IS_KATANA2(unit) ?
  29858                        SOC_INFO(unit).cpu_hg_pp_port_index :
  29859                        SOC_INFO(unit).cpu_hg_index;
  29860         if (IS_CPU_PORT(unit, ingress_port) && cpu_hg_index != -1) {
  29861             BCM_IF_ERROR_RETURN
  29862                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry));
  29863             soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp);
  29864             if (*enable & mode) {
  29865                 SOC_PBMP_PORT_ADD(pbmp, egress_port);
  29866             } else {
  29867                 SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  29868             }
  29869             soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp);
  29870             BCM_IF_ERROR_RETURN
  29871                 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry));
  29872         }
  29873     } else {
  29874         if (!IS_CPU_PORT(unit, ingress_port)) {
  29875             if (IS_ST_PORT(unit, ingress_port)) {
  29876                 mask_reg[0] = INVALIDr;
  29877                 mask_hi_reg[0] = INVALIDr;
  29878             } else {
  29879                 mask_reg[1] = INVALIDr;
  29880                 mask_hi_reg[1] = INVALIDr;
  29881             }
  29882         }
  29883 
  29884         for (index = 0; index < 2; index++) {
  29885             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  29886                 uint64      fval64, rval64;
  29887                 uint32      t_port;
  29888                 pbmp_t      curr_pbmp;
  29889 
  29890                 /*
  29891                 *  pbmp reg split to multiple reg due to high port count
  29892                 *  example :
  29893                 *   - BCAST_BLOCK_MASK_64r was split to
  29894                 *      {BCAST_BLOCK_MASK_LO_64r + BCAST_BLOCK_MASK_HI_64r}
  29895                 *   - ING_EGRMSKBMAP_64r was split to
  29896                 *      {ING_EGRMSKBMAP_LOr + ING_EGRMSKBMAP_HIr}
  29897                 */
  29898                 BCM_PBMP_CLEAR(curr_pbmp);
  29899                 COMPILER_64_ZERO(fval64);
  29900                 COMPILER_64_ZERO(rval64);
  29901 
  29902                 if (egress_port < 64) {
  29903                     reg = mask_reg[index];
  29904                     t_port = egress_port;
  29905                 } else {
  29906                     reg = mask_hi_reg[index];
  29907                     t_port = egress_port - 64;
  29908                 }
  29909                 field = BLK_BITMAPf;
  29910 
  29911                 if (SOC_REG_IS_VALID(unit, reg)) {
  29912                     BCM_IF_ERROR_RETURN(soc_reg_get(unit,
  29913                             reg, ingress_port, 0, &rval64));
  29914 
  29915                     fval64 = soc_reg64_field_get(unit, reg, rval64, field);
  29916                     SOC_PBMP_WORD_SET(curr_pbmp, 0, COMPILER_64_LO(fval64));
  29917                     SOC_PBMP_WORD_SET(curr_pbmp, 1, COMPILER_64_HI(fval64));
  29918 
  29919                     if (!set_op) {
  29920                         /* for GET */
  29921                         *enable = SOC_PBMP_MEMBER(curr_pbmp, t_port) ? mode : 0;
  29922                     } else {
  29923                         /* for SET */
  29924                         if (*enable & mode) {
  29925                             SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  29926                         } else {
  29927                             SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  29928                         }
  29929                         COMPILER_64_SET(fval64,
  29930                                 SOC_PBMP_WORD_GET(curr_pbmp, 1),
  29931                                 SOC_PBMP_WORD_GET(curr_pbmp, 0));
  29932                         soc_reg64_field_set(unit, reg,
  29933                                 &rval64, field, fval64);
  29934                         BCM_IF_ERROR_RETURN(soc_reg_set(unit,
  29935                                 reg, ingress_port, 0, rval64));
  29936                     }
  29937                 }
  29938             } else {
  29939                 reg = mask_reg[index];
  29940                 if (reg == INVALIDr) {
  29941                     continue;
  29942                 }
  29943                 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, ingress_port, 0, &rval));
  29944                 if (SOC_REG_IS_64(unit, reg)) {
  29945                     if (egress_port < 32) {
  29946                         if (soc_reg_field_valid(unit, reg, BLK_BITMAP_LOf)) {
  29947                             field = BLK_BITMAP_LOf;
  29948                         } else {
  29949                             field = BLK_BITMAP_0f;
  29950                         }
  29951                     } else {
  29952                         if (soc_reg_field_valid(unit, reg, BLK_BITMAP_HIf)) {
  29953                             field = BLK_BITMAP_HIf;
  29954                         } else {
  29955                             field = BLK_BITMAP_1f;
  29956                         }
  29957                     }
  29958                 } else {
  29959                     field = BLK_BITMAPf;
  29960                 }
  29961                 fval = soc_reg64_field32_get(unit, reg, rval, field);
  29962                 if (!set_op) {
  29963                     *enable = fval & (1 << (egress_port & 0x1f)) ? mode : 0;
  29964                     return BCM_E_NONE;
  29965                 }
  29966                 if (*enable & mode) {
  29967                     fval |= 1 << (egress_port & 0x1f);
  29968                 } else {
  29969                     fval &= ~(1 << (egress_port & 0x1f));
  29970                 }
  29971                 soc_reg64_field32_set(unit, reg, &rval, field, fval);
  29972                 BCM_IF_ERROR_RETURN(soc_reg_set(unit, reg, ingress_port, 0, rval));
  29973             }
  29974         }
  29975     }
  29976 
  29977     return BCM_E_NONE;
  29978 }
  29979 
  29980 #if defined(BCM_RAPTOR_SUPPORT)
  29981 /*
  29982  * Function:
  29983  *      _bcm_port_flood_block_hi_set
  29984  * Purpose:
  29985  *      Enable/disable port membership in one of the egress block registers
  29986  * Parameters:
  29987  *      unit
  29988  *      ingress_port    - ingress port on which the egress blocking
  29989  *                        will be enabled
  29990  *      egress_port     - port for which egress will be blocked
  29991  *      reg             - egress block register.
  29992  *      enable          - Whether blocking should be enabled or disabled
  29993  * Returns:
  29994  *      BCM_E_UNAVAIL   - This chip does not support this feature
  29995  *      BCM_E_NONE
  29996  * Notes:
  29997  *      'reg' must be one of BCAST_BLOCK_MASKr,
  29998  *      UNKNOWN_UCAST_BLOCK_MASKr, UNKNOWN_MCAST_BLOCK_MASKr, or
  29999  *      their Stack port variants.
  30000  *
  30001  *      This function is a helper for bcm_port_flood_block_set()
  30002  */
  30003 
  30004 STATIC int
  30005 _bcm_port_flood_block_hi_set(int unit,
  30006                               bcm_port_t ingress_port, bcm_port_t egress_port,
  30007                               soc_reg_t reg, uint32 enable)
  30008 {
  30009     uint32 rval;
  30010     pbmp_t pbmp;
  30011     uint32 pbmp32;
  30012     uint32 bitmap32, obitmap32;
  30013 
  30014     if (!soc_feature(unit, soc_feature_register_hi)) {
  30015         return BCM_E_UNAVAIL;
  30016     }
  30017 
  30018     SOC_PBMP_PORT_SET(pbmp, egress_port);
  30019     pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  30020 
  30021     if (!pbmp32) {
  30022         return BCM_E_NONE;
  30023     }
  30024 
  30025     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval));
  30026 
  30027     obitmap32 = bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf);
  30028     if (enable) {
  30029         bitmap32 |= pbmp32;
  30030     } else {
  30031         bitmap32 &= ~pbmp32;
  30032     }
  30033 
  30034     if (obitmap32 != bitmap32) {
  30035         soc_reg_field_set(unit, reg, &rval, BLK_BITMAPf, bitmap32);
  30036         return soc_reg32_set(unit, reg, ingress_port, 0, rval);
  30037     }
  30038 
  30039     return BCM_E_NONE;
  30040 }
  30041 
  30042 /*
  30043  * Function:
  30044  *      _bcm_port_flood_block_hi_get
  30045  * Purpose:
  30046  *      Retrieve the current state egress block state on a port
  30047  * Parameters:
  30048  *      unit
  30049  *      ingress_port    - ingress_port for which the state will be retreived
  30050  *      egress_port     - port for which the egress blocking state
  30051  *                        on ingress_port is requested
  30052  *      reg             - block mask register
  30053  *      enable          - (OUT) receives the block state
  30054  * Returns:
  30055  *      BCM_E_UNAVAIL   - Feature unavailable on this chip
  30056  *      BCM_E_NONE
  30057  * Notes:
  30058  *      See _bcm_port_flood_block_hi_set()
  30059  *      This is a helper function for bcm_port_flood_block_get()
  30060  */
  30061 
  30062 STATIC int
  30063 _bcm_port_flood_block_hi_get(int unit,
  30064                           bcm_port_t ingress_port, bcm_port_t egress_port,
  30065                           soc_reg_t reg, uint32 *enable)
  30066 {
  30067     uint32 rval;
  30068     pbmp_t pbmp;
  30069     uint32 pbmp32;
  30070     uint32 bitmap32;
  30071 
  30072     if (!soc_feature(unit, soc_feature_register_hi)) {
  30073         return BCM_E_UNAVAIL;
  30074     }
  30075 
  30076     SOC_PBMP_PORT_SET(pbmp, egress_port);
  30077     pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  30078     if (!pbmp32) {
  30079         *enable = 0;
  30080         return BCM_E_NONE;
  30081     }
  30082 
  30083     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval));
  30084 
  30085     bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf);
  30086     *enable = (pbmp32 & bitmap32) ? 1 : 0;
  30087 
  30088     return BCM_E_NONE;
  30089 }
  30090 #endif /* BCM_RAPTOR_SUPPORT */
  30091 
  30092 /*
  30093  * Function:
  30094  *      bcm_port_flood_block_set
  30095  * Purpose:
  30096  *      Set selective per-port blocking of flooded VLAN traffic
  30097  * Parameters:
  30098  *      unit            - unit number
  30099  *      ingress_port    - Port traffic is ingressing
  30100  *      egress_port     - Port for which the traffic should be blocked.
  30101  *      flags           - Specifies the type of traffic to block
  30102  * Returns:
  30103  *      BCM_E_UNAVAIL   - Functionality not available
  30104  *      BCM_E_NONE
  30105  *
  30106  * NOTE:  For fabrics, this changes egrmskbmap; as a result, all traffic
  30107  * will be blocked (or enabled) to the given egress port, including
  30108  * unicast traffic.
  30109  */
  30110 
  30111 int
  30112 bcm_esw_port_flood_block_set(int unit,
  30113                          bcm_port_t ingress_port, bcm_port_t egress_port,
  30114                          uint32 flags)
  30115 {
  30116     /* Make sure port module is initialized. */
  30117     PORT_INIT(unit);
  30118 
  30119     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port,
  30120                                                      &ingress_port));
  30121     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port,
  30122                                                      &egress_port));
  30123 
  30124 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  30125     /* See note above */
  30126     if (SOC_IS_XGS12_FABRIC(unit)) {
  30127         uint32  ports, oports;
  30128         pbmp_t  pbmp;
  30129 
  30130         if (!IS_HG_PORT(unit, ingress_port)) {
  30131             return BCM_E_PORT;
  30132         }
  30133 
  30134         SOC_IF_ERROR_RETURN
  30135             (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports));
  30136         oports = ports;
  30137         SOC_PBMP_CLEAR(pbmp);
  30138         SOC_PBMP_WORD_SET(pbmp, 0, ports);
  30139         if (flags) {
  30140             SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  30141         } else {
  30142             SOC_PBMP_PORT_ADD(pbmp, egress_port);
  30143         }
  30144         ports = SOC_PBMP_WORD_GET(pbmp, 0);
  30145         if (ports != oports) {
  30146             SOC_IF_ERROR_RETURN
  30147                 (WRITE_ING_EGRMSKBMAPr(unit, ingress_port, ports));
  30148         }
  30149         return BCM_E_NONE;
  30150     }
  30151 #endif /* BCM_XGS12_FABRIC_SUPPORT */
  30152 
  30153 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  30154         || defined(BCM_BRADLEY_SUPPORT)
  30155     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)||
  30156         SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  30157         BCM_IF_ERROR_RETURN
  30158             (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  30159                                       BCM_PORT_FLOOD_BLOCK_ALL, &flags));
  30160     }
  30161 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || \
  30162           BCM_BRADLEY_SUPPORT */
  30163 
  30164     BCM_IF_ERROR_RETURN
  30165         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  30166                                   BCM_PORT_FLOOD_BLOCK_BCAST, &flags));
  30167 
  30168     BCM_IF_ERROR_RETURN
  30169         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  30170                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, &flags));
  30171 
  30172     /*
  30173      * For some devices like RAVEN , which do not have support for
  30174      * blocking KNOWN_MCAST , continue processing.
  30175      */
  30176     BCM_IF_ERROR_NOT_UNAVAIL_RETURN
  30177         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  30178                                   BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, &flags));
  30179 
  30180     BCM_IF_ERROR_RETURN
  30181         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  30182                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, &flags));
  30183 
  30184     /*
  30185      * Handle the devices with > 32 ports that use _HI convention
  30186      */
  30187 #if defined(BCM_RAPTOR_SUPPORT)
  30188        if (soc_feature(unit, soc_feature_register_hi)){
  30189            soc_reg_t reg;
  30190            uint32 enable;
  30191             reg = IS_ST_PORT(unit, ingress_port) ?
  30192                 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr;
  30193             enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST;
  30194             BCM_IF_ERROR_RETURN
  30195                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  30196                                               reg, enable));
  30197 
  30198             reg = IS_ST_PORT(unit, ingress_port) ?
  30199                 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr;
  30200             enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST;
  30201             BCM_IF_ERROR_RETURN
  30202                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  30203                                               reg, enable));
  30204 
  30205             reg = IS_ST_PORT(unit, ingress_port) ?
  30206                 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr;
  30207             enable = flags & BCM_PORT_FLOOD_BLOCK_BCAST;
  30208             BCM_IF_ERROR_RETURN
  30209                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  30210                                               reg, enable));
  30211        }
  30212 #endif /* BCM_RAPTOR_SUPPORT */
  30213 
  30214     return BCM_E_NONE;
  30215 }
  30216 
  30217 /*
  30218  * Function:
  30219  *      bcm_port_flood_block_get
  30220  * Purpose:
  30221  *      Get the current per-port flood block settings
  30222  * Parameters:
  30223  *      unit            - unit number
  30224  *      ingress_port    - Port traffic is ingressing
  30225  *      egress_port     - Port for which the traffic would be blocked
  30226  *      flags           - (OUT) Returns the current settings
  30227  * Returns:
  30228  *      BCM_E_UNAVAIL   - Functionality not available
  30229  *      BCM_E_NONE
  30230  */
  30231 
  30232 int
  30233 bcm_esw_port_flood_block_get(int unit,
  30234                          bcm_port_t ingress_port, bcm_port_t egress_port,
  30235                          uint32 *flags)
  30236 {
  30237     uint32 enable;
  30238 
  30239     /* Make sure port module is initialized. */
  30240     PORT_INIT(unit);
  30241 
  30242     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port,
  30243                                                      &ingress_port));
  30244     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port,
  30245                                                      &egress_port));
  30246 
  30247     *flags = 0;
  30248 
  30249 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  30250     if (SOC_IS_XGS12_FABRIC(unit)) {
  30251         uint32  ports;
  30252         pbmp_t  pbmp;
  30253 
  30254         if (!IS_HG_PORT(unit, ingress_port)) {
  30255             return BCM_E_PORT;
  30256         }
  30257 
  30258         SOC_IF_ERROR_RETURN
  30259             (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports));
  30260         SOC_PBMP_CLEAR(pbmp);
  30261         SOC_PBMP_WORD_SET(pbmp, 0, ports);
  30262         if (!SOC_PBMP_MEMBER(pbmp, egress_port)) {
  30263             *flags = -1;        
  30264         }
  30265         return BCM_E_NONE;
  30266     }
  30267 #endif
  30268 
  30269 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  30270         || defined(BCM_BRADLEY_SUPPORT)
  30271     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)||
  30272         SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  30273         BCM_IF_ERROR_RETURN
  30274             (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  30275                                       BCM_PORT_FLOOD_BLOCK_ALL, &enable));
  30276         *flags |= enable;
  30277     }
  30278 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_BRADLEY_SUPPORT */
  30279 
  30280     BCM_IF_ERROR_RETURN
  30281         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  30282                                   BCM_PORT_FLOOD_BLOCK_BCAST, &enable));
  30283     *flags |= enable;
  30284 
  30285     BCM_IF_ERROR_RETURN
  30286         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  30287                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST,
  30288                                   &enable));
  30289     *flags |= enable;
  30290 
  30291     /*
  30292      * For some devices like RAVEN , which do not have support for
  30293      * blocking KNOWN_MCAST , continue processing.
  30294      */
  30295     BCM_IF_ERROR_NOT_UNAVAIL_RETURN
  30296         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  30297                                   BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST,
  30298                                   &enable));
  30299     *flags |= enable;
  30300 
  30301     BCM_IF_ERROR_RETURN
  30302         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  30303                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST,
  30304                                   &enable));
  30305     *flags |= enable;
  30306 
  30307 #if defined(BCM_RAPTOR_SUPPORT)
  30308     if (soc_feature(unit, soc_feature_register_hi)){
  30309         soc_reg_t reg;
  30310         reg = IS_ST_PORT(unit, ingress_port) ?
  30311             IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr;
  30312         BCM_IF_ERROR_RETURN
  30313             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  30314                                        reg, &enable));
  30315         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_BCAST : 0;
  30316 
  30317         reg = IS_ST_PORT(unit, ingress_port) ?
  30318             IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr;
  30319         BCM_IF_ERROR_RETURN
  30320             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  30321                                        reg, &enable));
  30322         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST : 0;
  30323 
  30324         reg = IS_ST_PORT(unit, ingress_port) ?
  30325             IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr;
  30326         BCM_IF_ERROR_RETURN
  30327             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  30328                                        reg, &enable));
  30329         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST : 0;
  30330     }
  30331 #endif /* BCM_RAPTOR_SUPPORT */
  30332 
  30333     return BCM_E_NONE;
  30334 }
  30335 
  30336 /*
  30337  * Per-port leaky bucket ingress and egress rate limiting
  30338  *
  30339  * Granularity is in kbits/sec and a rate of 0 disables rate limiting.
  30340  * The max burst size is set in kbits.
  30341  */
  30342 
  30343 /*
  30344  * Function:
  30345  *      bcm_port_rate_egress_set
  30346  * Purpose:
  30347  *      Set egress rate limiting parameters
  30348  * Parameters:
  30349  *      unit - Device number
  30350  *      port - Port number
  30351  *      kbits_sec - Rate in kilobits (1000 bits) per second.
  30352  *                      Rate of 0 disables rate limiting.
  30353  *      kbits_burst - Maximum burst size in kilobits (1000 bits).
  30354  * Returns:
  30355  *      BCM_E_XXX
  30356  */
  30357 
  30358 int
  30359 bcm_esw_port_rate_egress_set(int unit,
  30360                              bcm_port_t port,
  30361                              uint32 kbits_sec,
  30362                              uint32 kbits_burst)
  30363 {
  30364     /* Make sure port module is initialized. */
  30365     PORT_INIT(unit);
  30366 
  30367     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30368 
  30369     if (!soc_feature(unit, soc_feature_egress_metering)) {
  30370         return BCM_E_UNAVAIL;
  30371     } else {
  30372         return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port,
  30373                                                             kbits_sec,
  30374                                                             kbits_burst,
  30375                                                             _BCM_PORT_RATE_BYTE_MODE);
  30376     }
  30377 
  30378     return BCM_E_NONE;
  30379 }
  30380 
  30381 /*
  30382  * Function:
  30383  *      bcm_port_rate_egress_pps_set
  30384  * Purpose:
  30385  *      Set egress rate limiting parameter in packet mode.
  30386  * Parameters:
  30387  *      unit - Device number
  30388  *      port - Port number
  30389  *      pps -  Rate in pps
  30390  *             Rate of 0 disables rate limiting.
  30391  *      burst - Maximum burst size
  30392  * Returns:
  30393  *      BCM_E_XXX
  30394  */
  30395 
  30396 int
  30397 bcm_esw_port_rate_egress_pps_set(int unit,
  30398                              bcm_port_t port,
  30399                              uint32 pps,
  30400                              uint32 burst)
  30401 {
  30402     /* Make sure port module is initialized. */
  30403     PORT_INIT(unit);
  30404 
  30405     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30406 
  30407     if (!soc_feature(unit, soc_feature_egress_metering)) {
  30408         return BCM_E_UNAVAIL;
  30409     } else {
  30410         return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port,
  30411                                                             pps,
  30412                                                             burst,
  30413                                                             _BCM_PORT_RATE_PPS_MODE);
  30414     }
  30415 
  30416     return BCM_E_NONE;
  30417 }
  30418 
  30419 
  30420 /*
  30421  * Function:
  30422  *      bcm_port_rate_egress_get
  30423  * Purpose:
  30424  *      Get egress rate limiting parameters
  30425  * Parameters:
  30426  *      unit - Device number
  30427  *      port - Port number
  30428  *      kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or
  30429  *                        zero if rate limiting is disabled.
  30430  *      kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits).
  30431  * Returns:
  30432  *      BCM_E_XXX
  30433  */
  30434 
  30435 int
  30436 bcm_esw_port_rate_egress_get(int unit,
  30437                              bcm_port_t port,
  30438                              uint32 *kbits_sec,
  30439                              uint32 *kbits_burst)
  30440 {
  30441     uint32 flags = 0;
  30442     int    rv = BCM_E_NONE;
  30443 
  30444     /* Make sure port module is initialized. */
  30445     PORT_INIT(unit);
  30446 
  30447     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30448 
  30449     if (!soc_feature(unit, soc_feature_egress_metering)) {
  30450         return BCM_E_UNAVAIL;
  30451     } else {
  30452         rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port,
  30453                                                             kbits_sec,
  30454                                                             kbits_burst,
  30455                                                             &flags);
  30456     }
  30457 
  30458     if (BCM_SUCCESS(rv)) {
  30459         if (flags == _BCM_PORT_RATE_BYTE_MODE) {
  30460             return BCM_E_NONE;
  30461         } else {
  30462             /* Set as pps; kbits cannot be returned */
  30463             return BCM_E_CONFIG;
  30464         }
  30465     }
  30466 
  30467     return rv;
  30468 }
  30469 
  30470 /*
  30471  * Function:
  30472  *      bcm_port_rate_egress_pps_get
  30473  * Purpose:
  30474  *      Get egress rate limiting parameter in packet mode.
  30475  * Parameters:
  30476  *      unit - Device number
  30477  *      port - Port number
  30478  *      pps -  (OUT) Rate in pps
  30479  *                   0 if rate limiting is disabled
  30480  *      burst -(OUT) burst size
  30481  * Returns:
  30482  *      BCM_E_XXX
  30483  */
  30484 
  30485 int
  30486 bcm_esw_port_rate_egress_pps_get(int unit,
  30487                              bcm_port_t port,
  30488                              uint32 *pps,
  30489                              uint32 *burst)
  30490 {
  30491     uint32 flags = 0;
  30492     int    rv = BCM_E_NONE;
  30493 
  30494     /* Make sure port module is initialized. */
  30495     PORT_INIT(unit);
  30496 
  30497     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30498 
  30499     if (!soc_feature(unit, soc_feature_egress_metering)) {
  30500         return BCM_E_UNAVAIL;
  30501     } else {
  30502         rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port,
  30503                                                             pps,
  30504                                                             burst,
  30505                                                             &flags);
  30506     }
  30507 
  30508     if (BCM_SUCCESS(rv)) {
  30509         if (flags == _BCM_PORT_RATE_PPS_MODE) {
  30510             return BCM_E_NONE;
  30511         } else {
  30512             /* Set as kbits; pps cannot be returned */
  30513             return BCM_E_CONFIG;
  30514         }
  30515     }
  30516     return rv;
  30517 }
  30518 
  30519 /*
  30520  * Function:
  30521  *      bcm_port_rate_ingress_set
  30522  * Purpose:
  30523  *      Set ingress rate limiting parameters
  30524  * Parameters:
  30525  *      unit - Device number
  30526  *      port - Port number
  30527  *      kbits_sec - Rate in kilobits (1000 bits) per second.
  30528  *                  Rate of 0 disables rate limiting.
  30529  *      kbits_burst - Maximum burst size in kilobits (1000 bits).
  30530  * Returns:
  30531  *      BCM_E_XXX
  30532  */
  30533 
  30534 int
  30535 bcm_esw_port_rate_ingress_set(int unit,
  30536                               bcm_port_t port,
  30537                               uint32 kbits_sec,
  30538                               uint32 kbits_burst)
  30539 {
  30540     /* Make sure port module is initialized. */
  30541     PORT_INIT(unit);
  30542 
  30543     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30544 
  30545 #ifdef BCM_XGS3_SWITCH_SUPPORT
  30546     if (SOC_IS_XGS3_SWITCH(unit)) {
  30547         /*
  30548          * Use port-based ingress metering function.
  30549          * Enabling rate-based ingress metering on the Firebolt
  30550          * will also enable rate-based pause frames on this port.
  30551          */
  30552         return bcm_xgs3_port_rate_ingress_set(unit, port, kbits_sec,
  30553                                               kbits_burst);
  30554     }
  30555 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  30556 
  30557     return BCM_E_UNAVAIL;
  30558 }
  30559 
  30560 /*
  30561  * Function:
  30562  *      bcm_port_rate_ingress_get
  30563  * Purpose:
  30564  *      Get ingress rate limiting parameters
  30565  * Parameters:
  30566  *      unit - Device number
  30567  *      port - Port number
  30568  *      kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or
  30569  *                        zero if rate limiting is disabled.
  30570  *      kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits).
  30571  * Returns:
  30572  *      BCM_E_XXX
  30573  */
  30574 
  30575 int
  30576 bcm_esw_port_rate_ingress_get(int unit,
  30577                               bcm_port_t port,
  30578                               uint32 *kbits_sec,
  30579                               uint32 *kbits_burst)
  30580 {
  30581     /* Make sure port module is initialized. */
  30582     PORT_INIT(unit);
  30583 
  30584     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30585 
  30586     if (!kbits_sec || !kbits_burst) {
  30587         return BCM_E_PARAM;
  30588     }
  30589 
  30590 #ifdef BCM_XGS3_SWITCH_SUPPORT
  30591     if (SOC_IS_XGS3_SWITCH(unit)) {
  30592        /* Use port-based ingress metering function */
  30593         return bcm_xgs3_port_rate_ingress_get(unit, port, kbits_sec,
  30594                                             kbits_burst);
  30595     }
  30596 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  30597 
  30598     *kbits_sec = 0;
  30599     *kbits_burst = 0;
  30600 
  30601     return BCM_E_UNAVAIL;
  30602 }
  30603 
  30604 /*
  30605  * Function:
  30606  *      bcm_port_rate_pause_set
  30607  * Purpose:
  30608  *      Set ingress rate limiting pause frame control parameters
  30609  * Parameters:
  30610  *      unit - Device number
  30611  *      port - Port number
  30612  *      kbits_pause - Pause threshold in kbits (1000 bits).
  30613  *              A value of zero disables the pause/resume mechanism.
  30614  *      kbits_resume - Resume threshold in kbits (1000 bits).
  30615  * Returns:
  30616  *      BCM_E_XXX
  30617  * Notes:
  30618  *      This interface applies only when port ingress rate limiting
  30619  *      is active.  Currently, only the 566x supports this feature.
  30620  *
  30621  *      If the maximum of bits that could be received before dropping a
  30622  *      frame falls below the kbits_pause, a pause frame is sent.
  30623  *      A resume frame will be sent once it becomes possible to receive
  30624  *      kbits_resume bits of data without dropping.
  30625  */
  30626 
  30627 int
  30628 bcm_esw_port_rate_pause_set(int unit,
  30629                             bcm_port_t port,
  30630                             uint32 kbits_pause,
  30631                             uint32 kbits_resume)
  30632 {
  30633     /* Make sure port module is initialized. */
  30634     PORT_INIT(unit);
  30635 
  30636     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30637 
  30638 #ifdef BCM_FIREBOLT_SUPPORT
  30639     /*
  30640      * For Firebolt, rate-based pause frames are generated as
  30641      * a result of rate-based metering. As such, their behavior
  30642      * is not directly controllable, but may be read.
  30643      * see bcm_port_rate_pause_get().
  30644      */
  30645 #endif /* BCM_FIREBOLT_SUPPORT */
  30646     /* Otherwise, not supported  */
  30647     return (kbits_pause == 0) ? BCM_E_NONE : BCM_E_UNAVAIL;
  30648 }
  30649 
  30650 /*
  30651  * Function:
  30652  *      bcm_port_rate_pause_get
  30653  * Purpose:
  30654  *      Get ingress rate limiting pause frame control parameters
  30655  * Parameters:
  30656  *      unit - Device number
  30657  *      port - Port number
  30658  *      kbits_pause - (OUT) Pause threshold in kbits (1000 bits).
  30659  *              Zero indicates the pause/resume mechanism is disabled.
  30660  *      kbits_resume - (OUT) Resume threshold in kbits (1000 bits).
  30661  * Returns:
  30662  *      BCM_E_XXX
  30663  */
  30664 
  30665 int
  30666 bcm_esw_port_rate_pause_get(int unit,
  30667                             bcm_port_t port,
  30668                             uint32 *kbits_pause,
  30669                             uint32 *kbits_resume)
  30670 {
  30671     /* Make sure port module is initialized. */
  30672     PORT_INIT(unit);
  30673 
  30674 #if defined(BCM_HGPROXY_COE_SUPPORT)
  30675     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  30676         (soc_feature(unit, soc_feature_channelized_switching))) &&
  30677         BCM_GPORT_IS_SET(port) &&
  30678         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  30679         return BCM_E_PORT;
  30680     } else
  30681 #endif /* BCM_HGPROXY_COE_SUPPORT */
  30682 
  30683 #if defined(BCM_KATANA2_SUPPORT)
  30684     if (BCM_GPORT_IS_SET(port) &&
  30685         _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
  30686         return BCM_E_PORT;
  30687     }
  30688 #endif
  30689     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30690 
  30691 #ifdef BCM_MONTEREY_SUPPORT
  30692     if (SOC_IS_MONTEREY(unit)) {
  30693         *kbits_pause = 0;
  30694         *kbits_resume = 0;
  30695         return BCM_E_UNAVAIL;
  30696     } else
  30697 #endif
  30698 #ifdef BCM_TOMAHAWK_SUPPORT
  30699     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  30700         *kbits_pause = 0;
  30701         *kbits_resume = 0;
  30702         return BCM_E_UNAVAIL;
  30703     } else
  30704 #endif /* BCM_TOMAHAWK_SUPPORT */
  30705 #ifdef BCM_TRIDENT2_SUPPORT
  30706     if (SOC_IS_TD2_TT2(unit)) {
  30707         return bcm_td2_port_rate_pause_get(unit, port, kbits_pause,
  30708                                            kbits_resume);
  30709     } else
  30710 #endif /* BCM_TRIDENT2_SUPPORT */
  30711 #ifdef BCM_TRIUMPH_SUPPORT
  30712     if (SOC_IS_TR_VL(unit) && !SOC_IS_HURRICANEX(unit) &&
  30713         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  30714         return bcm_tr_port_rate_pause_get(unit, port, kbits_pause,
  30715                                           kbits_resume);
  30716     }
  30717 #endif /* BCM_TRIUMPH_SUPPORT */
  30718 #ifdef BCM_FIREBOLT_SUPPORT
  30719     if (SOC_IS_FBX(unit)) {
  30720         return bcm_fb_port_rate_pause_get(unit, port, kbits_pause,
  30721                                           kbits_resume);
  30722     }
  30723 #endif /* BCM_FIREBOLT_SUPPORT */
  30724     /* Otherwise, not supported */
  30725     *kbits_pause = 0;
  30726     *kbits_resume = 0;
  30727     return BCM_E_UNAVAIL;
  30728 }
  30729 
  30730 /*
  30731  * Function:
  30732  *      bcm_port_sample_rate_set
  30733  * Purpose:
  30734  *      Control the sampling of packets ingressing or egressing a port
  30735  * Parameters:
  30736  *      unit - Device number
  30737  *      port - Port number
  30738  *      ingress_rate - Every 1/ingress_rate packets will be sampled
  30739  *              0 indicates no sampling
  30740  *              1 indicates sampling all packets
  30741  *      egress_rate - Every 1/egress_rate packets will be sampled
  30742  *              0 indicates no sampling
  30743  *              1 indicates sampling all packets
  30744  * Returns:
  30745  *      BCM_E_XXX
  30746  * Notes:
  30747  *      This API is a building block for supporting sFlow (RFC 3176)
  30748  */
  30749 
  30750 int
  30751 bcm_esw_port_sample_rate_set(int unit, bcm_port_t port,
  30752                          int ingress_rate, int egress_rate)
  30753 {
  30754     /* Make sure port module is initialized. */
  30755     PORT_INIT(unit);
  30756 
  30757     /*
  30758      * IMPLEMENTATION NOTES
  30759      *
  30760      * ingress_rate maps into the per port SFLOW_ING_THRESHOLD reg:
  30761      *  if (ingress_rate <= 0) {
  30762      *          SFLOW_ING_THRESHOLD.ENABLE=0
  30763      *          SFLOW_ING_THRESHOLD.THRESHOLD=0
  30764      *  } else {
  30765      *          SFLOW_ING_THRESHOLD.ENABLE=1
  30766      *          SFLOW_ING_THRESHOLD.THRESHOLD=0xffff/ingress_rate
  30767      *  }
  30768      * egress_rate maps into the per port SFLOW_EGR_THRESHOLD reg:
  30769      *  if (egress_rate <= 0) {
  30770      *          SFLOW_EGR_THRESHOLD.ENABLE=0
  30771      *          SFLOW_EGR_THRESHOLD.THRESHOLD=0
  30772      *  } else {
  30773      *          SFLOW_EGR_THRESHOLD.ENABLE=1
  30774      *          SFLOW_EGR_THRESHOLD.THRESHOLD=0xffff/egress_rate
  30775      *  }
  30776      *
  30777      * bcmSwitchCpuSamplePrio maps to CPU_CONTROL_2.CPU_SFLOW_PRIORITY
  30778      * bcmSwitchSampleIngressRandomSeed maps to SFLOW_ING_RAND_SEED.SEED
  30779      * bcmSwitchSampleEgressRandomSeed maps to SFLOW_EGR_RAND_SEED.SEED
  30780      *
  30781      * There are two related RX reason codes defined in <bcm/rx.h>
  30782      *  BCM_RX_PR_SAMPLE_SRC
  30783      *  BCM_RX_PR_SAMPLE_DST
  30784      */
  30785 
  30786     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30787     if (ingress_rate < 0 || egress_rate < 0) {
  30788         return BCM_E_PARAM;
  30789     }
  30790 
  30791 #ifdef BCM_XGS3_SWITCH_SUPPORT
  30792     if (SOC_IS_XGS3_SWITCH(unit)) {
  30793         return bcm_xgs3_port_sample_rate_set(unit, port,
  30794                                              ingress_rate, egress_rate);
  30795     }
  30796 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  30797 
  30798     return BCM_E_UNAVAIL;
  30799 }
  30800 
  30801 /*
  30802  * Function:
  30803  *      bcm_port_sample_rate_get
  30804  * Purpose:
  30805  *      Get the sampling of packets ingressing or egressing a port
  30806  * Parameters:
  30807  *      unit - Device number
  30808  *      port - Port number
  30809  *      ingress_rate - Every 1/ingress_rate packets will be sampled
  30810  *              0 indicates no sampling
  30811  *              1 indicates sampling all packets
  30812  *      egress_rate - Every 1/egress_rate packets will be sampled
  30813  *              0 indicates no sampling
  30814  *              1 indicates sampling all packets
  30815  * Returns:
  30816  *      BCM_E_UNIT
  30817  *      BCM_E_PARAM
  30818  *      BCM_E_UNAVAIL
  30819  *      BCM_E_XXX
  30820  * Notes:
  30821  *      This API is a building block for supporting sFlow (RFC 3176)
  30822  */
  30823 
  30824 int
  30825 bcm_esw_port_sample_rate_get(int unit, bcm_port_t port,
  30826                          int *ingress_rate, int *egress_rate)
  30827 {
  30828     /* Make sure port module is initialized. */
  30829     PORT_INIT(unit);
  30830 
  30831     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30832 
  30833     if (ingress_rate == NULL  || egress_rate == NULL) {
  30834         return BCM_E_PARAM;
  30835     }
  30836 
  30837 #ifdef BCM_XGS3_SWITCH_SUPPORT
  30838     if (SOC_IS_XGS3_SWITCH(unit)) {
  30839         return bcm_xgs3_port_sample_rate_get(unit, port,
  30840                                            ingress_rate, egress_rate);
  30841     }
  30842 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  30843 
  30844 
  30845     return BCM_E_UNAVAIL;
  30846 }
  30847 
  30848 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  30849 #ifdef BCM_WARM_BOOT_SUPPORT
  30850 STATIC int
  30851 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem)
  30852 {
  30853     int idx_min, idx_max, i, id, rv = 0;
  30854     soc_counter_non_dma_t *non_dma = NULL;
  30855     soc_control_t *soc;
  30856     uint32 count = 0, subset_ct = 0, sflow_enable = 0;
  30857     uint8 *sflow_tbl_chunk = NULL;
  30858     void *sflow_entry;
  30859 
  30860     soc = SOC_CONTROL(unit);
  30861 
  30862     idx_min = soc_mem_index_min(unit, mem);
  30863     idx_max = soc_mem_index_max(unit, mem);
  30864     sflow_tbl_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
  30865                         "sFlow Ingress Data Source table buffer");
  30866     if (sflow_tbl_chunk == NULL) {
  30867         return BCM_E_MEMORY;
  30868     }
  30869 
  30870     /* Read Ingress rate data table entries */
  30871     sal_memset(sflow_tbl_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem));
  30872     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
  30873                             sflow_tbl_chunk);
  30874     if (SOC_FAILURE(rv)) {
  30875         soc_cm_sfree(unit, sflow_tbl_chunk);
  30876         return rv;
  30877     }
  30878 
  30879     if (mem == SFLOW_ING_DATA_SOURCEm) {
  30880         id = SOC_COUNTER_NON_DMA_SFLOW_ING_PKT;
  30881     } else {
  30882         id = SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT;
  30883     }
  30884 
  30885     for(i = idx_min; i < idx_max; i++) {
  30886         sflow_entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
  30887                                                    sflow_tbl_chunk, i);
  30888         sflow_enable = soc_mem_field32_get(unit, mem, sflow_entry, ENABLEf);
  30889 
  30890         if (sflow_enable) {
  30891             non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
  30892             /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  30893             subset_ct = non_dma->extra_ctr_ct << 1;
  30894             non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  30895             non_dma = non_dma->extra_ctrs;
  30896 
  30897             do {
  30898                 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  30899                 /* BYTE_CTRf not currently supported */
  30900                 count += 2;
  30901                 non_dma += 2;
  30902             } while ((count < subset_ct));
  30903             break;
  30904         }
  30905     }
  30906 
  30907     soc_cm_sfree(unit, sflow_tbl_chunk);
  30908     return BCM_E_NONE;
  30909 }
  30910 
  30911 /**
  30912  * Function:
  30913  *      _bcm_esw_sflow_wb_recover
  30914  * Purpose:
  30915  *      sFlow Warmboot Recovery
  30916  * Parameters:
  30917  *      unit - (IN) Unit number
  30918  * Returns:
  30919  *      BCM_E_xxx
  30920  */
  30921 STATIC int
  30922 _bcm_esw_sflow_wb_recover(int unit) {
  30923     int rv = 0;
  30924 
  30925     if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  30926         rv = _bcm_esw_sflow_counter_wb_recover(unit, SFLOW_ING_DATA_SOURCEm);
  30927         if (BCM_FAILURE(rv)) {
  30928             return rv;
  30929         }
  30930     }
  30931 
  30932     if (soc_feature(unit, soc_feature_sflow_flex)) {
  30933         rv = _bcm_esw_sflow_counter_wb_recover(unit,
  30934                 SFLOW_ING_FLEX_DATA_SOURCEm);
  30935         if (BCM_FAILURE(rv)) {
  30936             return rv;
  30937         }
  30938     }
  30939 
  30940     return BCM_E_NONE;
  30941 }
  30942 #endif /* BCM_WARM_BOOT_SUPPORT */
  30943 #endif /* BCM_TOMAHAWK_SUPPORT */
  30944 
  30945 /*
  30946  * Double Tagging
  30947  */
  30948 
  30949 /*
  30950  * Function:
  30951  *      bcm_port_dtag_mode_set
  30952  * Description:
  30953  *      Set the double-tagging mode of a port.
  30954  * Parameters:
  30955  *      unit - Device number
  30956  *      port - Port number
  30957  *      mode - Double-tagging mode, one of:
  30958  *              BCM_PORT_DTAG_MODE_NONE            No double tagging
  30959  *              BCM_PORT_DTAG_MODE_INTERNAL        Service Provider port
  30960  *              BCM_PORT_DTAG_MODE_EXTERNAL        Customer port
  30961  *              BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG  Remove customer tag
  30962  *              BCM_PORT_DTAG_ADD_EXTERNAL_TAG     Add customer tag
  30963  * Return Value:
  30964  *      BCM_E_XXX
  30965  * Notes:
  30966  *      BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports.
  30967  *              A tag will be added if the packet does not already
  30968  *              have the internal TPID (see bcm_port_tpid_set below).
  30969  *              Internally this sets DT_MODE and clears IGNORE_TAG.
  30970  *      BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports.
  30971  *              The service provider TPID will always be added
  30972  *              (see bcm_port_tpid_set below).
  30973  *              Internally this sets DT_MODE and sets IGNORE_TAG.
  30974  *      On some chips, such as BCM5665, double-tag enable is a system-wide
  30975  *              setting rather than a port setting, so enabling double-
  30976  *              tagging on one port may enable it on all ports.
  30977  */
  30978 
  30979 int
  30980 bcm_esw_port_dtag_mode_set(int unit, bcm_port_t port, int mode)
  30981 {
  30982 #ifdef BCM_FIREBOLT_SUPPORT
  30983     int         dt_mode, ignore_tag;
  30984 #endif
  30985     int         dt_mode_mask;
  30986 
  30987     /* Make sure port module is initialized. */
  30988     PORT_INIT(unit);
  30989 
  30990     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30991     /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */
  30992     if (!(IS_ST_PORT(unit, port) &&
  30993           soc_feature(unit, soc_feature_higig_lookup))) {
  30994         PORT_SWITCHED_CHECK(unit, port);
  30995     }
  30996 
  30997     dt_mode_mask = BCM_PORT_DTAG_MODE_INTERNAL |
  30998         BCM_PORT_DTAG_MODE_EXTERNAL;
  30999 
  31000 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  31001     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || \
  31002         SOC_IS_HAWKEYE(unit) || SOC_IS_TRX(unit)) {
  31003         if (mode & ~(BCM_PORT_DTAG_MODE_INTERNAL |
  31004                      BCM_PORT_DTAG_MODE_EXTERNAL |
  31005                      BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG |
  31006                      BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) {
  31007             return BCM_E_UNAVAIL;
  31008         }
  31009 
  31010         if (IS_ST_PORT(unit, port)) {
  31011             /* Addition or removal of two tags is not supported on
  31012              * Higig / Higig Lite ports.
  31013              */
  31014             if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG ||
  31015                 mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) {
  31016                 return BCM_E_PARAM;
  31017             }
  31018         }
  31019 
  31020         /* Removal of two tags should be enable only for UNI egress ports. */
  31021         if (mode == (BCM_PORT_DTAG_MODE_INTERNAL |
  31022                      BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) {
  31023             return BCM_E_PARAM;
  31024         }
  31025 
  31026 #ifdef BCM_TRX_SUPPORT
  31027         if (SOC_IS_TRX(unit)) {
  31028             if (!soc_feature(unit, soc_feature_vlan_action)) {
  31029                 return BCM_E_UNAVAIL;
  31030             }
  31031             return  _bcm_trx_port_dtag_mode_set(unit, port, mode);
  31032         }
  31033 #endif
  31034     } else
  31035 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  31036     if (0 != (mode & ~dt_mode_mask)) {
  31037         /* Some devices do not support the add/remove tag options */
  31038         return BCM_E_UNAVAIL;
  31039     }
  31040 
  31041 #ifdef BCM_FIREBOLT_SUPPORT
  31042     switch (mode & dt_mode_mask) {
  31043       case BCM_PORT_DTAG_MODE_NONE:
  31044           dt_mode = 0;
  31045           ignore_tag = 0;
  31046           break;
  31047       case BCM_PORT_DTAG_MODE_INTERNAL:
  31048           dt_mode = 1;
  31049           ignore_tag = 0;
  31050           break;
  31051       case BCM_PORT_DTAG_MODE_EXTERNAL:
  31052           dt_mode = 1;
  31053           ignore_tag = 1;
  31054           break;
  31055       default:
  31056           return BCM_E_PARAM;
  31057     }
  31058 
  31059     if (SOC_IS_FBX(unit)) {
  31060         return _bcm_fb_port_dtag_mode_set(unit, port, mode,
  31061                                           dt_mode, ignore_tag);
  31062     }
  31063 #endif
  31064     return BCM_E_UNAVAIL;
  31065 }
  31066 
  31067 /*
  31068  * Function:
  31069  *      bcm_port_dtag_mode_get
  31070  * Description:
  31071  *      Return the current double-tagging mode of a port.
  31072  * Parameters:
  31073  *      unit - Device number
  31074  *      port - Port number
  31075  *      mode - (OUT) Double-tagging mode
  31076  * Return Value:
  31077  *      BCM_E_XXX
  31078  */
  31079 
  31080 int
  31081 bcm_esw_port_dtag_mode_get(int unit, bcm_port_t port, int *mode)
  31082 {
  31083     /* Make sure port module is initialized. */
  31084     PORT_INIT(unit);
  31085 
  31086     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  31087     /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */
  31088     if (!(IS_ST_PORT(unit, port) &&
  31089           soc_feature(unit, soc_feature_higig_lookup))) {
  31090         PORT_SWITCHED_CHECK(unit, port);
  31091     }
  31092 
  31093     if (mode == NULL) {
  31094         return BCM_E_PARAM;
  31095     }
  31096 
  31097 #ifdef BCM_TRX_SUPPORT
  31098     if (SOC_IS_TRX(unit)) {
  31099         *mode = PORT(unit, port).dtag_mode;
  31100         return BCM_E_NONE;
  31101     }
  31102 #endif
  31103 
  31104 #ifdef BCM_FIREBOLT_SUPPORT
  31105     if (SOC_IS_FBX(unit)) {
  31106         return _bcm_fb_port_dtag_mode_get(unit, port, mode);
  31107     }
  31108 #endif
  31109 
  31110     return BCM_E_UNAVAIL;
  31111 }
  31112 
  31113 /*
  31114  * Function:
  31115  *      _bcm_esw_mod_port_tpid_set
  31116  * Description:
  31117  *      Set the Tag Protocol ID for a (module, port).
  31118  * Parameters:
  31119  *      unit - Device number
  31120  *      mod  - Module ID
  31121  *      port - Port number
  31122  *      tpid - Tag Protocol ID
  31123  * Return Value:
  31124  *      BCM_E_XXX
  31125  */
  31126 STATIC int
  31127 _bcm_esw_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port,
  31128         uint16 tpid)
  31129 {
  31130 #ifdef BCM_HURRICANE3_SUPPORT
  31131     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31132         return _bcm_hr3_mod_port_tpid_set(unit, mod, port, tpid);
  31133     } else
  31134 #endif /* BCM_HURRICANE3_SUPPORT */
  31135 #ifdef BCM_TRIDENT_SUPPORT
  31136     {
  31137         return _bcm_td_mod_port_tpid_set(unit, mod, port, tpid);
  31138     }
  31139 #endif /* BCM_TRIDENT_SUPPORT */
  31140     return BCM_E_UNAVAIL;
  31141 }
  31142 
  31143 #if defined(BCM_MONTEREY_SUPPORT)
  31144 STATIC
  31145 void bcm_port_inner_tpid_obm_set(int unit, bcm_port_t port, uint16 tpid)
  31146 {
  31147    uint32 rval32 = 0;
  31148    int obm, pgw, pgw_inst;
  31149    soc_info_t  *si;
  31150    soc_reg_t reg;
  31151    static const soc_reg_t obm_inner_tpid_regs[] = {
  31152         IDB_OBM0_INNER_TPIDr, IDB_OBM1_INNER_TPIDr,
  31153         IDB_OBM2_INNER_TPIDr, IDB_OBM3_INNER_TPIDr,
  31154         IDB_OBM4_INNER_TPIDr, IDB_OBM5_INNER_TPIDr,
  31155         IDB_OBM6_INNER_TPIDr, IDB_OBM7_INNER_TPIDr
  31156     };
  31157     if ((port < 1) || (port > 64)) {
  31158         return;
  31159     }
  31160     si = &SOC_INFO(unit);
  31161     obm = si->port_serdes[port];
  31162     obm %= MONTEREY_TSCS_PER_PGW;
  31163 
  31164     pgw = si->port_group[port];
  31165     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
  31166 
  31167     reg =  obm_inner_tpid_regs[obm];
  31168 
  31169     soc_reg32_get(unit, reg, pgw_inst, 0, &rval32);
  31170     soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid);
  31171     soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0);
  31172     soc_reg32_set(unit, reg, pgw_inst, 0, rval32);
  31173     return;
  31174 }
  31175 STATIC
  31176 void bcm_inner_tpid_obm_set(int unit, uint16 tpid)
  31177 {
  31178    int port;
  31179    BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  31180         bcm_port_inner_tpid_obm_set(unit, port, tpid);
  31181    }
  31182    return;
  31183 }
  31184 STATIC
  31185 void bcm_port_outer_tpid_obm_set(int unit, bcm_port_t port,
  31186                                  uint16 tpid, int tpid_index)
  31187 {
  31188    uint32 rval32 = 0;
  31189    int obm, pgw, pgw_inst;
  31190    soc_info_t  *si;
  31191    soc_reg_t reg;
  31192    static const soc_reg_t obm_inner_tpid_regs[][4] = {
  31193         {IDB_OBM0_OUTER_TPID_0r, IDB_OBM0_OUTER_TPID_1r,
  31194          IDB_OBM0_OUTER_TPID_2r, IDB_OBM0_OUTER_TPID_3r},
  31195         {IDB_OBM1_OUTER_TPID_0r, IDB_OBM1_OUTER_TPID_1r,
  31196          IDB_OBM1_OUTER_TPID_2r, IDB_OBM1_OUTER_TPID_3r},
  31197         {IDB_OBM2_OUTER_TPID_0r, IDB_OBM2_OUTER_TPID_1r,
  31198          IDB_OBM2_OUTER_TPID_2r, IDB_OBM2_OUTER_TPID_3r},
  31199         {IDB_OBM3_OUTER_TPID_0r, IDB_OBM3_OUTER_TPID_1r,
  31200          IDB_OBM3_OUTER_TPID_2r, IDB_OBM3_OUTER_TPID_3r},
  31201         {IDB_OBM4_OUTER_TPID_0r, IDB_OBM4_OUTER_TPID_1r,
  31202          IDB_OBM4_OUTER_TPID_2r, IDB_OBM4_OUTER_TPID_3r},
  31203         {IDB_OBM5_OUTER_TPID_0r, IDB_OBM5_OUTER_TPID_1r,
  31204          IDB_OBM5_OUTER_TPID_2r, IDB_OBM5_OUTER_TPID_3r},
  31205         {IDB_OBM6_OUTER_TPID_0r, IDB_OBM6_OUTER_TPID_1r,
  31206          IDB_OBM6_OUTER_TPID_2r, IDB_OBM6_OUTER_TPID_3r},
  31207         {IDB_OBM7_OUTER_TPID_0r, IDB_OBM7_OUTER_TPID_1r,
  31208          IDB_OBM7_OUTER_TPID_2r, IDB_OBM7_OUTER_TPID_3r}
  31209     };
  31210     if ((port < 1) || (port > 64) ||
  31211         (tpid_index < 0) || (tpid_index > 3)) {
  31212         return;
  31213     }
  31214     si = &SOC_INFO(unit);
  31215     obm = si->port_serdes[port];
  31216     obm %= MONTEREY_TSCS_PER_PGW;
  31217 
  31218     pgw = si->port_group[port];
  31219     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
  31220 
  31221     reg =  obm_inner_tpid_regs[obm][tpid_index];
  31222 
  31223     soc_reg32_get(unit, reg, pgw_inst, 0, &rval32);
  31224     soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid);
  31225     soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0);
  31226     soc_reg32_set(unit, reg, pgw_inst, 0, rval32);
  31227     return;
  31228 }
  31229 #endif
  31230 /*
  31231  * Function:
  31232  *      bcm_port_tpid_set
  31233  * Description:
  31234  *      Set the default Tag Protocol ID for a port.
  31235  * Parameters:
  31236  *      unit - Device number
  31237  *      port - Port number
  31238  *      tpid - Tag Protocol ID
  31239  * Return Value:
  31240  *      BCM_E_XXX
  31241  * Notes:
  31242  *      This API is not specifically double-tagging-related, but
  31243  *      the port TPID becomes the service provider TPID when double-tagging
  31244  *      is enabled on a port.  The default TPID is 0x8100.
  31245  *      On BCM5665, only 0x8100 is allowed for the inner (customer) tag.
  31246  */
  31247 
  31248 int
  31249 bcm_esw_port_tpid_set(int unit, bcm_port_t port, uint16 tpid)
  31250 {
  31251     int rv = BCM_E_UNAVAIL;
  31252     bcm_module_t mod_out;
  31253     bcm_port_t port_out;
  31254     bcm_trunk_t tgid_out;
  31255     int id_out;
  31256     int is_local = 0, tpid_index = 0;
  31257 #ifdef BCM_FIREBOLT_SUPPORT
  31258     bcm_port_t orig_port = -1;
  31259 #endif
  31260 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31261     int vp = -1;
  31262 #endif
  31263 
  31264     /* Make sure port module is initialized. */
  31265     PORT_INIT(unit);
  31266 
  31267     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31268         LOG_ERROR(BSL_LS_BCM_PORT,
  31269                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31270                    port));
  31271         return BCM_E_PARAM;
  31272     }
  31273 
  31274     if (BCM_GPORT_IS_SET(port)) {
  31275         /* Handle virtual ports separetly */
  31276         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31277             BCM_GPORT_IS_MIM_PORT(port) ||
  31278             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31279             BCM_GPORT_IS_FLOW_PORT(port) ||
  31280             BCM_GPORT_IS_VLAN_PORT(port)) {
  31281             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31282 #if defined(BCM_TRX_SUPPORT)
  31283                 PORT_LOCK(unit);
  31284                 rv = _bcm_trx_vp_tpid_set(unit, port, tpid);
  31285                 PORT_UNLOCK(unit);
  31286 #endif
  31287             }
  31288             return rv;
  31289         } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  31290             if (soc_feature(unit, soc_feature_subtag_coe)) {
  31291 #if defined(BCM_KATANA2_SUPPORT)
  31292                 PORT_LOCK(unit);
  31293                 rv = bcm_kt2_subport_subtag_port_tpid_set(unit, port, tpid);
  31294                 PORT_UNLOCK(unit);
  31295 #endif
  31296             }
  31297             return rv;
  31298         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31299 
  31300             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  31301                 (soc_feature(unit, soc_feature_channelized_switching))) {
  31302 #ifdef BCM_HGPROXY_COE_SUPPORT
  31303                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31304                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31305                         &mod_out, &port_out, &tgid_out, &id_out));
  31306                     orig_port = port;
  31307                     BCM_IF_ERROR_RETURN(
  31308                         _bcmi_coe_subport_physical_port_get(unit,
  31309                                     port, &port));
  31310                     } else {
  31311                         return BCM_E_PORT;
  31312                 }
  31313 #endif
  31314         } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31315                 soc_feature(unit, soc_feature_linkphy_coe)) {
  31316 #ifdef BCM_KATANA2_SUPPORT
  31317                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31318                     port)) {
  31319                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31320                         &mod_out, &port_out, &tgid_out, &id_out));
  31321                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31322                         mod_out, port_out, &port));
  31323                 } else {
  31324                     return BCM_E_PORT;
  31325                 }
  31326 #endif
  31327             } else {
  31328                 return BCM_E_PORT;
  31329             }
  31330         } else if (BCM_GPORT_IS_TRUNK(port)) {
  31331 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31332             if (soc_feature(unit, soc_feature_vp_lag)) {
  31333                 BCM_IF_ERROR_RETURN(
  31334                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  31335                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  31336                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  31337                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31338                         PORT_LOCK(unit);
  31339                         rv = _bcm_trx_vp_tpid_set(unit, port, tpid);
  31340                         PORT_UNLOCK(unit);
  31341                         return rv;
  31342                     }
  31343                 } else {
  31344                     return BCM_E_PARAM;
  31345                 }
  31346             }
  31347 #endif
  31348             return BCM_E_PARAM;
  31349         } else {
  31350             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31351                         &mod_out, &port_out, &tgid_out, &id_out));
  31352             if ((-1 != tgid_out) || (-1 != id_out)) {
  31353                 return BCM_E_PARAM;
  31354             }
  31355 
  31356             BCM_IF_ERROR_RETURN
  31357                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31358 #if defined(BCM_HURRICANE3_SUPPORT)
  31359             /* Here only take care non-local port, the local port will
  31360              * be handled later (by _bcm_fb2_port_tpid_set) */
  31361             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31362                 if (!is_local) {
  31363                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31364                         return _bcm_esw_mod_port_tpid_set(unit, mod_out,
  31365                                                           port_out, tpid);
  31366                     } else {
  31367                         return BCM_E_PARAM;
  31368                     }
  31369                 } else {
  31370                     BCM_IF_ERROR_RETURN(
  31371                         bcm_esw_port_local_get(unit, port, &port));
  31372                 }
  31373             } else
  31374 #endif
  31375             {
  31376                 if (!is_local) {
  31377                         if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm) ||
  31378                             soc_feature(unit,soc_feature_stm_tpid_support)) {
  31379                             return _bcm_esw_mod_port_tpid_set(unit, mod_out,
  31380                                                               port_out, tpid);
  31381                         } else {
  31382                             return BCM_E_PARAM;
  31383                         }
  31384                 } else {
  31385                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31386                         BCM_IF_ERROR_RETURN
  31387                             (_bcm_esw_mod_port_tpid_set(unit, mod_out,
  31388                                                         port_out, tpid));
  31389                     }
  31390                     BCM_IF_ERROR_RETURN(
  31391                         bcm_esw_port_local_get(unit, port, &port));
  31392                 }
  31393             }
  31394         }
  31395     } else if (!SOC_PORT_VALID(unit, port)) {
  31396         return BCM_E_PORT;
  31397     }
  31398 
  31399 #if defined (BCM_TRX_SUPPORT)
  31400     if (SOC_IS_TRX(unit) &&
  31401         (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) {
  31402         /* For DT mode external ports, don't enable any outer TPIDs */
  31403         return BCM_E_NONE;
  31404     }
  31405 #endif
  31406 
  31407 #ifdef BCM_FIREBOLT_SUPPORT
  31408     if (SOC_IS_FBX(unit)) {
  31409         PORT_LOCK(unit);
  31410 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \
  31411         defined(BCM_RAVEN_SUPPORT)
  31412         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31413             if (orig_port != -1) {
  31414                 rv = _bcm_fb2_port_tpid_set(unit, orig_port, tpid, &tpid_index);
  31415             } else {
  31416                 rv = _bcm_fb2_port_tpid_set(unit, port, tpid, &tpid_index);
  31417             }
  31418 #if defined(BCM_TOMAHAWK_SUPPORT)
  31419     /* For Tomahawk low latency mode, use outer_tpid field  */
  31420     /* of EGR_VLAN_TAG_ACTION_FOR_BYPASSr on egress side    */
  31421             if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) {
  31422                 uint32 rval;
  31423                 bcm_port_t local_port;
  31424 
  31425                 if (orig_port != -1)
  31426                     local_port = orig_port;
  31427                 else {
  31428                     local_port = port;
  31429                 }
  31430 
  31431                 rv = READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port,
  31432                                                           &rval);
  31433                 if (SOC_FAILURE(rv)) {
  31434                     PORT_UNLOCK(unit);
  31435                     return (rv);
  31436                 }
  31437 
  31438                 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval,
  31439                                   OUTER_TPIDf, tpid);
  31440 
  31441                 rv = WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port,
  31442                                                            rval);
  31443                 if (SOC_FAILURE(rv)) {
  31444                     PORT_UNLOCK(unit);
  31445                     return (rv);
  31446                 }
  31447             }
  31448 #endif
  31449 #if defined(BCM_MONTEREY_SUPPORT)
  31450     if (soc_feature(unit, soc_feature_obm_tpid_sync)) {
  31451         bcm_port_outer_tpid_obm_set(unit, port, tpid, tpid_index);
  31452     }
  31453 #endif
  31454         } else
  31455 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  31456         {
  31457             rv = _bcm_fb_port_tpid_set(unit, port, tpid);
  31458         }
  31459         /* coverity[negative_shift] */
  31460         if (BCM_SUCCESS(rv) && SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  31461 
  31462             
  31463             if(!SOC_IS_TOMAHAWK3(unit)) {
  31464                 /*
  31465                  * At now, this mac drvier is only supported by XMAC & XLMAC
  31466                  * If function return BCM_E_UNAVAIL, it should be correct.
  31467                  */
  31468                 if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  31469                     rv = bcmi_esw_portctrl_vlan_tpid_set(unit, port, tpid);
  31470                 } else {
  31471                     rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  31472                                      SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID, tpid);
  31473                     if (rv == BCM_E_UNAVAIL) {
  31474                         rv = BCM_E_NONE;
  31475                     }
  31476                 }
  31477             }
  31478         }
  31479         PORT_UNLOCK(unit);
  31480         return rv;
  31481     }
  31482 #endif
  31483 
  31484     if (tpid == 0x8100) {
  31485         return BCM_E_NONE;
  31486     }
  31487     return BCM_E_UNAVAIL;
  31488 }
  31489 
  31490 /*
  31491  * Function:
  31492  *      _bcm_esw_mod_port_tpid_get
  31493  * Description:
  31494  *      Retrieve the Tag Protocol ID for a (module, port).
  31495  * Parameters:
  31496  *      unit - Device number
  31497  *      mod  - Module ID
  31498  *      port - Port number
  31499  *      tpid - (OUT) Tag Protocol ID
  31500  * Return Value:
  31501  *      BCM_E_XXX
  31502  */
  31503 STATIC int
  31504 _bcm_esw_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port,
  31505         uint16 *tpid)
  31506 {
  31507 #ifdef BCM_HURRICANE3_SUPPORT
  31508     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31509         return _bcm_hr3_mod_port_tpid_get(unit, mod, port, tpid);
  31510     } else
  31511 #endif /* BCM_HURRICANE3_SUPPORT */
  31512 #ifdef BCM_TRIDENT_SUPPORT
  31513     {
  31514         return _bcm_td_mod_port_tpid_get(unit, mod, port, tpid);
  31515     }
  31516 #endif /* BCM_TRIDENT_SUPPORT */
  31517     return BCM_E_UNAVAIL;
  31518 }
  31519 
  31520 
  31521 /*
  31522  * Function:
  31523  *      bcm_port_tpid_get
  31524  * Description:
  31525  *      Retrieve the default Tag Protocol ID for a port.
  31526  * Parameters:
  31527  *      unit - Device number
  31528  *      port - Port number
  31529  *      tpid - (OUT) Tag Protocol ID
  31530  * Return Value:
  31531  *      BCM_E_XXX
  31532  */
  31533 
  31534 int
  31535 bcm_esw_port_tpid_get(int unit, bcm_port_t port, uint16 *tpid)
  31536 {
  31537     int rv = BCM_E_UNAVAIL;
  31538     bcm_module_t mod_out;
  31539     bcm_port_t port_out;
  31540     bcm_trunk_t tgid_out;
  31541     int id_out;
  31542     int is_local = 0;
  31543 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31544     int vp = -1;
  31545 #endif
  31546 
  31547     /* Make sure port module is initialized. */
  31548     PORT_INIT(unit);
  31549 
  31550     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31551         LOG_ERROR(BSL_LS_BCM_PORT,
  31552                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31553                    port));
  31554         return BCM_E_PARAM;
  31555     }
  31556 
  31557     if (BCM_GPORT_IS_SET(port)) {
  31558         /* Handle virtual ports separetly */
  31559         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31560             BCM_GPORT_IS_MIM_PORT(port) ||
  31561             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31562             BCM_GPORT_IS_FLOW_PORT(port) ||
  31563             BCM_GPORT_IS_VLAN_PORT(port)) {
  31564 
  31565             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31566 #if defined(BCM_TRX_SUPPORT)
  31567                 PORT_LOCK(unit);
  31568                 rv = _bcm_trx_vp_tpid_get(unit, port, tpid);
  31569                 PORT_UNLOCK(unit);
  31570 #endif
  31571             }
  31572             return rv;
  31573         } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  31574             if (soc_feature(unit, soc_feature_subtag_coe)) {
  31575 #if defined(BCM_KATANA2_SUPPORT)
  31576                 PORT_LOCK(unit);
  31577                 rv = bcm_kt2_subport_subtag_port_tpid_get(unit, port, tpid);
  31578                 PORT_UNLOCK(unit);
  31579 #endif
  31580             }
  31581             return rv;
  31582         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31583 
  31584             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  31585                 (soc_feature(unit, soc_feature_channelized_switching))) {
  31586 #ifdef BCM_HGPROXY_COE_SUPPORT
  31587                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31588                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31589                         &mod_out, &port_out, &tgid_out, &id_out));
  31590                     } else {
  31591                         return BCM_E_PORT;
  31592                 }
  31593 #endif
  31594             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31595                        soc_feature(unit, soc_feature_linkphy_coe)) {
  31596 #ifdef BCM_KATANA2_SUPPORT
  31597                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31598                     port)) {
  31599                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31600                         &mod_out, &port_out, &tgid_out, &id_out));
  31601                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31602                         mod_out, port_out, &port));
  31603                 } else {
  31604                     return BCM_E_PORT;
  31605                 }
  31606 #endif
  31607             } else {
  31608                 return BCM_E_PORT;
  31609             }
  31610         } else if (BCM_GPORT_IS_TRUNK(port)) {
  31611 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31612             if (soc_feature(unit, soc_feature_vp_lag)) {
  31613                 BCM_IF_ERROR_RETURN(
  31614                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  31615                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  31616                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  31617                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31618                         PORT_LOCK(unit);
  31619                         rv = _bcm_trx_vp_tpid_get(unit, port, tpid);
  31620                         PORT_UNLOCK(unit);
  31621                         return rv;
  31622                     }
  31623                 } else {
  31624                     return BCM_E_PARAM;
  31625                 }
  31626             }
  31627 #endif
  31628             return BCM_E_PARAM;
  31629         } else {
  31630             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31631                         &mod_out, &port_out, &tgid_out, &id_out));
  31632             if ((-1 != tgid_out) || (-1 != id_out)) {
  31633                 return BCM_E_PARAM;
  31634             }
  31635 
  31636             BCM_IF_ERROR_RETURN
  31637                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31638             if (!is_local) {
  31639                 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31640                     return _bcm_esw_mod_port_tpid_get(unit, mod_out, port_out,
  31641                             tpid);
  31642                 } else {
  31643                     return BCM_E_PARAM;
  31644                 }
  31645             } else {
  31646                 BCM_IF_ERROR_RETURN(
  31647                         bcm_esw_port_local_get(unit, port, &port));
  31648             }
  31649         }
  31650 
  31651     } else if (!SOC_PORT_VALID(unit, port)) {
  31652         return BCM_E_PORT;
  31653     }
  31654 
  31655     if (tpid == NULL) {
  31656         return BCM_E_PARAM;
  31657     }
  31658 
  31659 #ifdef BCM_FIREBOLT_SUPPORT
  31660     if (SOC_IS_FBX(unit)) {
  31661          PORT_LOCK(unit);
  31662 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  31663         || defined(BCM_RAVEN_SUPPORT)
  31664         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31665             rv = _bcm_fb2_port_tpid_get(unit, port, tpid);
  31666         } else
  31667 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  31668         {
  31669             rv = _bcm_fb_port_tpid_get(unit, port, tpid);
  31670         }
  31671         PORT_UNLOCK(unit);
  31672         return rv;
  31673     }
  31674 #endif /* BCM_FIREBOLT_SUPPORT */
  31675     *tpid = 0x8100;
  31676     return (BCM_E_NONE);
  31677 }
  31678 
  31679 /*
  31680  * Function:
  31681  *      _bcm_esw_mod_port_tpid_add
  31682  * Description:
  31683  *      Add TPID for a (module, port).
  31684  * Parameters:
  31685  *      unit - (IN) Device number
  31686  *      mod  - (IN) Module ID
  31687  *      port - (IN) Port number
  31688  *      tpid - (IN) Tag Protocol ID
  31689  * Return Value:
  31690  *      BCM_E_XXX
  31691  */
  31692 STATIC int
  31693 _bcm_esw_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port,
  31694                       uint16 tpid)
  31695 {
  31696 #ifdef BCM_HURRICANE3_SUPPORT
  31697     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31698         return _bcm_hr3_mod_port_tpid_add(unit, mod, port, tpid);
  31699     } else
  31700 #endif /* BCM_HURRICANE3_SUPPORT */
  31701 #ifdef BCM_TRIDENT_SUPPORT
  31702     {
  31703         return _bcm_td_mod_port_tpid_add(unit, mod, port, tpid);
  31704     }
  31705 #endif /* BCM_TRIDENT_SUPPORT */
  31706     return BCM_E_UNAVAIL;
  31707 }
  31708 
  31709 /*
  31710  * Function:
  31711  *      bcm_esw_port_tpid_add
  31712  * Description:
  31713  *      Add allowed TPID for a port.
  31714  * Parameters:
  31715  *      unit         - (IN) Device number
  31716  *      port         - (IN) Port number
  31717  *      tpid         - (IN) Tag Protocol ID
  31718  *      color_select - (IN) Color mode for TPID
  31719  * Return Value:
  31720  *      BCM_E_XXX
  31721  */
  31722 int
  31723 bcm_esw_port_tpid_add(int unit, bcm_port_t port,
  31724                       uint16 tpid, int color_select)
  31725 {
  31726     int rv = BCM_E_UNAVAIL;
  31727     bcm_module_t mod_out;
  31728     bcm_port_t port_out;
  31729     bcm_trunk_t tgid_out;
  31730     int id_out;
  31731     int is_local = 0;
  31732 #ifdef BCM_FIREBOLT_SUPPORT
  31733     bcm_port_t orig_port = -1;
  31734 #endif
  31735 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31736     int vp = -1;
  31737 #endif
  31738 
  31739     if (color_select != BCM_COLOR_PRIORITY &&
  31740         color_select != BCM_COLOR_OUTER_CFI &&
  31741         color_select != BCM_COLOR_INNER_CFI) {
  31742         return BCM_E_PARAM;
  31743     }
  31744 
  31745     /* Make sure port module is initialized. */
  31746     PORT_INIT(unit);
  31747 
  31748     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31749         LOG_ERROR(BSL_LS_BCM_PORT,
  31750                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31751                    port));
  31752         return BCM_E_PARAM;
  31753     }
  31754 
  31755     if (BCM_GPORT_IS_SET(port)) {
  31756         /* Handle virtual ports separetly */
  31757         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31758             BCM_GPORT_IS_MIM_PORT(port) ||
  31759             BCM_GPORT_IS_TRILL_PORT(port) ||
  31760             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31761             BCM_GPORT_IS_FLOW_PORT(port) ||
  31762             BCM_GPORT_IS_VLAN_PORT(port)) {
  31763 
  31764             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31765 #if defined(BCM_TRX_SUPPORT)
  31766                 PORT_LOCK(unit);
  31767                 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, color_select);
  31768                 PORT_UNLOCK(unit);
  31769 #endif
  31770             }
  31771             return rv;
  31772         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31773 
  31774             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  31775                 (soc_feature(unit, soc_feature_channelized_switching))) {
  31776 #ifdef BCM_HGPROXY_COE_SUPPORT
  31777                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31778                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31779                         &mod_out, &port_out, &tgid_out, &id_out));
  31780                     orig_port = port;
  31781                     BCM_IF_ERROR_RETURN(
  31782                         _bcmi_coe_subport_physical_port_get(unit,
  31783                                     port, &port));
  31784                     } else {
  31785                         return BCM_E_PORT;
  31786                     }
  31787 #endif
  31788             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31789                        soc_feature(unit, soc_feature_linkphy_coe)) {
  31790 #ifdef BCM_KATANA2_SUPPORT
  31791                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31792                     port)) {
  31793                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31794                         &mod_out, &port_out, &tgid_out, &id_out));
  31795                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31796                         mod_out, port_out, &port));
  31797                 } else {
  31798                     return BCM_E_PORT;
  31799                 }
  31800 #endif
  31801             } else {
  31802                 return BCM_E_PORT;
  31803             }
  31804         } else if (BCM_GPORT_IS_TRUNK(port)) {
  31805 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31806             if (soc_feature(unit, soc_feature_vp_lag)) {
  31807                 BCM_IF_ERROR_RETURN(
  31808                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  31809                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  31810                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  31811                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31812                         PORT_LOCK(unit);
  31813                         rv = _bcm_trx_vp_tpid_add(unit, port, tpid,
  31814                                                   color_select);
  31815                         PORT_UNLOCK(unit);
  31816                         return rv;
  31817                     }
  31818                 } else {
  31819                     return BCM_E_PARAM;
  31820                 }
  31821             }
  31822 #endif
  31823             return BCM_E_PARAM;
  31824         } else {
  31825             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31826                         &mod_out, &port_out, &tgid_out, &id_out));
  31827             if ((-1 != tgid_out) || (-1 != id_out)) {
  31828                 return BCM_E_PARAM;
  31829             }
  31830 
  31831             BCM_IF_ERROR_RETURN
  31832                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31833 #if defined(BCM_HURRICANE3_SUPPORT)
  31834             /* Here only take care non-local port, the local port will
  31835              * be handled later (by _bcm_fb2_port_tpid_add) */
  31836             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31837                 if (!is_local) {
  31838                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31839                         return _bcm_esw_mod_port_tpid_add(unit, mod_out,
  31840                                                           port_out, tpid);
  31841                     } else {
  31842                         return BCM_E_PARAM;
  31843                     }
  31844                 } else {
  31845                     BCM_IF_ERROR_RETURN(
  31846                             bcm_esw_port_local_get(unit, port, &port));
  31847                 }
  31848             } else
  31849 #endif
  31850             {
  31851                 if (!is_local) {
  31852                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31853                         return _bcm_esw_mod_port_tpid_add(unit, mod_out,
  31854                                                           port_out, tpid);
  31855                     } else {
  31856                         return BCM_E_PARAM;
  31857                     }
  31858                 } else {
  31859                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31860                         BCM_IF_ERROR_RETURN
  31861                             (_bcm_esw_mod_port_tpid_add(unit, mod_out,
  31862                                                         port_out, tpid));
  31863                     }
  31864                     BCM_IF_ERROR_RETURN(
  31865                         bcm_esw_port_local_get(unit, port, &port));
  31866                 }
  31867             }
  31868         }
  31869 
  31870     } else if (!SOC_PORT_VALID(unit, port)) {
  31871         return BCM_E_PORT;
  31872     }
  31873 
  31874 #if defined (BCM_TRX_SUPPORT)
  31875     if (SOC_IS_TRX(unit) &&
  31876         (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) {
  31877         /* For DT mode external ports, don't enable any outer TPIDs */
  31878         return BCM_E_NONE;
  31879     }
  31880 #endif
  31881 
  31882 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  31883     || defined(BCM_RAVEN_SUPPORT)
  31884     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31885         PORT_LOCK(unit);
  31886         if (orig_port != -1) {
  31887             rv = _bcm_fb2_port_tpid_add(unit, orig_port, tpid, color_select);
  31888         } else {
  31889             rv = _bcm_fb2_port_tpid_add(unit, port, tpid, color_select);
  31890         }
  31891         PORT_UNLOCK(unit);
  31892     }
  31893 #endif
  31894     return rv;
  31895 }
  31896 
  31897 /*
  31898  * Function:
  31899  *      _bcm_esw_mod_port_tpid_delete
  31900  * Description:
  31901  *      Delete TPID for a (module, port).
  31902  * Parameters:
  31903  *      unit - (IN) Device number
  31904  *      mod  - (IN) Module ID
  31905  *      port - (IN) Port number
  31906  *      tpid - (IN) Tag Protocol ID
  31907  * Return Value:
  31908  *      BCM_E_XXX
  31909  */
  31910 STATIC int
  31911 _bcm_esw_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port,
  31912         uint16 tpid)
  31913 {
  31914 #ifdef BCM_HURRICANE3_SUPPORT
  31915     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31916         return _bcm_hr3_mod_port_tpid_delete(unit, mod, port, tpid);
  31917     } else
  31918 #endif /* BCM_HURRICANE3_SUPPORT */
  31919 #ifdef BCM_TRIDENT_SUPPORT
  31920     {
  31921         return _bcm_td_mod_port_tpid_delete(unit, mod, port, tpid);
  31922     }
  31923 #endif /* BCM_TRIDENT_SUPPORT */
  31924     return BCM_E_UNAVAIL;
  31925 }
  31926 
  31927 /*
  31928  * Function:
  31929  *      bcm_esw_port_tpid_delete
  31930  * Description:
  31931  *      Delete allowed TPID for a port.
  31932  * Parameters:
  31933  *      unit - (IN) Device number
  31934  *      port - (IN) Port number
  31935  *      tpid - (IN) Tag Protocol ID
  31936  * Return Value:
  31937  *      BCM_E_XXX
  31938  */
  31939 int
  31940 bcm_esw_port_tpid_delete(int unit, bcm_port_t port, uint16 tpid)
  31941 {
  31942     int rv = BCM_E_UNAVAIL;
  31943     bcm_module_t mod_out;
  31944     bcm_port_t port_out;
  31945     bcm_trunk_t tgid_out;
  31946     int id_out;
  31947     int is_local = 0;
  31948 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31949     int vp = -1;
  31950 #endif
  31951 
  31952     /* Make sure port module is initialized. */
  31953     PORT_INIT(unit);
  31954 
  31955     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31956         LOG_ERROR(BSL_LS_BCM_PORT,
  31957                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31958                    port));
  31959         return BCM_E_PARAM;
  31960     }
  31961 
  31962     if (BCM_GPORT_IS_SET(port)) {
  31963         /* Handle virtual ports separetly */
  31964         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31965             BCM_GPORT_IS_TRILL_PORT(port) ||
  31966             BCM_GPORT_IS_MIM_PORT(port) ||
  31967             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31968             BCM_GPORT_IS_FLOW_PORT(port) ||
  31969             BCM_GPORT_IS_VLAN_PORT(port)) {
  31970 
  31971             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31972 #if defined(BCM_TRX_SUPPORT)
  31973                 PORT_LOCK(unit);
  31974                 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid);
  31975                 PORT_UNLOCK(unit);
  31976 #endif
  31977             }
  31978             return rv;
  31979         }  else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  31980             if (soc_feature(unit, soc_feature_subtag_coe)) {
  31981 #if defined(BCM_KATANA2_SUPPORT)
  31982                 PORT_LOCK(unit);
  31983                 rv = bcm_kt2_subport_subtag_port_tpid_delete(unit, port, tpid);
  31984                 PORT_UNLOCK(unit);
  31985 #endif
  31986             }
  31987             return rv;
  31988         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31989 
  31990             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  31991                 (soc_feature(unit, soc_feature_channelized_switching))) {
  31992 #ifdef BCM_HGPROXY_COE_SUPPORT
  31993                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31994                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31995                         &mod_out, &port_out, &tgid_out, &id_out));
  31996                     } else {
  31997                         return BCM_E_PORT;
  31998                     }
  31999 #endif
  32000             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  32001                        soc_feature(unit, soc_feature_linkphy_coe)) {
  32002 #ifdef BCM_KATANA2_SUPPORT
  32003                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  32004                     port)) {
  32005                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32006                         &mod_out, &port_out, &tgid_out, &id_out));
  32007                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  32008                         mod_out, port_out, &port));
  32009                 } else {
  32010                     return BCM_E_PORT;
  32011                 }
  32012 #endif
  32013             } else {
  32014                 return BCM_E_PORT;
  32015             }
  32016         } else if (BCM_GPORT_IS_TRUNK(port)) {
  32017 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  32018             if (soc_feature(unit, soc_feature_vp_lag)) {
  32019                 BCM_IF_ERROR_RETURN(
  32020                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  32021                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  32022                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  32023                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32024                         PORT_LOCK(unit);
  32025                         rv = _bcm_trx_vp_tpid_delete(unit, port, tpid);
  32026                         PORT_UNLOCK(unit);
  32027                         return rv;
  32028                     }
  32029                 } else {
  32030                     return BCM_E_PARAM;
  32031                 }
  32032             }
  32033 #endif
  32034             return BCM_E_PARAM;
  32035         } else {
  32036             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32037                         &mod_out, &port_out, &tgid_out, &id_out));
  32038             if ((-1 != tgid_out) || (-1 != id_out)) {
  32039                 return BCM_E_PARAM;
  32040             }
  32041 
  32042             BCM_IF_ERROR_RETURN
  32043                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  32044 #if defined(BCM_HURRICANE3_SUPPORT)
  32045             /* Here only take care non-local port, the local port will
  32046              * be handled later (by _bcm_fb2_port_tpid_delete) */
  32047             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  32048                 if (!is_local) {
  32049                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32050                         return _bcm_esw_mod_port_tpid_delete(unit, mod_out,
  32051                                                              port_out, tpid);
  32052                     } else {
  32053                         return BCM_E_PARAM;
  32054                     }
  32055                 } else {
  32056                     BCM_IF_ERROR_RETURN(
  32057                         bcm_esw_port_local_get(unit, port, &port));
  32058                 }
  32059             } else
  32060 #endif
  32061             {
  32062                 if (!is_local) {
  32063                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32064                         return _bcm_esw_mod_port_tpid_delete(unit, mod_out,
  32065                                                              port_out, tpid);
  32066                     } else {
  32067                         return BCM_E_PARAM;
  32068                     }
  32069                 } else {
  32070                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32071                         BCM_IF_ERROR_RETURN
  32072                             (_bcm_esw_mod_port_tpid_delete(unit, mod_out,
  32073                                                            port_out, tpid));
  32074                     }
  32075                     BCM_IF_ERROR_RETURN(
  32076                         bcm_esw_port_local_get(unit, port, &port));
  32077                 }
  32078             }
  32079         }
  32080 
  32081     } else if (!SOC_PORT_VALID(unit, port)) {
  32082         return BCM_E_PORT;
  32083     }
  32084 
  32085 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  32086     || defined(BCM_RAVEN_SUPPORT)
  32087     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32088         PORT_LOCK(unit);
  32089         rv = _bcm_fb2_port_tpid_delete(unit, port, tpid);
  32090         PORT_UNLOCK(unit);
  32091     }
  32092 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  32093     return rv;
  32094 }
  32095 
  32096 /*
  32097  * Function:
  32098  *      _bcm_esw_mod_port_tpid_delete_all
  32099  * Description:
  32100  *      Delete all TPID for a (module, port).
  32101  * Parameters:
  32102  *      unit - (IN) Device number
  32103  *      mod  - (IN) Module ID
  32104  *      port - (IN) Port number
  32105  * Return Value:
  32106  *      BCM_E_XXX
  32107  */
  32108 STATIC int
  32109 _bcm_esw_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port)
  32110 {
  32111 #ifdef BCM_HURRICANE3_SUPPORT
  32112     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  32113         return _bcm_hr3_mod_port_tpid_delete_all(unit, mod, port);
  32114     } else
  32115 #endif /* BCM_HURRICANE3_SUPPORT */
  32116 #ifdef BCM_TRIDENT_SUPPORT
  32117     {
  32118         return _bcm_td_mod_port_tpid_delete_all(unit, mod, port);
  32119     }
  32120 #endif /* BCM_TRIDENT_SUPPORT */
  32121     return BCM_E_UNAVAIL;
  32122 }
  32123 
  32124 /*
  32125  * Function:
  32126  *      bcm_esw_port_tpid_delete_all
  32127  * Description:
  32128  *      Delete all allowed TPID for a port.
  32129  * Parameters:
  32130  *      unit - (IN) Device number
  32131  *      port - (IN) Port number
  32132  * Return Value:
  32133  *      BCM_E_XXX
  32134  */
  32135 int
  32136 bcm_esw_port_tpid_delete_all(int unit, bcm_port_t port)
  32137 {
  32138     int rv = BCM_E_UNAVAIL;
  32139     bcm_module_t mod_out;
  32140     bcm_port_t port_out;
  32141     bcm_trunk_t tgid_out;
  32142     int id_out;
  32143     int is_local = 0;
  32144 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  32145     int vp = -1;
  32146 #endif
  32147 
  32148     /* Make sure port module is initialized. */
  32149     PORT_INIT(unit);
  32150 
  32151     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32152         LOG_ERROR(BSL_LS_BCM_PORT,
  32153                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32154                    port));
  32155         return BCM_E_PARAM;
  32156     }
  32157 
  32158     if (BCM_GPORT_IS_SET(port)) {
  32159         /* Handle virtual ports separetly */
  32160         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  32161             BCM_GPORT_IS_MIM_PORT(port) ||
  32162             BCM_GPORT_IS_VXLAN_PORT(port) ||
  32163             BCM_GPORT_IS_FLOW_PORT(port) ||
  32164             BCM_GPORT_IS_VLAN_PORT(port)) {
  32165 
  32166             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32167 #if defined(BCM_TRX_SUPPORT)
  32168                 PORT_LOCK(unit);
  32169                 rv = _bcm_trx_vp_tpid_delete_all(unit, port);
  32170                 PORT_UNLOCK(unit);
  32171 #endif
  32172             }
  32173             return rv;
  32174         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  32175 
  32176             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  32177                 (soc_feature(unit, soc_feature_channelized_switching))) {
  32178 #ifdef BCM_HGPROXY_COE_SUPPORT
  32179                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  32180                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32181                         &mod_out, &port_out, &tgid_out, &id_out));
  32182                     } else {
  32183                         return BCM_E_PORT;
  32184                     }
  32185 #endif
  32186              } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  32187                       soc_feature(unit, soc_feature_linkphy_coe)) {
  32188 #ifdef BCM_KATANA2_SUPPORT
  32189                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  32190                     port)) {
  32191                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32192                         &mod_out, &port_out, &tgid_out, &id_out));
  32193                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  32194                         mod_out, port_out, &port));
  32195                 } else {
  32196                     return BCM_E_PORT;
  32197                 }
  32198 #endif
  32199             } else {
  32200                 return BCM_E_PORT;
  32201             }
  32202         } else if (BCM_GPORT_IS_TRUNK(port)) {
  32203 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  32204             if (soc_feature(unit, soc_feature_vp_lag)) {
  32205                 BCM_IF_ERROR_RETURN(
  32206                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  32207                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  32208                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  32209                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32210                         PORT_LOCK(unit);
  32211                         rv = _bcm_trx_vp_tpid_delete_all(unit, port);
  32212                         PORT_UNLOCK(unit);
  32213                         return rv;
  32214                     }
  32215                 } else {
  32216                     return BCM_E_PARAM;
  32217                 }
  32218             }
  32219 #endif
  32220             return BCM_E_PARAM;
  32221         } else {
  32222             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32223                         &mod_out, &port_out, &tgid_out, &id_out));
  32224             if ((-1 != tgid_out) || (-1 != id_out)) {
  32225                 return BCM_E_PARAM;
  32226             }
  32227 
  32228             BCM_IF_ERROR_RETURN
  32229                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  32230 #if defined(BCM_HURRICANE3_SUPPORT)
  32231             /* Here only take care non-local port, the local port will
  32232              * be handled later (by _bcm_fb2_port_tpid_delete_all) */
  32233             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  32234                 if (!is_local) {
  32235                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32236                         return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  32237                                                                  port_out);
  32238                     } else {
  32239                         return BCM_E_PARAM;
  32240                     }
  32241                 } else {
  32242                     BCM_IF_ERROR_RETURN(
  32243                         bcm_esw_port_local_get(unit, port, &port));
  32244                 }
  32245             } else
  32246 #endif
  32247             {
  32248                 if (!is_local) {
  32249                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32250                         return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  32251                                                                  port_out);
  32252                     } else {
  32253                         return BCM_E_PARAM;
  32254                     }
  32255                 } else {
  32256                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32257                         BCM_IF_ERROR_RETURN
  32258                             (_bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  32259                                                                port_out));
  32260                     }
  32261                     BCM_IF_ERROR_RETURN(
  32262                         bcm_esw_port_local_get(unit, port, &port));
  32263                 }
  32264             }
  32265         }
  32266 
  32267     } else if (!SOC_PORT_VALID(unit, port)) {
  32268         return BCM_E_PORT;
  32269     }
  32270 
  32271 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  32272  || defined(BCM_RAVEN_SUPPORT)
  32273     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32274         PORT_LOCK(unit);
  32275         rv = _bcm_fb2_port_tpid_delete_all(unit, port);
  32276         PORT_UNLOCK(unit);
  32277     }
  32278 #endif
  32279     return rv;
  32280 }
  32281 
  32282 /*
  32283  * Function:
  32284  *      _bcm_esw_mod_port_inner_tpid_enable
  32285  * Description:
  32286  *      Enable the Inner Tag Protocol ID for a (module, port).
  32287  * Parameters:
  32288  *      unit - Device number
  32289  *      mod  - Module ID
  32290  *      port - Port number
  32291  * Return Value:
  32292  *      BCM_E_XXX
  32293  */
  32294 STATIC int
  32295 _bcm_esw_mod_port_inner_tpid_enable(int unit, bcm_module_t mod, bcm_port_t port)
  32296 {
  32297     int rv = BCM_E_NONE;
  32298     if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  32299         int sys_index = 0;
  32300         uint32 enable = 1;
  32301         system_config_table_entry_t systab;
  32302         sys_index = mod * 64 + port;
  32303         rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, sys_index,
  32304                                        &systab);
  32305         if (BCM_SUCCESS(rv)) {
  32306             soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab,
  32307                                                  INNER_TPID_ENABLEf, enable);
  32308             rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL,
  32309                                             sys_index, &systab);
  32310         }
  32311     } else {
  32312 #ifdef BCM_HURRICANE3_SUPPORT
  32313         if (SOC_IS_HURRICANE3(unit)) {
  32314             rv = _bcm_hr3_mod_port_inner_tpid_enable_write(unit, mod, port, 1);
  32315         }
  32316 #endif /* BCM_HURRICANE3_SUPPORT */
  32317     }
  32318     return rv;
  32319 }
  32320 
  32321 /*
  32322  * Function:
  32323  *      bcm_port_inner_tpid_set
  32324  * Purpose:
  32325  *      Set the expected TPID for the inner tag in double-tagging mode.
  32326  * Parameters:
  32327  *      unit - Device number
  32328  *      port - Port number
  32329  *      tpid - Tag Protocol ID
  32330  * Returns:
  32331  *      BCM_E_NONE - Success.
  32332  *      BCM_E_XXX
  32333  */
  32334 int
  32335 bcm_esw_port_inner_tpid_set(int unit, bcm_port_t port, uint16 tpid)
  32336 {
  32337     int rv = BCM_E_UNAVAIL;
  32338     bcm_module_t mod_out = BCM_MODID_INVALID;
  32339     bcm_port_t port_out;
  32340     bcm_trunk_t tgid_out;
  32341     int is_local = TRUE;
  32342     int id_out;
  32343 
  32344     /* Make sure port module is initialized. */
  32345     PORT_INIT(unit);
  32346 
  32347     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32348         LOG_ERROR(BSL_LS_BCM_PORT,
  32349                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32350                    port));
  32351         return BCM_E_PARAM;
  32352     }
  32353 
  32354     if (BCM_GPORT_IS_SET(port)) {
  32355         /* Handle virtual ports separetly */
  32356         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  32357             BCM_GPORT_IS_MIM_PORT(port) ||
  32358             BCM_GPORT_IS_VLAN_PORT(port)) {
  32359 
  32360             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32361 #if defined(BCM_TRX_SUPPORT)
  32362                 PORT_LOCK(unit);
  32363                 rv = _bcm_trx_vp_tpid_set(unit, port,tpid);
  32364                 PORT_UNLOCK(unit);
  32365 #endif
  32366             }
  32367             return rv;
  32368         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  32369             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  32370                 (soc_feature(unit, soc_feature_channelized_switching))) {
  32371 #ifdef BCM_HGPROXY_COE_SUPPORT
  32372                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  32373                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32374                         &mod_out, &port_out, &tgid_out, &id_out));
  32375                     BCM_IF_ERROR_RETURN(
  32376                         _bcmi_coe_subport_physical_port_get(unit,
  32377                                     port, &port));
  32378                     } else {
  32379                         return BCM_E_PORT;
  32380                     }
  32381 #endif
  32382             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  32383                 soc_feature(unit, soc_feature_linkphy_coe)) {
  32384 #ifdef BCM_KATANA2_SUPPORT
  32385                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  32386                     port)) {
  32387                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  32388                         &mod_out, &port_out, &tgid_out, &id_out));
  32389                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  32390                         mod_out, port_out, &port));
  32391                 } else {
  32392                     return BCM_E_PORT;
  32393                 }
  32394 #endif
  32395             } else {
  32396                 return BCM_E_PORT;
  32397             }
  32398         } else {
  32399             BCM_IF_ERROR_RETURN(
  32400                 _bcm_esw_gport_resolve(unit, port, &mod_out, &port_out,
  32401                                        &tgid_out, &id_out));
  32402             if ((-1 != tgid_out) || (-1 != id_out)) {
  32403                 return BCM_E_PARAM;
  32404             }
  32405             port = port_out;
  32406             BCM_IF_ERROR_RETURN(
  32407                 _bcm_esw_modid_is_local(unit, mod_out, &is_local));
  32408         }
  32409     } else if (!SOC_PORT_VALID(unit, port)) {
  32410         return BCM_E_PORT;
  32411     }
  32412 
  32413     if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
  32414         if (BCM_MODID_INVALID == mod_out) {
  32415             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out));
  32416         }
  32417         BCM_IF_ERROR_RETURN(
  32418             _bcm_esw_mod_port_inner_tpid_enable(unit, mod_out, port));
  32419 
  32420         if (TRUE == is_local) {
  32421             uint32 enable = 1;
  32422             BCM_IF_ERROR_RETURN(
  32423                 soc_mem_field32_modify(unit, PORT_TABm, port,
  32424                                        INNER_TPID_ENABLEf, enable));
  32425             if (soc_reg_field_valid(unit, EGR_VLAN_CONTROL_1r, INNER_TPID_ENABLEf)) {
  32426                 soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  32427                                        INNER_TPID_ENABLEf, enable);
  32428             }
  32429         }
  32430     } else {
  32431     /*  INNER_TPID_ENABLEf is also in SYSTEM_CONFIG_TABLE which is for Higig.
  32432          *  Hence, bypass the switched port check */
  32433 
  32434         PORT_SWITCHED_CHECK(unit, port);
  32435     }
  32436 
  32437 #ifdef BCM_FIREBOLT_SUPPORT
  32438     if (SOC_IS_FBX(unit)) {
  32439         uint32 rval;
  32440 #if 0
  32441         int tpid_index;
  32442 
  32443         for (tpid_index = 0; tpid_index < 4; tpid_index++) {
  32444             if (SOC_REG_IS_VALID(unit, PARSER1_ING_INNER_TPIDr)) {
  32445                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  32446                     PARSER1_ING_INNER_TPIDr, tpid_index, TPIDf, tpid));
  32447                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  32448                     PARSER2_ING_INNER_TPIDr, tpid_index, TPIDf, tpid));
  32449             }
  32450 
  32451             if (SOC_REG_IS_VALID(unit, EGR_INNER_TPIDr)) {
  32452                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  32453                     EGR_INNER_TPIDr, tpid_index, TPIDf, tpid));
  32454             }
  32455 
  32456             if (SOC_REG_IS_VALID(unit, EGR_PARSER_INNER_TPIDr)) {
  32457                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  32458                     EGR_PARSER_INNER_TPIDr, tpid_index, TPIDf, tpid));
  32459             }
  32460         }
  32461 #endif
  32462 
  32463         BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval));
  32464         soc_reg_field_set(unit, VLAN_CTRLr, &rval, INNER_TPIDf, tpid);
  32465         BCM_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval));
  32466         if (soc_reg_field_valid(unit, EGR_CONFIGr, INNER_TPIDf)) {
  32467             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIGr,
  32468                                 REG_PORT_ANY, INNER_TPIDf, tpid));
  32469         }
  32470 #ifdef BCM_TRIDENT3_SUPPORT
  32471         if (SOC_IS_TRIDENT3X(unit)) {
  32472             if (soc_reg_field_valid(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) {
  32473                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  32474                                     REG_PORT_ANY, INNER_TPIDf, tpid));
  32475             }
  32476         }
  32477 #endif
  32478         if (SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  32479             /*
  32480              * At now, this mac drvier is only supported by XMAC & XLMAC
  32481              * If function return BCM_E_UNAVAIL, it should be correct.
  32482              */
  32483             if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  32484                 (void)bcmi_esw_portctrl_vlan_inner_tpid_set(unit, port, tpid);
  32485             } else {
  32486                 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(
  32487                     MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  32488                                 SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID, tpid));
  32489             }
  32490         }
  32491         rv = BCM_E_NONE;
  32492     }
  32493 #endif
  32494 #if defined(BCM_MONTEREY_SUPPORT)
  32495     if (soc_feature(unit, soc_feature_obm_tpid_sync) && (rv == BCM_E_NONE)) {
  32496         bcm_inner_tpid_obm_set(unit, tpid);
  32497     }
  32498 #endif
  32499      return rv;
  32500 }
  32501 
  32502 /*
  32503  * Function:
  32504  *      bcm_port_inner_tpid_get
  32505  * Purpose:
  32506  *      Get the expected TPID for the inner tag in double-tagging mode.
  32507  * Parameters:
  32508  *      unit - Device number
  32509  *      port - Port number
  32510  *      tpid - (OUT) Tag Protocol ID
  32511  * Returns:
  32512  *      BCM_E_NONE - Success.
  32513  *      BCM_E_XXX
  32514  */
  32515 int
  32516 bcm_esw_port_inner_tpid_get(int unit, bcm_port_t port, uint16 *tpid)
  32517 {
  32518     int rv = BCM_E_UNAVAIL;
  32519 
  32520     /* Make sure port module is initialized. */
  32521     PORT_INIT(unit);
  32522 
  32523     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32524         LOG_ERROR(BSL_LS_BCM_PORT,
  32525                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32526                    port));
  32527         return BCM_E_PARAM;
  32528     }
  32529 
  32530     if (BCM_GPORT_IS_SET(port)) {
  32531         /* Handle virtual ports separetly */
  32532         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  32533             BCM_GPORT_IS_MIM_PORT(port) ||
  32534             BCM_GPORT_IS_VLAN_PORT(port)) {
  32535 
  32536             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  32537 #if defined(BCM_TRX_SUPPORT)
  32538                 PORT_LOCK(unit);
  32539                 rv = _bcm_trx_vp_tpid_get(unit, port,tpid);
  32540                 PORT_UNLOCK(unit);
  32541 #endif
  32542             }
  32543             return rv;
  32544         } else {
  32545             BCM_IF_ERROR_RETURN(
  32546                 _bcm_esw_port_gport_validate(unit, port, &port));
  32547         }
  32548 
  32549     } else if (!SOC_PORT_VALID(unit, port)) {
  32550         return BCM_E_PORT;
  32551     }
  32552 
  32553     PORT_SWITCHED_CHECK(unit, port);
  32554 
  32555     if (tpid == NULL) {
  32556         return BCM_E_PARAM;
  32557     }
  32558 
  32559 #ifdef BCM_FIREBOLT_SUPPORT
  32560     if (SOC_IS_FBX(unit)) {
  32561         uint32 rval;
  32562         BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval));
  32563         *tpid = soc_reg_field_get(unit, VLAN_CTRLr, rval, INNER_TPIDf);
  32564         return BCM_E_NONE;
  32565     }
  32566 #endif
  32567 
  32568     return BCM_E_UNAVAIL;
  32569 }
  32570 
  32571 /*
  32572  * Function:
  32573  *      bcm_esw_port_frame_max_set
  32574  * Description:
  32575  *      Set the maximum receive frame size for the port
  32576  * Parameters:
  32577  *      unit - Device number
  32578  *      in_port - Port number
  32579  *      size - Maximum frame size in bytes
  32580  * Return Value:
  32581  *      BCM_E_XXX
  32582  * Notes:
  32583  *      Depending on chip or port type the actual maximum receive frame size
  32584  *      might be slightly higher.
  32585  *
  32586  *      It looks like this operation is performed the same way on all the chips
  32587  *      and the only depends on the port type.
  32588  */
  32589 int
  32590 bcm_esw_port_frame_max_set(int unit, bcm_port_t in_port, int size)
  32591 {
  32592     bcm_port_t port;
  32593     int max_size = BCM_PORT_JUMBO_MAXSZ;
  32594 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  32595     uint32 rval;
  32596 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  32597 #if defined(BCM_KATANA2_SUPPORT)
  32598     int         min_pp_port = SOC_INFO(unit).pp_port_index_min;
  32599 #endif /* BCM_KATANA2_SUPPORT */
  32600 
  32601     /* Make sure port module is initialized. */
  32602     PORT_INIT(unit);
  32603 
  32604     if(bcm_common_oamp_port_enable_get(unit, in_port)) {
  32605         LOG_ERROR(BSL_LS_BCM_PORT,
  32606                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32607                    in_port));
  32608         return BCM_E_PARAM;
  32609     }
  32610 
  32611     /* Call Port Control module */
  32612     if (SOC_PORT_USE_PORTCTRL(unit, in_port)) {
  32613         return bcmi_esw_portctrl_frame_max_set(unit, in_port, size);
  32614     }
  32615 
  32616     /* Set jumbo max size to 12k for Katana2 as per Arch team recommendation */
  32617     max_size = SOC_INFO(unit).max_mtu;
  32618 #ifdef BCM_TRIDENT2_SUPPORT
  32619     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWKX(unit) ||
  32620         SOC_IS_HURRICANE4(unit)) {
  32621         if (IS_XE_PORT(unit, in_port) || IS_GE_PORT(unit, in_port)
  32622             || IS_CE_PORT(unit, in_port)
  32623             || (IS_C_PORT(unit, in_port) && IS_E_PORT(unit, in_port))) {
  32624             max_size -= 4;
  32625         }
  32626     }
  32627 #endif
  32628     if (size < 0 || size > max_size) {
  32629         return BCM_E_PARAM;
  32630     }
  32631 
  32632     if (!BCM_GPORT_IS_SET(in_port)) {
  32633         if (!SOC_PBMP_MEMBER((PBMP_PORT_ALL(unit)), in_port)) {
  32634             return BCM_E_PORT;
  32635         }
  32636     }
  32637     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port));
  32638 
  32639 #if defined(BCM_KATANA2_SUPPORT)
  32640     /* LinkPHY/SubportTag CoE subport does not have MAC */
  32641 #if defined(BCM_METROLITE_SUPPORT)
  32642     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  32643         soc_feature(unit, soc_feature_subtag_coe)) &&
  32644         soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  32645         (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) &&
  32646         !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) {
  32647     } else
  32648 #endif
  32649     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  32650         soc_feature(unit, soc_feature_subtag_coe)) &&
  32651         !soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  32652         (port >= min_pp_port)) {
  32653     } else
  32654 #endif
  32655     {
  32656 #ifdef BCM_HURRICANE4_SUPPORT
  32657         if (SOC_IS_HURRICANE4(unit) &&
  32658             (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)
  32659             || IS_CE_PORT(unit, port)
  32660             || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port)))) {
  32661             SOC_IF_ERROR_RETURN
  32662                 (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, (size + 4)));
  32663         } else
  32664 #endif
  32665         {
  32666             SOC_IF_ERROR_RETURN
  32667                 (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, size));
  32668         }
  32669     }
  32670 
  32671 #ifdef BCM_SHADOW_SUPPORT
  32672     if (SOC_IS_SHADOW(unit)) {
  32673         SOC_IF_ERROR_RETURN(READ_EGR_L2_MTUr(unit, port, &rval));
  32674         soc_reg_field_set(unit, EGR_L2_MTUr, &rval,
  32675                           VALUEf, size + 4);
  32676         SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval));
  32677     } else
  32678 #endif /* BCM_SHADOW_SUPPORT */
  32679 
  32680 #ifdef BCM_XGS3_SWITCH_SUPPORT
  32681     if (SOC_IS_XGS3_SWITCH(unit)) {
  32682         soc_reg_t reg;
  32683         egr_mtu_entry_t mtu;
  32684         uint32 mtu_size = size;
  32685         uint32 field_val_set = 1;
  32686 
  32687         if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)
  32688             || IS_CE_PORT(unit, port)
  32689             || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port))) {
  32690             mtu_size += 4;
  32691         }
  32692 
  32693         if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  32694             soc_mem_t mem = EGR_MTUm;
  32695             if (soc_feature(unit, soc_feature_egr_all_profile)) {
  32696                 BCM_IF_ERROR_RETURN(
  32697                     bcm_esw_port_egr_lport_field_set(unit, port, mem,
  32698                     MTU_SIZEf, mtu_size));
  32699                 
  32700             } else {
  32701                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
  32702                                                  port, &mtu));
  32703                 soc_mem_field_set (unit, mem, (uint32 *)&mtu, MTU_SIZEf,
  32704                                    &mtu_size);
  32705                 if (soc_mem_field_valid(unit, EGR_MTUm, MTU_ENABLEf)) {
  32706                     soc_mem_field_set(unit, EGR_MTUm, (uint32 *)&mtu,
  32707                                   MTU_ENABLEf, &field_val_set);
  32708                 }
  32709 
  32710                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY,
  32711                                                  port, &mtu));
  32712             }
  32713         } else {
  32714             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  32715 
  32716             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  32717             soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu_size);
  32718             if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) {
  32719                 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 1);
  32720             }
  32721             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  32722         }
  32723     }
  32724 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  32725 
  32726     return BCM_E_NONE;
  32727 }
  32728 
  32729 /*
  32730  * Function:
  32731  *      bcm_esw_port_frame_max_get
  32732  * Description:
  32733  *      Get the maximum receive frame size for the port
  32734  * Parameters:
  32735  *      unit - Device number
  32736  *      in_port - Port number
  32737  *      size - Maximum frame size in bytes
  32738  * Return Value:
  32739  *      BCM_E_XXX
  32740  * Notes:
  32741  *      Depending on chip or port type the actual maximum receive frame size
  32742  *      might be slightly higher.
  32743  *
  32744  *      For GE ports that use 2 separate MACs (one for GE and another one for
  32745  *      10/100 modes) the function returns the maximum rx frame size set for
  32746  *      the current mode.
  32747  */
  32748 int
  32749 bcm_esw_port_frame_max_get(int unit, bcm_port_t in_port, int *size)
  32750 {
  32751     int rv = BCM_E_UNAVAIL;
  32752     bcm_port_t port;
  32753 #if defined(BCM_KATANA2_SUPPORT)
  32754     uint32 rval;
  32755     int min_pp_port = SOC_INFO(unit).pp_port_index_min;
  32756     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  32757 
  32758 #if defined(BCM_SABER2_SUPPORT)
  32759     if(SOC_IS_SABER2(unit)) {
  32760         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  32761     }
  32762 #endif
  32763 #endif
  32764 
  32765     /* Make sure port module is initialized. */
  32766     PORT_INIT(unit);
  32767 
  32768     /* Call Port Control module */
  32769     if (SOC_PORT_USE_PORTCTRL(unit, in_port)) {
  32770         return bcmi_esw_portctrl_frame_max_get(unit, in_port, size);
  32771     }
  32772 
  32773 #if defined(BCM_KATANA2_SUPPORT)
  32774     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(in_port)) &&
  32775         (!((in_port >= 1) && (in_port <= max_phy_port) &&
  32776          SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),in_port)))) {
  32777           return BCM_E_PORT;
  32778     }
  32779 #endif
  32780 
  32781     if(bcm_common_oamp_port_enable_get(unit, in_port)) {
  32782         LOG_ERROR(BSL_LS_BCM_PORT,
  32783                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32784                    in_port));
  32785         return BCM_E_PARAM;
  32786     }
  32787 
  32788     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port));
  32789 
  32790 #if defined(BCM_KATANA2_SUPPORT)
  32791     /* LinkPHY/SubportTag CoE subport does not have MAC */
  32792 #if defined(BCM_METROLITE_SUPPORT)
  32793     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  32794          soc_feature(unit, soc_feature_subtag_coe)) &&
  32795          soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  32796         (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) &&
  32797          !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) {
  32798         *size = 0;
  32799         if (SOC_REG_IS_VALID(unit, EGR_MTUr)) {
  32800             SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval));
  32801             if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) {
  32802                 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4;
  32803             }
  32804         }
  32805         rv = BCM_E_NONE;
  32806     } else
  32807 #endif
  32808     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  32809         soc_feature(unit, soc_feature_subtag_coe)) &&
  32810         !soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  32811         (port >= min_pp_port)) {
  32812         *size = 0;
  32813         if (SOC_REG_IS_VALID(unit, EGR_MTUr)) {
  32814             SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval));
  32815             if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) {
  32816                 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4;
  32817             }
  32818         }
  32819         rv = BCM_E_NONE;
  32820     } else
  32821 #endif
  32822     {
  32823         rv = MAC_FRAME_MAX_GET(PORT(unit, port).p_mac, unit, port, size);
  32824 #ifdef BCM_HURRICANE4_SUPPORT
  32825         if (SOC_IS_HURRICANE4(unit) &&
  32826             (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)
  32827             || IS_CE_PORT(unit, port)
  32828             || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port)))) {
  32829             *size = *size - 4;
  32830         }
  32831 #endif
  32832     }
  32833 
  32834     return rv;
  32835 }
  32836 
  32837 /*
  32838  * Function:
  32839  *      bcm_esw_port_l3_mtu_set
  32840  * Description:
  32841  *      Set the maximum L3 frame size for the port
  32842  * Parameters:
  32843  *      unit - Device number
  32844  *      port - Port number
  32845  *      size - Maximum frame size in bytes
  32846  * Return Value:
  32847  *      BCM_E_XXX
  32848  */
  32849 int
  32850 bcm_esw_port_l3_mtu_set(int unit, bcm_port_t port, int size)
  32851 {
  32852     int rv = BCM_E_UNAVAIL;
  32853 
  32854     /* Make sure port module is initialized. */
  32855     PORT_INIT(unit);
  32856 
  32857     COMPILER_REFERENCE(rv);
  32858 
  32859     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32860         LOG_ERROR(BSL_LS_BCM_PORT,
  32861                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32862                    port));
  32863         return BCM_E_PARAM;
  32864     }
  32865 
  32866 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  32867 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  32868     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  32869 
  32870         int encap_bytes = 0;
  32871         soc_info_t *si = &SOC_INFO(unit);
  32872         soc_field_t fields[2];
  32873         uint32 values[2];
  32874 
  32875         if (soc_feature(unit, soc_feature_egr_all_profile) ||
  32876             (((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) ||
  32877              (soc_feature(unit, soc_feature_channelized_switching))) &&
  32878               _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
  32879 
  32880 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT)
  32881             if (soc_feature(unit, soc_feature_channelized_switching)) {
  32882 
  32883                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  32884                     encap_bytes = 4;
  32885                 } else {
  32886                     if (BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) {
  32887                         encap_bytes = 4;
  32888 
  32889                     }
  32890                 }
  32891             }
  32892 #endif
  32893 
  32894             if ((size + encap_bytes) > si->max_mtu) {
  32895 
  32896                 LOG_ERROR(BSL_LS_BCM_PORT,
  32897                     (BSL_META("MTU (%d) more than max mtu (%d) .\n"),
  32898                     (size + encap_bytes), si->max_mtu));
  32899 
  32900                 if (encap_bytes) {
  32901                     LOG_ERROR(
  32902                         BSL_LS_BCM_PORT,
  32903                         (BSL_META_U(unit,
  32904                                 "For CoE port 0x%x, extra 4 bytes are added "
  32905                                 "to user provided MTU to account for SVTAG \n"),
  32906                          port));
  32907                 }
  32908 
  32909                 return BCM_E_PARAM;
  32910             }
  32911 
  32912             /* Add extra encap bytes on port. */
  32913             size += encap_bytes;
  32914 
  32915             /* Setup the fields and their values */
  32916             fields[0] = MTU_SIZEf;  values[0] = size;
  32917             fields[1] = MTU_ENABLEf; values[1] = 1;
  32918 
  32919             return bcm_esw_port_egr_lport_fields_set(unit, port,
  32920                         EGR_MTUm, 2, fields, values);
  32921 
  32922         } else {
  32923             egr_mtu_entry_t egr_mtu_entry;
  32924 
  32925             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32926             SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm,
  32927                             MEM_BLOCK_ANY, port, &egr_mtu_entry));
  32928             /* Set up the fields */
  32929             soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_SIZEf, size);
  32930             soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_ENABLEf,
  32931                                 1);
  32932             /* Write data to hardware */
  32933             return soc_mem_write(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &egr_mtu_entry);
  32934         }
  32935     } else
  32936 #endif
  32937     {
  32938         if (soc_feature(unit, soc_feature_egr_l3_mtu)) {
  32939             soc_reg_t reg;
  32940 
  32941             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32942             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  32943             return soc_reg_field32_modify(unit, reg, port,
  32944                     (SOC_REG_FIELD_VALID(unit, reg, L3_MTU_SIZEf) ?
  32945                     L3_MTU_SIZEf : MTU_SIZEf), size);
  32946         }
  32947     }
  32948 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  32949 
  32950     return BCM_E_UNAVAIL;
  32951 
  32952 }
  32953 
  32954 /*
  32955  * Function:
  32956  *      bcm_esw_port_l3_mtu_get
  32957  * Description:
  32958  *      Get the maximum L3 frame size for the port
  32959  * Parameters:
  32960  *      unit - Device number
  32961  *      port - Port number
  32962  *      size - Maximum frame size in bytes
  32963  * Return Value:
  32964  *      BCM_E_XXX
  32965  */
  32966 int
  32967 bcm_esw_port_l3_mtu_get(int unit, bcm_port_t port, int *size)
  32968 {
  32969     /* Make sure port module is initialized. */
  32970     PORT_INIT(unit);
  32971 
  32972     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32973         LOG_ERROR(BSL_LS_BCM_PORT,
  32974                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32975                    port));
  32976         return BCM_E_PARAM;
  32977     }
  32978 
  32979 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  32980 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  32981     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  32982        if (soc_feature(unit, soc_feature_egr_all_profile) ||
  32983            ((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) &&
  32984                 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
  32985 
  32986             int rv = BCM_E_NONE;
  32987 
  32988             rv =  bcm_esw_port_egr_lport_field_get(unit, port,
  32989                     EGR_MTUm, MTU_SIZEf, (uint32*)size);
  32990 
  32991 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT)
  32992             if (BCM_SUCCESS(rv)) {
  32993                 if (soc_feature(unit, soc_feature_channelized_switching)) {
  32994                     soc_info_t *si = &SOC_INFO(unit);
  32995 
  32996                     if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  32997                         *size -= 4;
  32998                     } else {
  32999                         if (BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) {
  33000                             *size -= 4;
  33001                         }
  33002                     }
  33003                 }
  33004             }
  33005 #endif
  33006             return rv;
  33007 
  33008         } else {
  33009             egr_mtu_entry_t entry;
  33010 
  33011             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33012             SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &entry));
  33013             *size = soc_mem_field32_get(unit, EGR_MTUm, &entry, MTU_SIZEf);
  33014             return BCM_E_NONE;
  33015         }
  33016     } else
  33017 #endif
  33018     {
  33019         if (soc_feature(unit, soc_feature_egr_l3_mtu)) {
  33020             soc_reg_t reg;
  33021             uint32 rval;
  33022 
  33023             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33024 
  33025             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  33026 
  33027             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  33028             *size = soc_reg_field_get(unit, reg, rval,
  33029                     (SOC_REG_FIELD_VALID(unit, reg,L3_MTU_SIZEf) ?
  33030                      L3_MTU_SIZEf : MTU_SIZEf));
  33031             return BCM_E_NONE;
  33032         }
  33033     }
  33034 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  33035 
  33036     return BCM_E_UNAVAIL;
  33037 }
  33038 
  33039 #ifdef BCM_WARM_BOOT_SUPPORT
  33040 /*
  33041  * Function:
  33042  *     _bcm_esw_port_ipg_ifg_wb_set
  33043  * Purpose:
  33044  *     Restore the ifg based on the working speed and duplex
  33045  */
  33046 STATIC int
  33047 _bcm_esw_port_ipg_ifg_wb_set(
  33048     int unit,
  33049     bcm_port_t port,
  33050     soc_ipg_t *ipg,
  33051     uint32 ifg)
  33052 {
  33053     int speed, duplex;
  33054 
  33055     if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  33056         /* XLMAC or CLMAC */
  33057         ipg->fd_xe = ifg;
  33058     } else {
  33059         /* UNIMAC */
  33060         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33061             BCM_IF_ERROR_RETURN
  33062                     (bcm_esw_port_speed_get(unit, port, &speed));
  33063             BCM_IF_ERROR_RETURN
  33064                     (bcm_esw_port_duplex_get(unit, port, &duplex));
  33065         } else {
  33066             BCM_IF_ERROR_RETURN(
  33067                 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed));
  33068             BCM_IF_ERROR_RETURN(
  33069                 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex));
  33070         }
  33071         if (duplex == BCM_PORT_DUPLEX_FULL) {
  33072             switch (speed) {
  33073                 case 10:
  33074                     ipg->fd_10 = ifg;
  33075                     break;
  33076                 case 100:
  33077                     ipg->fd_100 = ifg;
  33078                     break;
  33079                 case 1000:
  33080                     ipg->fd_1000 = ifg;
  33081                     break;
  33082                 case 2500:
  33083                     ipg->fd_2500 = ifg;
  33084                     break;
  33085                 default:
  33086                     return BCM_E_PARAM;
  33087             }
  33088         } else {
  33089             switch (speed) {
  33090                 case 10:
  33091                     ipg->hd_10 = ifg;
  33092                     break;
  33093                 case 100:
  33094                     ipg->hd_100 = ifg;
  33095                     break;
  33096                 default:
  33097                     return BCM_E_PARAM;
  33098             }
  33099         }
  33100     }
  33101     return BCM_E_NONE;
  33102 }
  33103 
  33104 /*
  33105  * Function:
  33106  *     _bcm_esw_port_ipg_ifg_wb_get
  33107  * Purpose:
  33108  *     Get the ifg based on the working speed and duplex
  33109  */
  33110 STATIC int
  33111 _bcm_esw_port_ipg_ifg_wb_get(
  33112     int unit,
  33113     bcm_port_t port,
  33114     soc_ipg_t *ipg,
  33115     uint32 *ifg)
  33116 {
  33117     int speed, duplex;
  33118 
  33119     if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  33120         /* XLMAC or CLMAC */
  33121         *ifg = ipg->fd_xe;
  33122     } else {
  33123         /* UNIMAC */
  33124         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33125             BCM_IF_ERROR_RETURN
  33126                     (bcm_esw_port_speed_get(unit, port, &speed));
  33127             BCM_IF_ERROR_RETURN
  33128                     (bcm_esw_port_duplex_get(unit, port, &duplex));
  33129         } else {
  33130             BCM_IF_ERROR_RETURN(
  33131                 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed));
  33132             BCM_IF_ERROR_RETURN(
  33133                 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex));
  33134         }
  33135         if (duplex == BCM_PORT_DUPLEX_FULL) {
  33136             switch (speed) {
  33137                 case 10:
  33138                     *ifg = ipg->fd_10;
  33139                     break;
  33140                 case 100:
  33141                     *ifg = ipg->fd_100;
  33142                     break;
  33143                 case 1000:
  33144                     *ifg = ipg->fd_1000;
  33145                     break;
  33146                 case 2500:
  33147                     *ifg = ipg->fd_2500;
  33148                     break;
  33149                 default:
  33150                     return BCM_E_PARAM;
  33151             }
  33152         } else {
  33153             switch (speed) {
  33154                 case 10:
  33155                     *ifg = ipg->hd_10;
  33156                     break;
  33157                 case 100:
  33158                     *ifg = ipg->hd_100;
  33159                     break;
  33160                 default:
  33161                     return BCM_E_PARAM;
  33162             }
  33163         }
  33164     }
  33165     return BCM_E_NONE;
  33166 }
  33167 
  33168 /*
  33169  * Function:
  33170  *     _bcm_esw_port_ifg_wb_sync
  33171  * Purpose:
  33172  *     Sync port_ifg DB to scache.
  33173  * Parameters:
  33174  *     unit - Device unit number
  33175  *     scache_ptr - Scache pointer.
  33176  * Returns:
  33177  *     BCM_E_XXX
  33178  */
  33179 STATIC int
  33180 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr)
  33181 {
  33182     bcm_port_t  port;
  33183     soc_ipg_t   *si = NULL;
  33184     uint32      ifg = 0;
  33185     int         mode = 0;
  33186     int         rv = BCM_E_NONE;
  33187 
  33188     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  33189         return BCM_E_PARAM;
  33190     }
  33191 
  33192     PBMP_ALL_ITER(unit, port) {
  33193         si = &SOC_PERSIST(unit)->ipg[port];
  33194         if (IS_E_PORT(unit, port)) {
  33195             if (soc_feature(unit, soc_feature_ifg_wb_include_unimac) ||
  33196                                             IS_EGPHY_PORT(unit, port)) {
  33197                 BCM_IF_ERROR_RETURN(
  33198                     _bcm_esw_port_ipg_ifg_wb_get(unit, port, si, &ifg));
  33199             } else {
  33200                 ifg = si->fd_xe;
  33201             }
  33202         } else {
  33203             if (soc_feature(unit, soc_feature_xmac)) {
  33204                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  33205                 if (BCM_E_NONE == rv) {
  33206                     if (BCM_PORT_ENCAP_HIGIG2 == mode) {
  33207                         ifg = si->fd_hg2;
  33208                     } else {
  33209                         ifg = si->fd_hg;
  33210                     }
  33211                 }
  33212             } else {
  33213                 ifg = si->fd_hg;
  33214             }
  33215         }
  33216         sal_memcpy(*scache_ptr, &ifg, sizeof(uint32));
  33217         *scache_ptr += sizeof(uint32);
  33218 
  33219         rv = _scache_port_print_add(unit, port, SPT_IFG, sizeof(uint32),
  33220                 *scache_ptr - sizeof(uint32));
  33221         if (BCM_FAILURE(rv)) {
  33222             return rv;
  33223         }
  33224     }
  33225 
  33226     return BCM_E_NONE;
  33227 }
  33228 
  33229 /*
  33230  * Function:
  33231  *     _bcm_esw_port_ifg_wb_reinit
  33232  * Purpose:
  33233  *     Retrieve port_ifg from scache.
  33234  * Parameters:
  33235  *     unit - Device unit number
  33236  *     scache_ptr - Scache pointer.
  33237  * Returns:
  33238  *     BCM_E_XXX
  33239  */
  33240 STATIC int
  33241 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr)
  33242 {
  33243     bcm_port_t  port;
  33244     soc_ipg_t   *si = NULL;
  33245     uint32      ifg = 0;
  33246     int         mode = 0;
  33247     int         rv = BCM_E_NONE;
  33248 
  33249     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  33250         return BCM_E_PARAM;
  33251     }
  33252 
  33253     PBMP_ALL_ITER(unit, port) {
  33254         si = &SOC_PERSIST(unit)->ipg[port];
  33255         sal_memcpy(&ifg, *scache_ptr, sizeof(uint32));
  33256         if (IS_E_PORT(unit, port)) {
  33257             if (soc_feature(unit, soc_feature_ifg_wb_include_unimac) ||
  33258                                             IS_EGPHY_PORT(unit, port)) {
  33259                 BCM_IF_ERROR_RETURN(
  33260                     _bcm_esw_port_ipg_ifg_wb_set(unit, port, si, ifg));
  33261             } else {
  33262                 si->fd_xe = ifg;
  33263             }
  33264         } else {
  33265             if (soc_feature(unit, soc_feature_xmac)) {
  33266                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  33267                 if (BCM_E_NONE == rv) {
  33268                     if (BCM_PORT_ENCAP_HIGIG2 == mode) {
  33269                         si->fd_hg2 = ifg;
  33270                     } else {
  33271                         si->fd_hg = ifg;
  33272                     }
  33273                 }
  33274             } else {
  33275                 si->fd_hg = ifg;
  33276             }
  33277         }
  33278         *scache_ptr += sizeof(uint32);
  33279 
  33280         rv = _scache_port_print_add(unit, port, SPT_IFG, sizeof(uint32),
  33281                 *scache_ptr - sizeof(uint32));
  33282         if (BCM_FAILURE(rv)) {
  33283             return rv;
  33284         }
  33285     }
  33286 
  33287     return BCM_E_NONE;
  33288 }
  33289 #endif
  33290 
  33291 /*
  33292  * Function:
  33293  *      bcm_esw_port_ifg_set
  33294  * Description:
  33295  *      Sets the new ifg (Inter-frame gap) value
  33296  * Parameters:
  33297  *      unit   - Device number
  33298  *      port   - Port number
  33299  *      speed  - the speed for which the IFG is being set
  33300  *      duplex - the duplex for which the IFG is being set
  33301  *      ifg    - Inter-frame gap in bit-times
  33302  * Return Value:
  33303  *      BCM_E_XXX
  33304  * Notes:
  33305  *      The function makes sure the IFG value makes sense and updates the
  33306  *      IPG register in case the speed/duplex match the current settings
  33307  */
  33308 int
  33309 bcm_esw_port_ifg_set(int unit, bcm_port_t port,
  33310                  int speed, bcm_port_duplex_t duplex,
  33311                  int ifg)
  33312 {
  33313 
  33314     /* Make sure port module is initialized. */
  33315     PORT_INIT(unit);
  33316 
  33317     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33318         return bcmi_esw_portctrl_ifg_set(unit, port, speed, duplex, ifg);
  33319     }
  33320 
  33321     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33322         LOG_ERROR(BSL_LS_BCM_PORT,
  33323                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33324                    port));
  33325         return BCM_E_PARAM;
  33326     }
  33327 
  33328     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33329 
  33330     return MAC_IFG_SET(PORT(unit, port).p_mac, unit, port,
  33331                        speed, duplex, ifg);
  33332 }
  33333 
  33334 /*
  33335  * Function:
  33336  *      bcm_port_ifg_get
  33337  * Description:
  33338  *      Gets the new ifg (Inter-frame gap) value
  33339  * Parameters:
  33340  *      unit   - Device number
  33341  *      port   - Port number
  33342  *      speed  - the speed for which the IFG is being set
  33343  *      duplex - the duplex for which the IFG is being set
  33344  *      ifg    - Inter-frame gap in bit-times
  33345  * Return Value:
  33346  *      BCM_E_XXX
  33347  * Notes:
  33348  */
  33349 int
  33350 bcm_esw_port_ifg_get(int unit, bcm_port_t port,
  33351                  int speed, bcm_port_duplex_t duplex,
  33352                  int *ifg)
  33353 {
  33354     /* Make sure port module is initialized. */
  33355     PORT_INIT(unit);
  33356 
  33357     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33358         return bcmi_esw_portctrl_ifg_get(unit, port, speed, duplex, ifg);
  33359     }
  33360 
  33361     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33362         LOG_ERROR(BSL_LS_BCM_PORT,
  33363                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33364                    port));
  33365         return BCM_E_PARAM;
  33366     }
  33367 
  33368     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33369 
  33370     return MAC_IFG_GET(PORT(unit, port).p_mac, unit, port,
  33371                        speed, duplex, ifg);
  33372 }
  33373 
  33374 /*
  33375  * Function:
  33376  *      bcm_port_phy_get
  33377  * Description:
  33378  *      General PHY register read
  33379  * Parameters:
  33380  *      unit - Device number
  33381  *      port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  33382  *      flags - Logical OR of one or more of the following flags:
  33383  *              BCM_PORT_PHY_INTERNAL
  33384  *                      Address internal SERDES PHY for port
  33385  *              BCM_PORT_PHY_NOMAP
  33386  *                      Instead of mapping port to PHY MDIO address,
  33387  *                      treat port parameter as actual PHY MDIO address.
  33388  *              BCM_PORT_PHY_CLAUSE45
  33389  *                      Assume Clause 45 device instead of Clause 22
  33390  *      phy_addr - PHY internal register address
  33391  *      phy_data - (OUT) Data that was read
  33392  * Returns:
  33393  *      BCM_E_XXX
  33394  */
  33395 int
  33396 bcm_esw_port_phy_get(int unit, bcm_port_t port, uint32 flags,
  33397                  uint32 phy_reg_addr, uint32 *phy_data)
  33398 {
  33399     uint16  phy_id;
  33400     uint8  phy_devad;
  33401     uint16 phy_reg;
  33402     uint16 phy_rd_data;
  33403     uint32 reg_flag;
  33404     int    rv;
  33405     int lane = -1;
  33406     int phyn = -1, sys_side = 0;
  33407     bcm_port_t local_port = -1;
  33408 
  33409     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33410         return bcmi_esw_portctrl_phy_get(unit, port, flags, phy_reg_addr,
  33411                                          phy_data);
  33412     }
  33413 
  33414     /* Make sure port module is initialized. */
  33415     PORT_INIT(unit);
  33416 
  33417     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33418         LOG_ERROR(BSL_LS_BCM_PORT,
  33419                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33420                    port));
  33421         return BCM_E_PARAM;
  33422     }
  33423 
  33424     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  33425         BCM_IF_ERROR_RETURN
  33426             (_bcm_esw_port_gport_phyn_validate(unit, port,
  33427                                            &local_port, &phyn,
  33428                                            &lane, &sys_side));
  33429         if (local_port != -1) {
  33430             port = local_port;
  33431         }
  33432         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33433 
  33434         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  33435             return BCM_E_PORT;
  33436         }
  33437     }
  33438 
  33439     if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) {
  33440         PORT_LOCK(unit);
  33441         rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data);
  33442         PORT_UNLOCK(unit);
  33443         return rv;
  33444     }
  33445 
  33446     rv       = BCM_E_UNAVAIL;
  33447     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  33448     if ( (reg_flag & SOC_PHY_REG_INDIRECT) ||
  33449          (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) {
  33450         if (flags & BCM_PORT_PHY_NOMAP) {
  33451             /* Indirect register access is performed through PHY driver.
  33452              * Therefore, indirect register access is not supported if
  33453              * BCM_PORT_PHY_NOMAP flag is set.
  33454              */
  33455             return BCM_E_PARAM;
  33456         }
  33457         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  33458 
  33459         if (lane >= 0) {
  33460 #if defined(PHYMOD_SUPPORT)
  33461             SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane);
  33462 #endif
  33463         }
  33464         if (phyn == 1) {
  33465             flags |= SOC_PHY_INTERNAL;
  33466         }
  33467         PORT_LOCK(unit);
  33468         rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data);
  33469         PORT_UNLOCK(unit);
  33470     }
  33471 
  33472     if (rv == BCM_E_UNAVAIL) {
  33473         if (flags & BCM_PORT_PHY_NOMAP) {
  33474             phy_id = port;
  33475         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  33476             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  33477         } else {
  33478             phy_id = PORT_TO_PHY_ADDR(unit, port);
  33479         }
  33480 
  33481         PORT_LOCK(unit);
  33482         if (flags & BCM_PORT_PHY_CLAUSE45) {
  33483             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  33484             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  33485             rv = soc_miimc45_read(unit, phy_id, phy_devad,
  33486                                   phy_reg, &phy_rd_data);
  33487 
  33488         } else {
  33489             phy_reg = phy_reg_addr;
  33490             rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data);
  33491         }
  33492         PORT_UNLOCK(unit);
  33493 
  33494         if (BCM_SUCCESS(rv)) {
  33495            *phy_data = phy_rd_data;
  33496         }
  33497     }
  33498 
  33499     LOG_INFO(BSL_LS_BCM_PORT,
  33500              (BSL_META_U(unit,
  33501                          "bcm_esw_port_phy_get: u=%d p=%d flags=0x%08x "
  33502                          "phy_reg=0x%08x, phy_data=0x%08x, rv=%d\n"),
  33503               unit, port, flags, phy_reg_addr, *phy_data, rv));
  33504 
  33505     return rv;
  33506 }
  33507 
  33508 /*
  33509  * Function:
  33510  *      bcm_port_phy_set
  33511  * Description:
  33512  *      General PHY register write
  33513  * Parameters:
  33514  *      unit - Device number
  33515  *      port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  33516  *      flags - Logical OR of one or more of the following flags:
  33517  *              BCM_PORT_PHY_INTERNAL
  33518  *                      Address internal SERDES PHY for port
  33519  *              BCM_PORT_PHY_NOMAP
  33520  *                      Instead of mapping port to PHY MDIO address,
  33521  *                      treat port parameter as actual PHY MDIO address.
  33522  *              BCM_PORT_PHY_CLAUSE45
  33523  *                      Assume Clause 45 device instead of Clause 22
  33524  *              BCM_PORT_PHY_BROADCAST_WRITE
  33525  *                      Broadcast write transactions to all MDIO buses
  33526  *                      within one unit. All the ports that have the same
  33527  *                      phy address as the specified port will receive
  33528  *                      the write command.
  33529  *      phy_addr - PHY internal register address
  33530  *      phy_data - Data to write
  33531  * Returns:
  33532  *      BCM_E_XXX
  33533  */
  33534 int
  33535 bcm_esw_port_phy_set(int unit, bcm_port_t port, uint32 flags,
  33536                  uint32 phy_reg_addr, uint32 phy_data)
  33537 {
  33538     uint16 phy_id;
  33539     uint8  phy_devad;
  33540     uint16 phy_reg;
  33541     uint16 phy_wr_data;
  33542     uint32 reg_flag;
  33543     int    rv;
  33544     int lane = -1;
  33545     int phyn = -1, sys_side = 0;
  33546     bcm_port_t local_port = -1;
  33547 
  33548     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33549         return bcmi_esw_portctrl_phy_set(unit, port, flags, phy_reg_addr,
  33550                                          phy_data);
  33551     }
  33552 
  33553     /* Make sure port module is initialized. */
  33554     PORT_INIT(unit);
  33555 
  33556     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33557         LOG_ERROR(BSL_LS_BCM_PORT,
  33558                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33559                    port));
  33560         return BCM_E_PARAM;
  33561     }
  33562 
  33563     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  33564         BCM_IF_ERROR_RETURN
  33565             (_bcm_esw_port_gport_phyn_validate(unit, port,
  33566                                            &local_port, &phyn,
  33567                                            &lane, &sys_side));
  33568         if (local_port != -1) {
  33569             port = local_port;
  33570         }
  33571         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33572 
  33573         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  33574             return BCM_E_PORT;
  33575         }
  33576     }
  33577 
  33578     LOG_INFO(BSL_LS_BCM_PORT,
  33579              (BSL_META_U(unit,
  33580                          "bcm_esw_port_phy_set: u=%d p=%d flags=0x%08x "
  33581                          "phy_reg=0x%08x phy_data=0x%08x\n"),
  33582               unit, port, flags, phy_reg_addr, phy_data));
  33583 
  33584     if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) {
  33585         PORT_LOCK(unit);
  33586         rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data);
  33587         PORT_UNLOCK(unit);
  33588         return rv;
  33589     }
  33590 
  33591     rv       = BCM_E_UNAVAIL;
  33592     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  33593     if ( (reg_flag & SOC_PHY_REG_INDIRECT) ||
  33594          (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) {
  33595         if (flags & BCM_PORT_PHY_NOMAP) {
  33596             /* Indirect register access is performed through PHY driver.
  33597              * Therefore, indirect register access is not supported if
  33598              * BCM_PORT_PHY_NOMAP flag is set.
  33599              */
  33600             return BCM_E_PARAM;
  33601         }
  33602         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  33603         if (lane >= 0) {
  33604 #if defined(PHYMOD_SUPPORT)
  33605             SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane);
  33606 #endif
  33607         }
  33608         if (phyn == 1) {
  33609             flags |= SOC_PHY_INTERNAL;
  33610         }
  33611         PORT_LOCK(unit);
  33612         rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data);
  33613         PORT_UNLOCK(unit);
  33614     }
  33615 
  33616     if (rv == BCM_E_UNAVAIL) {
  33617         if (flags & BCM_PORT_PHY_NOMAP) {
  33618             phy_id = port;
  33619         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  33620             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  33621         } else {
  33622             phy_id = PORT_TO_PHY_ADDR(unit, port);
  33623         }
  33624 
  33625         if (flags & BCM_PORT_PHY_BROADCAST_WRITE) {
  33626             phy_id |= 0x400;
  33627         }
  33628 
  33629         phy_wr_data = (uint16) (phy_data & 0xffff);
  33630         PORT_LOCK(unit);
  33631         if (flags & BCM_PORT_PHY_CLAUSE45) {
  33632             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  33633             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  33634             rv = soc_miimc45_write(unit, phy_id, phy_devad,
  33635                                    phy_reg, phy_wr_data);
  33636         } else {
  33637             phy_reg = phy_reg_addr;
  33638             rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data);
  33639         }
  33640         PORT_UNLOCK(unit);
  33641     }
  33642     return rv;
  33643 }
  33644 /*
  33645  * Function:
  33646  *      bcm_port_phy_multi_get
  33647  * Description:
  33648  *      General PHY register read
  33649  * Parameters:
  33650  *      unit - Device number
  33651  *      port - Port number
  33652  *      flags - TBD
  33653  *      dev_addr - Device address on the PHY's bus (ex. I2C addr)
  33654  *      offset - Offset within device
  33655  *      max_size - Requested data size
  33656  *      data - Data buffer
  33657  *      actual_size - Received data size
  33658  * Returns:
  33659  *      BCM_E_XXX
  33660  */
  33661 int
  33662 bcm_esw_port_phy_multi_get(int unit, bcm_port_t port, uint32 flags,
  33663                  uint32 dev_addr, uint32 offset, int max_size, uint8 *data, int *actual_size)
  33664 {
  33665     int rv;
  33666 
  33667     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33668         return bcmi_esw_portctrl_phy_multi_get(unit, port, flags, dev_addr,
  33669                                                offset, max_size, data,
  33670                                                actual_size);
  33671     }
  33672 
  33673     /* Make sure port module is initialized. */
  33674     PORT_INIT(unit);
  33675 
  33676     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33677         LOG_ERROR(BSL_LS_BCM_PORT,
  33678                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33679                    port));
  33680         return BCM_E_PARAM;
  33681     }
  33682 
  33683     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33684 
  33685     PORT_LOCK(unit);
  33686     rv = soc_phyctrl_port_phy_multi_get(unit, port, flags, dev_addr, offset, max_size, data, actual_size);
  33687     PORT_UNLOCK(unit);
  33688     /*
  33689     LOG_INFO(BSL_LS_BCM_PORT,
  33690              (BSL_META_U(unit,
  33691                          "bcm_esw_port_phy_multi_get: u=%d p=%d flags=0x%08x "
  33692                          "dev_addr=0x%08x, offset=0x%08x, max_size=%d data=%p actual_size=%d rv=%d\n"),
  33693               unit, port, flags, dev_addr, offset, max_size, data, *actual_size, rv));
  33694     */
  33695     return rv;
  33696 }
  33697 
  33698 /*
  33699  * Function:
  33700  *      bcm_port_phy_modify
  33701  * Description:
  33702  *      General PHY register modify
  33703  * Parameters:
  33704  *      unit - Device number
  33705  *      port - Port number  or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  33706  *      flags - Logical OR of one or more of the following flags:
  33707  *              BCM_PORT_PHY_INTERNAL
  33708  *                      Address internal SERDES PHY for port
  33709  *              BCM_PORT_PHY_NOMAP
  33710  *                      Instead of mapping port to PHY MDIO address,
  33711  *                      treat port parameter as actual PHY MDIO address.
  33712  *              BCM_PORT_PHY_CLAUSE45
  33713  *                      Assume Clause 45 device instead of Clause 22
  33714  *      phy_addr - PHY internal register address
  33715  *      phy_data - Data to write
  33716  *      phy_mask - Bits to modify using phy_data
  33717  * Returns:
  33718  *      BCM_E_XXX
  33719  */
  33720 int
  33721 bcm_esw_port_phy_modify(int unit, bcm_port_t port, uint32 flags,
  33722                         uint32 phy_reg_addr, uint32 phy_data, uint32 phy_mask)
  33723 {
  33724     uint16 phy_id;
  33725     uint8  phy_devad;
  33726     uint16 phy_reg;
  33727     uint16 phy_rd_data;
  33728     uint16 phy_wr_data;
  33729     uint32 reg_flag;
  33730     int    rv;
  33731     int lane = -1;
  33732     int phyn = -1, sys_side = 0;
  33733     bcm_port_t local_port = -1;
  33734 
  33735     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33736         return bcmi_esw_portctrl_phy_modify(unit, port, flags, phy_reg_addr,
  33737                                             phy_data, phy_mask);
  33738     }
  33739 
  33740     /* Make sure port module is initialized. */
  33741     PORT_INIT(unit);
  33742 
  33743     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33744         LOG_ERROR(BSL_LS_BCM_PORT,
  33745                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33746                    port));
  33747         return BCM_E_PARAM;
  33748     }
  33749 
  33750     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  33751         BCM_IF_ERROR_RETURN
  33752             (_bcm_esw_port_gport_phyn_validate(unit, port,
  33753                                            &local_port, &phyn,
  33754                                            &lane, &sys_side));
  33755         if (local_port != -1) {
  33756             port = local_port;
  33757         }
  33758         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33759 
  33760         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  33761             return BCM_E_PORT;
  33762         }
  33763     }
  33764 
  33765     LOG_INFO(BSL_LS_BCM_PORT,
  33766              (BSL_META_U(unit,
  33767                          "bcm_esw_port_phy_modify: u=%d p=%d flags=0x%08x "
  33768                          "phy_reg=0x%08x phy_data=0x%08x phy_mask=0x%08x\n"),
  33769               unit, port, flags, phy_reg_addr, phy_data, phy_mask));
  33770 
  33771     rv       = BCM_E_UNAVAIL;
  33772     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  33773     if (reg_flag & SOC_PHY_REG_INDIRECT) {
  33774         if (flags & BCM_PORT_PHY_NOMAP) {
  33775             /* Indirect register access is performed through PHY driver.
  33776              * Therefore, indirect register access is not supported if
  33777              * BCM_PORT_PHY_NOMAP flag is set.
  33778              */
  33779             return BCM_E_PARAM;
  33780         }
  33781         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  33782         if (lane >= 0) {
  33783 #if defined(PHYMOD_SUPPORT)
  33784            SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane);
  33785 #endif
  33786         }
  33787         if (phyn == 1) {
  33788             flags |= SOC_PHY_INTERNAL;
  33789         }
  33790         PORT_LOCK(unit);
  33791         rv = soc_phyctrl_reg_modify(unit, port, flags, phy_reg_addr,
  33792                                     phy_data, phy_mask);
  33793         PORT_UNLOCK(unit);
  33794     }
  33795 
  33796     if (rv == BCM_E_UNAVAIL) {
  33797         if (flags & BCM_PORT_PHY_NOMAP) {
  33798             phy_id = port;
  33799         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  33800             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  33801         } else {
  33802             phy_id = PORT_TO_PHY_ADDR(unit, port);
  33803         }
  33804 
  33805         phy_wr_data = (uint16) (phy_data & phy_mask & 0xffff);
  33806         PORT_LOCK(unit);
  33807         if (flags & BCM_PORT_PHY_CLAUSE45) {
  33808             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  33809             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  33810             rv = soc_miimc45_read(unit, phy_id, phy_devad,
  33811                                   phy_reg, &phy_rd_data);
  33812             phy_wr_data |= (phy_rd_data & ~phy_mask);
  33813             rv = soc_miimc45_write(unit, phy_id, phy_devad,
  33814                                    phy_reg, phy_wr_data);
  33815         } else {
  33816             phy_reg = phy_reg_addr;
  33817             rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data);
  33818             if (BCM_SUCCESS(rv)) {
  33819                 phy_wr_data |= (phy_rd_data & ~phy_mask);
  33820                 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data);
  33821             }
  33822         }
  33823         PORT_UNLOCK(unit);
  33824     }
  33825     return rv;
  33826 }
  33827 
  33828 /*
  33829  * Function:
  33830  *      bcm_port_mdix_set
  33831  * Description:
  33832  *      Set the Auto-MDIX mode of a port/PHY
  33833  * Parameters:
  33834  *      unit - Device number
  33835  *      port - Port number
  33836  *      mode - One of:
  33837  *              BCM_PORT_MDIX_AUTO
  33838  *                      Enable auto-MDIX when autonegotiation is enabled
  33839  *              BCM_PORT_MDIX_FORCE_AUTO
  33840  *                      Enable auto-MDIX always
  33841  *              BCM_PORT_MDIX_NORMAL
  33842  *                      Disable auto-MDIX
  33843  *              BCM_PORT_MDIX_XOVER
  33844  *                      Disable auto-MDIX, and swap cable pairs
  33845  * Return Value:
  33846  *      BCM_E_UNAVAIL - feature unsupported by hardware
  33847  *      BCM_E_XXX - other error
  33848  */
  33849 int
  33850 bcm_esw_port_mdix_set(int unit, bcm_port_t port, bcm_port_mdix_t mode)
  33851 {
  33852     int rv;
  33853 
  33854     /* Make sure port module is initialized. */
  33855     PORT_INIT(unit);
  33856 
  33857     /* Call Port Control module */
  33858     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33859         return bcmi_esw_portctrl_mdix_set(unit, port, mode);
  33860     }
  33861 
  33862     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33863         LOG_ERROR(BSL_LS_BCM_PORT,
  33864                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33865                    port));
  33866         return BCM_E_PARAM;
  33867     }
  33868 
  33869     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33870 
  33871     PORT_LOCK(unit);
  33872     rv = soc_phyctrl_mdix_set(unit, port, mode);
  33873     PORT_UNLOCK(unit);
  33874     return rv;
  33875 }
  33876 
  33877 /*
  33878  * Function:
  33879  *      bcm_port_mdix_get
  33880  * Description:
  33881  *      Get the Auto-MDIX mode of a port/PHY
  33882  * Parameters:
  33883  *      unit - Device number
  33884  *      port - Port number
  33885  *      mode - (Out) One of:
  33886  *              BCM_PORT_MDIX_AUTO
  33887  *                      Enable auto-MDIX when autonegotiation is enabled
  33888  *              BCM_PORT_MDIX_FORCE_AUTO
  33889  *                      Enable auto-MDIX always
  33890  *              BCM_PORT_MDIX_NORMAL
  33891  *                      Disable auto-MDIX
  33892  *              BCM_PORT_MDIX_XOVER
  33893  *                      Disable auto-MDIX, and swap cable pairs
  33894  * Return Value:
  33895  *      BCM_E_UNAVAIL - feature unsupported by hardware
  33896  *      BCM_E_XXX - other error
  33897  */
  33898 int
  33899 bcm_esw_port_mdix_get(int unit, bcm_port_t port, bcm_port_mdix_t *mode)
  33900 {
  33901     int rv=BCM_E_NONE;
  33902 
  33903     /* Make sure port module is initialized. */
  33904     PORT_INIT(unit);
  33905 
  33906     /* Call Port Control module */
  33907     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33908         return bcmi_esw_portctrl_mdix_get(unit, port, mode);
  33909     }
  33910 
  33911     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33912         LOG_ERROR(BSL_LS_BCM_PORT,
  33913                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33914                    port));
  33915         return BCM_E_PARAM;
  33916     }
  33917 
  33918     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33919     PORT_LOCK(unit);
  33920     rv = soc_phyctrl_mdix_get(unit, port, mode);
  33921     PORT_UNLOCK(unit);
  33922 
  33923     return rv;
  33924 }
  33925 
  33926 /*
  33927  * Function:
  33928  *      bcm_port_mdix_status_get
  33929  * Description:
  33930  *      Get the current MDIX status on a port/PHY
  33931  * Parameters:
  33932  *      unit    - Device number
  33933  *      port    - Port number
  33934  *      status  - (OUT) One of:
  33935  *              BCM_PORT_MDIX_STATUS_NORMAL
  33936  *                      Straight connection
  33937  *              BCM_PORT_MDIX_STATUS_XOVER
  33938  *                      Crossover has been performed
  33939  * Return Value:
  33940  *      BCM_E_UNAVAIL - feature unsupported by hardware
  33941  *      BCM_E_XXX - other error
  33942  */
  33943 int
  33944 bcm_esw_port_mdix_status_get(int unit, bcm_port_t port,
  33945                          bcm_port_mdix_status_t *status)
  33946 {
  33947     int rv=BCM_E_NONE;
  33948 
  33949     /* Make sure port module is initialized. */
  33950     PORT_INIT(unit);
  33951 
  33952     /* Call Port Control module */
  33953     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33954         return bcmi_esw_portctrl_mdix_status_get(unit, port, status);
  33955     }
  33956 
  33957     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33958     PORT_LOCK(unit);
  33959     rv = soc_phyctrl_mdix_status_get(unit, port, status);
  33960     PORT_UNLOCK(unit);
  33961     return rv;
  33962 }
  33963 
  33964 /*
  33965  * Function:
  33966  *      bcm_port_medium_config_set
  33967  * Description:
  33968  *      Set the medium-specific configuration for a combo port
  33969  * Parameters:
  33970  *      unit     - Device number
  33971  *      port     - Port number
  33972  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  33973  *                 to apply the configuration to
  33974  *      config   - per-medium configuration
  33975  * Return Value:
  33976  *      BCM_E_XXX
  33977  */
  33978 int
  33979 bcm_esw_port_medium_config_set(int unit, bcm_port_t port,
  33980                            bcm_port_medium_t medium,
  33981                            bcm_phy_config_t  *config)
  33982 {
  33983     int rv;
  33984 
  33985     /* Make sure port module is initialized. */
  33986     PORT_INIT(unit);
  33987     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33988 
  33989 #ifdef PORTMOD_SUPPORT
  33990     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  33991         rv = bcmi_esw_portctrl_medium_config_set(unit, port, medium, config);
  33992     } else
  33993 #endif /* PORTMOD_SUPPORT */
  33994     {
  33995         PORT_LOCK(unit);
  33996         rv = soc_phyctrl_medium_config_set(unit, port, medium, config);
  33997         PORT_UNLOCK(unit);
  33998     }
  33999 
  34000     return rv;
  34001 }
  34002 
  34003 /*
  34004  * Function:
  34005  *      bcm_port_medium_config_get
  34006  * Description:
  34007  *      Get the medium-specific configuration for a combo port
  34008  * Parameters:
  34009  *      unit     - Device number
  34010  *      port     - Port number
  34011  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  34012  *                 to get the config for
  34013  *      config   - per-medium configuration
  34014  * Return Value:
  34015  *      BCM_E_XXX
  34016  */
  34017 int
  34018 bcm_esw_port_medium_config_get(int unit, bcm_port_t port,
  34019                            bcm_port_medium_t  medium,
  34020                            bcm_phy_config_t  *config)
  34021 {
  34022     int rv;
  34023 
  34024     /* Make sure port module is initialized. */
  34025     PORT_INIT(unit);
  34026     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34027 
  34028 #ifdef PORTMOD_SUPPORT
  34029     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  34030         rv = bcmi_esw_portctrl_medium_config_get(unit, port, medium, config);
  34031     } else
  34032 #endif /* PORTMOD_SUPPORT */
  34033     {
  34034         PORT_LOCK(unit);
  34035         rv = soc_phyctrl_medium_config_get(unit, port, medium, config);
  34036         PORT_UNLOCK(unit);
  34037     }
  34038     return rv;
  34039 }
  34040 
  34041 /*
  34042  * Function:
  34043  *      bcm_port_medium_get
  34044  * Description:
  34045  *      Get the current medium used by a combo port
  34046  * Parameters:
  34047  *      unit     - Device number
  34048  *      port     - Port number
  34049  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  34050  *                 which is currently selected
  34051  * Return Value:
  34052  *      BCM_E_XXX
  34053  */
  34054 int
  34055 bcm_esw_port_medium_get(int unit, bcm_port_t port,
  34056                     bcm_port_medium_t *medium)
  34057 {
  34058     int rv=BCM_E_NONE;
  34059     /* Make sure port module is initialized. */
  34060     PORT_INIT(unit);
  34061 
  34062     /* Call Port Control module */
  34063     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  34064         return bcmi_esw_portctrl_medium_get(unit, port, medium);
  34065     }
  34066 
  34067     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34068     PORT_LOCK(unit);
  34069     rv = soc_phyctrl_medium_get(unit, port, medium);
  34070     PORT_UNLOCK(unit);
  34071     return rv;
  34072 }
  34073 
  34074 /*
  34075  * Function:
  34076  *      bcm_port_medium_status_register
  34077  * Description:
  34078  *      Register a callback function to be called on medium change event
  34079  * Parameters:
  34080  *      unit      - Device number
  34081  *      port      - port number
  34082  *      callback  - The callback function to call
  34083  *      user_data - An opaque cookie to pass to callback function
  34084  *                  whenever it is called
  34085  * Returns:
  34086  *      BCM_E_NONE
  34087  *      BCM_E_PARAM  -- NULL function pointer or bad {unit, port} combination
  34088  *      BCM_E_FULL   -- Cannot register more than 1 callback per {unit, port}
  34089  */
  34090 int
  34091 bcm_esw_port_medium_status_register(int                          unit,
  34092                                 bcm_port_t                   port,
  34093                                 bcm_port_medium_status_cb_t  callback,
  34094                                 void                        *user_data)
  34095 {
  34096     /* Make sure port module is initialized. */
  34097     PORT_INIT(unit);
  34098 
  34099     return soc_phy_medium_status_register(unit, port, callback, user_data);
  34100 }
  34101 
  34102 /*
  34103  * Function:
  34104  *      bcm_port_medium_status_unregister
  34105  * Description:
  34106  *      Unregister a callback function to be called on medium change event
  34107  * Parameters:
  34108  *      unit      - Device number
  34109  *      port      - port number
  34110  *      callback  - The callback function to call
  34111  *      user_data - An opaque cookie to pass to callback function
  34112  *                  whenever it is called
  34113  * Returns:
  34114  *      BCM_E_NONE
  34115  *      BCM_E_PARAM       -- Bad {unit, port} combination
  34116  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  34117  *                           combination have not been registered before
  34118  */
  34119 int
  34120 bcm_esw_port_medium_status_unregister(int                          unit,
  34121                                   bcm_port_t                   port,
  34122                                   bcm_port_medium_status_cb_t  callback,
  34123                                   void                        *user_data)
  34124 {
  34125     /* Make sure port module is initialized. */
  34126     PORT_INIT(unit);
  34127 
  34128     return soc_phy_medium_status_unregister(unit, port, callback, user_data);
  34129 }
  34130 
  34131 /*
  34132  * Function:
  34133  *      bcm_port_phy_reset
  34134  * Description:
  34135  *      This function performs the low-level PHY reset and is intended to be
  34136  *      called ONLY from callback function registered with
  34137  *      bcm_port_phy_reset_register. Attempting to call it from any other
  34138  *      place will break lots of things.
  34139  * Parameters:
  34140  *      unit    - Device number
  34141  *      port    - Port number
  34142  * Returns:
  34143  *      BCM_E_XXX
  34144  */
  34145 int
  34146 bcm_esw_port_phy_reset(int unit, bcm_port_t port)
  34147 {
  34148     int rv;
  34149 
  34150     /* Make sure port module is initialized. */
  34151     PORT_INIT(unit);
  34152 
  34153     /* Call Port Control module */
  34154     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  34155         return (bcmi_esw_portctrl_phy_reset(unit, port));
  34156     }
  34157 
  34158     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34159 
  34160     if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  34161         return BCM_E_PORT;
  34162     }
  34163 
  34164     PORT_LOCK(unit);
  34165     rv = soc_phyctrl_reset(unit, port, NULL);
  34166     PORT_UNLOCK(unit);
  34167     return rv;
  34168 }
  34169 
  34170 /*
  34171  * Function:
  34172  *      bcm_port_phy_reset_register
  34173  * Description:
  34174  *      Register a callback function to be called whenever a PHY driver
  34175  *      needs to perform a PHY reset
  34176  * Parameters:
  34177  *      unit      - Device number
  34178  *      port      - port number
  34179  *      callback  - The callback function to call
  34180  *      user_data - An opaque cookie to pass to callback function
  34181  *                  whenever it is called
  34182  * Returns:
  34183  *      BCM_E_NONE
  34184  *      BCM_E_PARAM       -- Bad {unit, port} combination
  34185  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  34186  *                           combination have not been registered before
  34187  */
  34188 int
  34189 bcm_esw_port_phy_reset_register(int unit, bcm_port_t port,
  34190                             bcm_port_phy_reset_cb_t callback,
  34191                             void  *user_data)
  34192 {
  34193     /* Make sure port module is initialized. */
  34194     PORT_INIT(unit);
  34195 
  34196     return soc_phy_reset_register(unit, port, callback, user_data, FALSE);
  34197 }
  34198 
  34199 /*
  34200  * Function:
  34201  *      bcm_port_phy_reset_unregister
  34202  * Description:
  34203  *      Unregister a callback function to be called whenever a PHY driver
  34204  *      needs to perform a PHY reset
  34205  * Parameters:
  34206  *      unit      - Device number
  34207  *      port      - port number
  34208  *      callback  - The callback function to call
  34209  *      user_data - An opaque cookie to pass to callback function
  34210  *                  whenever it is called
  34211  * Returns:
  34212  *      BCM_E_NONE
  34213  *      BCM_E_PARAM       -- Bad {unit, port} combination
  34214  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  34215  *                           combination have not been registered before
  34216  */
  34217 int
  34218 bcm_esw_port_phy_reset_unregister(int unit, bcm_port_t port,
  34219                               bcm_port_phy_reset_cb_t callback,
  34220                               void  *user_data)
  34221 {
  34222     /* Make sure port module is initialized. */
  34223     PORT_INIT(unit);
  34224 
  34225     return soc_phy_reset_unregister(unit, port, callback, user_data);
  34226 }
  34227 
  34228 /*
  34229  * Function:
  34230  *      bcm_port_jam_set
  34231  * Description:
  34232  *      Enable or disable half duplex jamming on a port
  34233  * Parameters:
  34234  *      unit - Device number
  34235  *      port - Port number
  34236  *      enable - non-zero to enable jamming
  34237  * Return Value:
  34238  *      BCM_E_XXX
  34239  */
  34240 int
  34241 bcm_esw_port_jam_set(int unit, bcm_port_t port, int enable)
  34242 {
  34243     /* Make sure port module is initialized. */
  34244     PORT_INIT(unit);
  34245 
  34246     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34247 
  34248     if (!IS_E_PORT(unit, port)) {       /* HG, CPU ports */
  34249         return enable ? BCM_E_CONFIG : BCM_E_NONE;
  34250     }
  34251 
  34252 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  34253     if (SOC_IS_XGS3_SWITCH(unit)) {
  34254         uint32                  rval;
  34255         int                     oenable;
  34256 
  34257         if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) {
  34258             return BCM_E_UNAVAIL;
  34259         } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) &&
  34260                    !soc_feature(unit, soc_feature_unimac)) {
  34261             return BCM_E_UNAVAIL;
  34262         }
  34263 
  34264         if (soc_feature(unit, soc_feature_unimac)) {
  34265 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  34266             if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) ||
  34267                  SOC_IS_GREYHOUND2(unit)) &&
  34268                 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) {
  34269                 return BCM_E_UNAVAIL;
  34270             }
  34271 #endif
  34272 #ifdef BCM_KATANA_SUPPORT
  34273             /* In KATANA, certain GE ports do not use UNIMAC driver */
  34274             if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) {
  34275                 return BCM_E_UNAVAIL;
  34276             }
  34277 #endif
  34278             SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval));
  34279             oenable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval,
  34280                                         HD_FC_ENAf);
  34281 #ifdef BCM_HAWKEYE_SUPPORT
  34282             if(SOC_IS_HAWKEYE(unit)) {
  34283                 /*
  34284                 * In HAWKEYE A0, the back-pressure is disabled
  34285                 *      when the bit HD_FC_ENA is cleared (binary 0).
  34286                 * In other revision of HAWKEYE, the back-pressure is disabled
  34287                 *      when the bit HD_FC_ENA is set (binary 1).
  34288                 */
  34289                 if(soc_feature(unit, soc_feature_hawkeye_a0_war)) {
  34290                     enable = enable ? 1 : 0;
  34291                 } else {
  34292                     enable = enable ? 0 : 1;
  34293                 }
  34294             } else
  34295 #endif /* BCM_HAWKEYE_SUPPORT */
  34296             {
  34297                 enable = enable ? 1 : 0;
  34298             }
  34299             if (oenable != enable) {
  34300                 soc_reg_field_set(unit, IPG_HD_BKP_CNTLr, &rval, HD_FC_ENAf,
  34301                                   enable);
  34302                 SOC_IF_ERROR_RETURN(WRITE_IPG_HD_BKP_CNTLr(unit, port, rval));
  34303             }
  34304         } else {
  34305             SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval));
  34306             oenable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf);
  34307             enable = enable ? 1 : 0;
  34308             if (oenable != enable) {
  34309                 soc_reg_field_set(unit, GE_PORT_CONFIGr, &rval, JAM_ENf, enable);
  34310                 SOC_IF_ERROR_RETURN(WRITE_GE_PORT_CONFIGr(unit, port, rval));
  34311             }
  34312         }
  34313         return BCM_E_NONE;
  34314     }
  34315 #endif
  34316 
  34317     /* XE ports */
  34318     return enable ? BCM_E_CONFIG : BCM_E_NONE;
  34319 }
  34320 
  34321 /*
  34322  * Function:
  34323  *      bcm_port_jam_get
  34324  * Description:
  34325  *      Return half duplex jamming state
  34326  * Parameters:
  34327  *      unit - Device number
  34328  *      port - Port number
  34329  *      enable - (OUT) non-zero if jamming enabled
  34330  * Return Value:
  34331  *      BCM_E_XXX
  34332  */
  34333 int
  34334 bcm_esw_port_jam_get(int unit, bcm_port_t port, int *enable)
  34335 {
  34336     /* Make sure port module is initialized. */
  34337     PORT_INIT(unit);
  34338 
  34339     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34340 
  34341     if (!IS_E_PORT(unit, port)) {       /* HG, CPU ports */
  34342         *enable = 0;
  34343         return BCM_E_NONE;
  34344     }
  34345 
  34346 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  34347     if (SOC_IS_XGS3_SWITCH(unit)) {
  34348         uint32                  rval;
  34349 
  34350         if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) {
  34351             return BCM_E_UNAVAIL;
  34352         } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) &&
  34353                    !soc_feature(unit, soc_feature_unimac)) {
  34354             return BCM_E_UNAVAIL;
  34355         }
  34356 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  34357         else if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) ||
  34358                  SOC_IS_GREYHOUND2(unit)) &&
  34359                 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) {
  34360             return BCM_E_UNAVAIL;
  34361         }
  34362 #endif
  34363 
  34364         if (soc_feature(unit, soc_feature_unimac)) {
  34365 #ifdef BCM_KATANA_SUPPORT
  34366         /* In KATANA, certain GE ports do not use UNIMAC driver */
  34367             if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) {
  34368                 return BCM_E_UNAVAIL;
  34369             }
  34370 #endif
  34371             SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval));
  34372             *enable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, HD_FC_ENAf);
  34373         } else {
  34374             SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval));
  34375             *enable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf);
  34376         }
  34377         return BCM_E_NONE;
  34378     }
  34379 #endif
  34380 
  34381     *enable = 0;
  34382     return BCM_E_NONE;
  34383 }
  34384 
  34385 /*
  34386  * Function:
  34387  *      bcm_port_cable_diag
  34388  * Description:
  34389  *      Run Cable Diagnostics on port
  34390  * Parameters:
  34391  *      unit - Device number
  34392  *      port - Port number
  34393  *      status - (OUT) cable diag status structure
  34394  * Return Value:
  34395  *      BCM_E_XXX
  34396  * Notes:
  34397  *      Cable diagnostics are only supported by some phy types
  34398  *      (currently 5248 10/100 phy and 546x 10/100/1000 phys)
  34399  */
  34400 int
  34401 bcm_esw_port_cable_diag(int unit, bcm_port_t port,
  34402                     bcm_port_cable_diag_t *status)
  34403 {
  34404     int rv = BCM_E_NONE;
  34405 
  34406     /* Make sure port module is initialized. */
  34407     PORT_INIT(unit);
  34408 
  34409     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34410 
  34411 #ifdef BCM_RCPU_SUPPORT
  34412     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  34413         return BCM_E_PORT;
  34414     }
  34415 #endif /* BCM_RCPU_SUPPORT */
  34416 
  34417 #ifdef PORTMOD_SUPPORT
  34418     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  34419         return bcmi_esw_portctrl_cable_diag(unit, port, status);
  34420     } else
  34421 #endif /* PORTMOD_SUPPORT */
  34422     {
  34423         PORT_LOCK(unit);
  34424         rv = soc_phyctrl_cable_diag(unit, port, status);
  34425         PORT_UNLOCK(unit);
  34426     }
  34427 
  34428     return rv;
  34429 }
  34430 
  34431 /*
  34432  * Function:
  34433  *      bcm_esw_port_fault_get
  34434  * Description:
  34435  *      Get link fault type
  34436  * Parameters:
  34437  *      unit - Device number
  34438  *      port - Port number
  34439  *      flags - (OUT) flags to indicate fault type
  34440  * Return Value:
  34441  *      BCM_E_XXX
  34442  */
  34443 
  34444 int
  34445 bcm_esw_port_fault_get(int unit, bcm_port_t port, uint32 *flags)
  34446 {
  34447     int rv, local_fault, remote_fault;
  34448     int faults = FALSE;
  34449     soc_persist_t *sop = SOC_PERSIST(unit);
  34450 
  34451     /* Make sure port module is initialized. */
  34452     PORT_INIT(unit);
  34453 
  34454     if(bcm_common_oamp_port_enable_get(unit, port)) {
  34455         LOG_ERROR(BSL_LS_BCM_PORT,
  34456                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  34457                    port));
  34458         return BCM_E_PARAM;
  34459     }
  34460 
  34461     if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  34462         faults = FALSE;
  34463         SOC_IF_ERROR_RETURN(soc_phyctrl_linkfault_get(unit, port, &faults));
  34464     }
  34465 
  34466     /* Call Port Control module */
  34467     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  34468         rv = bcmi_esw_portctrl_fault_get(unit, port, flags);
  34469         if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  34470             if (faults) {
  34471                 *flags |= faults;
  34472             }
  34473         }
  34474         return (rv);
  34475     }
  34476 
  34477     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34478 
  34479     rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  34480                          SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, &local_fault);
  34481     if (rv == SOC_E_UNAVAIL) {
  34482         return BCM_E_PORT;
  34483     }
  34484     SOC_IF_ERROR_RETURN
  34485         (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  34486                          SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, &remote_fault));
  34487 
  34488     *flags = 0;
  34489     if (remote_fault) {
  34490         *flags |= BCM_PORT_FAULT_REMOTE;
  34491     }
  34492     if (local_fault) {
  34493         *flags |= BCM_PORT_FAULT_LOCAL;
  34494     }
  34495 
  34496     if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  34497         *flags |= faults;
  34498     }
  34499 
  34500     return BCM_E_NONE;
  34501 }
  34502 
  34503 /*
  34504  * Function:
  34505  *      bcm_port_trunk_index_set
  34506  * Description:
  34507  *      Set port index of a trunk for ingress port that is used to select
  34508  *      the egress port in the trunk.
  34509  * Parameters:
  34510  *      unit       - StrataSwitch PCI device unit number (driver internal).
  34511  *      port       - Ingress port.
  34512  *      port_index - Port index of a trunk.
  34513  * Returns:
  34514  *      BCM_E_xxxx
  34515  * Note:
  34516  *      The psc (aka rtag) vlaue needs to be 7 (set in bcm_trunk_set()) for
  34517  *      a trunk in order to utilize this programmable hashing mechanism.
  34518  */
  34519 
  34520 int
  34521 bcm_esw_port_trunk_index_set(int unit, bcm_port_t port, int port_index)
  34522 {
  34523 #if defined(BCM_FIREBOLT_SUPPORT)
  34524     uint32 val, mask = 0x7;
  34525 
  34526     /* Make sure port module is initialized. */
  34527     PORT_INIT(unit);
  34528 
  34529     if (soc_feature(unit, soc_feature_port_trunk_index)) {
  34530         if (IS_ST_PORT(unit, port)) {
  34531             if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) {
  34532                 return BCM_E_UNAVAIL;
  34533             }
  34534 
  34535             val = 0;
  34536             if (!SOC_IS_RAVEN(unit)) {
  34537                 mask = 0x3;
  34538             }
  34539             soc_reg_field_set(unit, IUSER_TRUNK_HASH_SELECTr, &val,
  34540                               TRUNK_CFG_VALf, port_index & mask);
  34541             SOC_IF_ERROR_RETURN
  34542                 (WRITE_IUSER_TRUNK_HASH_SELECTr(unit, port, val));
  34543         } else if (IS_E_PORT(unit, port)) {
  34544             if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) {
  34545                 return BCM_E_UNAVAIL;
  34546             }
  34547 
  34548             val = 0;
  34549             soc_reg_field_set(unit, USER_TRUNK_HASH_SELECTr, &val,
  34550                               TRUNK_CFG_VALf, port_index & mask);
  34551             SOC_IF_ERROR_RETURN
  34552                 (WRITE_USER_TRUNK_HASH_SELECTr(unit, port, val));
  34553         }
  34554 
  34555         return BCM_E_NONE;
  34556     }
  34557 #endif  /* BCM_FIREBOLT_SUPPORT */
  34558 
  34559     return BCM_E_UNAVAIL;
  34560 }
  34561 
  34562 /*
  34563  * Function:
  34564  *      bcm_port_trunk_index_get
  34565  * Description:
  34566  *      Get port index of a trunk for ingress port that is used to select
  34567  *      the egress port in the trunk.
  34568  * Parameters:
  34569  *      unit       - StrataSwitch PCI device unit number (driver internal).
  34570  *      port       - Ingress port.
  34571  *      port_index - (OUT) Port index of a trunk.
  34572  * Returns:
  34573  *      BCM_E_xxxx
  34574  */
  34575 
  34576 int
  34577 bcm_esw_port_trunk_index_get(int unit, bcm_port_t port, int *port_index)
  34578 {
  34579 #if defined(BCM_FIREBOLT_SUPPORT)
  34580     uint32 val;
  34581 
  34582     /* Make sure port module is initialized. */
  34583     PORT_INIT(unit);
  34584 
  34585     if (soc_feature(unit, soc_feature_port_trunk_index)) {
  34586         if (IS_ST_PORT(unit, port)) {
  34587             if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) {
  34588                 return BCM_E_UNAVAIL;
  34589             }
  34590 
  34591             SOC_IF_ERROR_RETURN
  34592                (READ_IUSER_TRUNK_HASH_SELECTr(unit, port, &val));
  34593             *port_index = soc_reg_field_get(unit, IUSER_TRUNK_HASH_SELECTr,
  34594                                             val, TRUNK_CFG_VALf);
  34595         } else if (IS_E_PORT(unit, port)) {
  34596             if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) {
  34597                 return BCM_E_UNAVAIL;
  34598             }
  34599 
  34600             SOC_IF_ERROR_RETURN
  34601                (READ_USER_TRUNK_HASH_SELECTr(unit, port, &val));
  34602             *port_index = soc_reg_field_get(unit, USER_TRUNK_HASH_SELECTr,
  34603                                             val, TRUNK_CFG_VALf);
  34604         }
  34605 
  34606         return BCM_E_NONE;
  34607     }
  34608 #endif  /* BCM_FIREBOLT_SUPPORT */
  34609 
  34610     return BCM_E_UNAVAIL;
  34611 }
  34612 
  34613 #ifdef BCM_XGS3_SWITCH_SUPPORT
  34614 
  34615 static soc_field_t _bcm_xgs3_priority_fields[] = {
  34616     PRIORITY0_CNGf,
  34617     PRIORITY1_CNGf,
  34618     PRIORITY2_CNGf,
  34619     PRIORITY3_CNGf,
  34620     PRIORITY4_CNGf,
  34621     PRIORITY5_CNGf,
  34622     PRIORITY6_CNGf,
  34623     PRIORITY7_CNGf,
  34624 };
  34625 
  34626 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  34627 
  34628 #ifdef BCM_TRIUMPH2_SUPPORT
  34629 STATIC
  34630 int _bcm_esw_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged,
  34631                                 int pkt_pri, int cfi,
  34632                                 int internal_pri, bcm_color_t color)
  34633 {
  34634     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) {
  34635         return _bcm_tr2_vp_ing_pri_cng_set(unit, port, untagged,
  34636                                            pkt_pri, cfi,
  34637                                            internal_pri, color);
  34638     }
  34639     return BCM_E_PORT;
  34640 }
  34641 
  34642 STATIC
  34643 int _bcm_esw_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged,
  34644                                 int pkt_pri, int cfi,
  34645                                 int *internal_pri, bcm_color_t *color)
  34646 {
  34647     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) {
  34648         return _bcm_tr2_vp_ing_pri_cng_get(unit, port, untagged,
  34649                                            pkt_pri, cfi,
  34650                                            internal_pri, color);
  34651     }
  34652     return BCM_E_PORT;
  34653 }
  34654 #endif
  34655 /*
  34656  * Function:
  34657  *      bcm_port_priority_color_set
  34658  * Purpose:
  34659  *      Specify the color selection for the given priority.
  34660  * Parameters:
  34661  *      unit -  StrataSwitch PCI device unit number (driver internal).
  34662  *      port -  Port to configure
  34663  *      prio -  priority (aka 802.1p CoS)
  34664  *      color - color assigned to packets with indicated priority.
  34665  * Returns:
  34666  *      BCM_E_NONE - Success.
  34667  *      BCM_E_XXX
  34668  * Notes:
  34669  *      Available on XGS3 only.
  34670  */
  34671 int
  34672 bcm_esw_port_priority_color_set(int unit, bcm_port_t port,
  34673                                 int prio, bcm_color_t color)
  34674 {
  34675     /* Make sure port module is initialized. */
  34676     PORT_INIT(unit);
  34677 
  34678 #ifdef BCM_XGS3_SWITCH_SUPPORT
  34679     if (soc_feature(unit, soc_feature_color)) {
  34680 
  34681         VLAN_CHK_PRIO(unit, prio);
  34682 
  34683 #if defined(BCM_TRIUMPH2_SUPPORT)
  34684         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34685             if (BCM_GPORT_IS_SET(port) &&
  34686                 !BCM_GPORT_IS_MODPORT(port) &&
  34687                 !BCM_GPORT_IS_LOCAL(port) &&
  34688                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  34689                 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, prio,
  34690                                                    -1, -1, color);
  34691             }
  34692         }
  34693 #endif
  34694 
  34695         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34696 
  34697 #ifdef BCM_TRIUMPH2_SUPPORT
  34698         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34699 #ifdef BCM_TRIDENT3_SUPPORT
  34700             if (SOC_IS_TRIDENT3X(unit)) {
  34701                 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE,
  34702                                                     prio, -1, -1, color);
  34703             } else
  34704 #endif
  34705 #ifdef BCM_TRIDENT_SUPPORT
  34706             if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  34707                 SOC_IS_TRIUMPH3(unit)) {
  34708                 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE,
  34709                                                    prio, -1, -1, color);
  34710             } else
  34711 #endif /* BCM_TRIDENT_SUPPORT */
  34712             {
  34713                 return _bcm_tr2_port_priority_color_set(unit, port,
  34714                                                         prio, color);
  34715             }
  34716         } else
  34717 #endif
  34718         {
  34719             uint32 val, oval;
  34720 
  34721             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  34722             oval = val;
  34723             soc_reg_field_set(unit, CNG_MAPr, &val,
  34724                               _bcm_xgs3_priority_fields[prio],
  34725                               _BCM_COLOR_ENCODING(unit, color));
  34726             if (oval != val) {
  34727                 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val));
  34728             }
  34729             return BCM_E_NONE;
  34730         }
  34731     }
  34732 #endif
  34733     return BCM_E_UNAVAIL;
  34734 }
  34735 
  34736 /*
  34737  * Function:
  34738  *      bcm_port_priority_color_get
  34739  * Purpose:
  34740  *      Get the color selection for the given priority.
  34741  * Parameters:
  34742  *      unit -  StrataSwitch PCI device unit number (driver internal).
  34743  *      port -  Port to configure
  34744  *      prio -  priority (aka 802.1p CoS)
  34745  *      color - (OUT) color assigned to packets with indicated priority.
  34746  * Returns:
  34747  *      BCM_E_NONE - Success.
  34748  *      BCM_E_XXX
  34749  * Notes:
  34750  *      Available on XGS3 only.
  34751  */
  34752 int
  34753 bcm_esw_port_priority_color_get(int unit, bcm_port_t port,
  34754                                 int prio, bcm_color_t *color)
  34755 {
  34756     /* Make sure port module is initialized. */
  34757     PORT_INIT(unit);
  34758 
  34759 #ifdef BCM_XGS3_SWITCH_SUPPORT
  34760     if (soc_feature(unit, soc_feature_color)) {
  34761         uint32 val, hw_color;
  34762         cng_map_entry_t cng_map_entry;
  34763         int ptr;
  34764 
  34765         /* Input parameters check. */
  34766         if ((NULL == color)) {
  34767             return (BCM_E_PARAM);
  34768         }
  34769 
  34770         VLAN_CHK_PRIO(unit, prio);
  34771 
  34772 #if defined(BCM_TRIUMPH2_SUPPORT)
  34773         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34774             if (BCM_GPORT_IS_SET(port) &&
  34775                 !BCM_GPORT_IS_MODPORT(port) &&
  34776                 !BCM_GPORT_IS_LOCAL(port) &&
  34777                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  34778                 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, prio,
  34779                                                    0, NULL, color);
  34780             }
  34781         }
  34782 #endif
  34783         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34784         ptr = port;
  34785 
  34786 #ifdef BCM_TRIUMPH2_SUPPORT
  34787         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34788 #ifdef BCM_TRIDENT3_SUPPORT
  34789             if (SOC_IS_TRIDENT3X(unit)) {
  34790                 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE,
  34791                                                     prio, 0, NULL, color);
  34792             } else
  34793 #endif /* BCM_TRIDENT3_SUPPORT */
  34794 #ifdef BCM_TRIDENT_SUPPORT
  34795             if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  34796                 SOC_IS_TRIUMPH3(unit)) {
  34797                 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE,
  34798                                                    prio, 0, NULL, color);
  34799             } else
  34800 #endif /* BCM_TRIDENT_SUPPORT */
  34801             {
  34802                 /* Get the pointer from the ING_PRI_CNG_MAP table */
  34803                 port_tab_entry_t pent;
  34804                 BCM_IF_ERROR_RETURN
  34805                     (soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  34806                                   SOC_PORT_MOD_OFFSET(unit, port), &pent));
  34807                 ptr = soc_PORT_TABm_field32_get(unit, &pent,
  34808                                                 TRUST_DOT1P_PTRf);
  34809             }
  34810         }
  34811 #endif
  34812         if (SOC_MEM_IS_VALID(unit, CNG_MAPm)) {
  34813             SOC_IF_ERROR_RETURN(READ_CNG_MAPm(unit, MEM_BLOCK_ANY,
  34814                                               ptr, &cng_map_entry));
  34815             hw_color = soc_CNG_MAPm_field32_get(unit, &cng_map_entry,
  34816                                                _bcm_xgs3_priority_fields[prio]);
  34817         } else {
  34818             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, ptr, &val));
  34819             hw_color = soc_reg_field_get(unit, CNG_MAPr, val,
  34820                                          _bcm_xgs3_priority_fields[prio]);
  34821         }
  34822         *color = _BCM_COLOR_DECODING(unit, hw_color);
  34823         return BCM_E_NONE;
  34824     }
  34825 #endif
  34826     return BCM_E_UNAVAIL;
  34827 }
  34828 
  34829 /*
  34830  * Function:
  34831  *      bcm_port_cfi_color_set
  34832  * Purpose:
  34833  *      Specify the color selection for the given CFI.
  34834  * Parameters:
  34835  *      unit -  StrataSwitch PCI device unit number (driver internal).
  34836  *      port -  Port to configure
  34837  *      cfi -   Canonical format indicator (TRUE/FALSE)
  34838  *      color - color assigned to packets with indicated CFI.
  34839  * Returns:
  34840  *      BCM_E_NONE - Success.
  34841  *      BCM_E_XXX
  34842  * Notes:
  34843  *      Available on XGS3 only.
  34844  */
  34845 int
  34846 bcm_esw_port_cfi_color_set(int unit, bcm_port_t port,
  34847                            int cfi, bcm_color_t color)
  34848 {
  34849     /* Make sure port module is initialized. */
  34850     PORT_INIT(unit);
  34851 
  34852 #ifdef BCM_XGS3_SWITCH_SUPPORT
  34853     if (soc_feature(unit, soc_feature_color)) {
  34854         if (cfi < 0 || cfi > 1) {
  34855             return BCM_E_PARAM;
  34856         }
  34857 
  34858 #if defined(BCM_TRIUMPH2_SUPPORT)
  34859         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34860             if (BCM_GPORT_IS_SET(port) &&
  34861                 !BCM_GPORT_IS_MODPORT(port) &&
  34862                 !BCM_GPORT_IS_LOCAL(port) &&
  34863                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  34864                 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, -1,
  34865                                                    cfi, -1, color);
  34866             }
  34867         }
  34868 #endif
  34869 
  34870         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34871 #ifdef BCM_TRIDENT3_SUPPORT
  34872         if (SOC_IS_TRIDENT3X(unit)) {
  34873             return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE,
  34874                                                 -1, cfi, -1, color);
  34875         } else
  34876 #endif
  34877 #ifdef BCM_TRIDENT_SUPPORT
  34878         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  34879             SOC_IS_TRIUMPH3(unit)) {
  34880             return bcm_td_port_ing_pri_cng_set(unit, port, FALSE,
  34881                                                -1, cfi, -1, color);
  34882         } else
  34883 #endif /* BCM_TRIDENT_SUPPORT */
  34884 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  34885         || defined (BCM_TRX_SUPPORT)
  34886         if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_TRX(unit) ||
  34887             SOC_IS_HAWKEYE(unit)) {
  34888             int                     index, pkt_pri;
  34889             uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  34890 
  34891             sal_memset(pri_map, 0, sizeof(pri_map));
  34892 
  34893 #if defined(BCM_TRIUMPH2_SUPPORT)
  34894             if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34895                 pkt_pri = -1;
  34896                 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri,
  34897                         cfi,
  34898                         pkt_pri, color);
  34899             } else
  34900 #endif /* BCM_TRIUMPH2_SUPPORT */
  34901             {
  34902                 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) {
  34903                     /* ING_PRI_CNG_MAP table is indexed with
  34904                      * port[0:4] incoming priority[2:0] incoming CFI[0]
  34905                      */
  34906                     index = (port << 4) | (pkt_pri << 1) | cfi;
  34907                     if (SOC_IS_TRIDENT3X(unit)) {
  34908                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf,
  34909                                             pkt_pri);
  34910                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf,
  34911                                             _BCM_COLOR_ENCODING(unit, color));
  34912                         SOC_IF_ERROR_RETURN(WRITE_PHB_MAPPING_TBL_1m(unit,
  34913                                                 MEM_BLOCK_ALL, index, &pri_map));
  34914                     } else {
  34915                         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf,
  34916                                             pkt_pri);
  34917                         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf,
  34918                                             _BCM_COLOR_ENCODING(unit, color));
  34919                         SOC_IF_ERROR_RETURN(WRITE_ING_PRI_CNG_MAPm(unit,
  34920                                                 MEM_BLOCK_ALL, index, &pri_map));
  34921                     }
  34922                 }
  34923             }
  34924         } else
  34925 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  34926         {
  34927             uint32 val, oval;
  34928             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  34929             oval = val;
  34930             soc_reg_field_set(unit, CNG_MAPr, &val,
  34931                               cfi ? CFI1_CNGf : CFI0_CNGf,
  34932                              _BCM_COLOR_ENCODING(unit, color));
  34933             if (oval != val) {
  34934                 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val));
  34935             }
  34936         }
  34937         return BCM_E_NONE;
  34938     }
  34939 #endif
  34940     return BCM_E_UNAVAIL;
  34941 }
  34942 
  34943 /*
  34944  * Function:
  34945  *      bcm_port_cfi_color_get
  34946  * Purpose:
  34947  *      Get the color selection for the given CFI.
  34948  * Parameters:
  34949  *      unit -  StrataSwitch PCI device unit number (driver internal).
  34950  *      port -  Port to configure
  34951  *      cfi -   Canonical format indicator (TRUE/FALSE)
  34952  *      color - (OUT) color assigned to packets with indicated CFI.
  34953  * Returns:
  34954  *      BCM_E_NONE - Success.
  34955  *      BCM_E_XXX
  34956  * Notes:
  34957  *      Available on XGS3 only.
  34958  */
  34959 int
  34960 bcm_esw_port_cfi_color_get(int unit, bcm_port_t port,
  34961                            int cfi, bcm_color_t *color)
  34962 {
  34963     /* Make sure port module is initialized. */
  34964     PORT_INIT(unit);
  34965 
  34966 #ifdef BCM_XGS3_SWITCH_SUPPORT
  34967     if (soc_feature(unit, soc_feature_color)) {
  34968         uint32 hw_color;
  34969 
  34970         if (cfi < 0 || cfi > 1) {
  34971             return BCM_E_PARAM;
  34972         }
  34973 
  34974         /* Input parameters check. */
  34975         if ((NULL == color)) {
  34976             return (BCM_E_PARAM);
  34977         }
  34978 
  34979 #if defined(BCM_TRIUMPH2_SUPPORT)
  34980         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34981             if (BCM_GPORT_IS_SET(port) &&
  34982                 !BCM_GPORT_IS_MODPORT(port) &&
  34983                 !BCM_GPORT_IS_LOCAL(port) &&
  34984                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  34985                 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, 0,
  34986                                                    cfi, NULL, color);
  34987             }
  34988         }
  34989 #endif
  34990 
  34991     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34992 
  34993 #ifdef BCM_TRIDENT3_SUPPORT
  34994         if (SOC_IS_TRIDENT3X(unit)) {
  34995             return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL,
  34996                                                 color);
  34997         } else
  34998 #endif /* BCM_TRIDENT3_SUPPORT */
  34999 #ifdef BCM_TRIDENT_SUPPORT
  35000     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  35001         SOC_IS_TRIUMPH3(unit)) {
  35002         return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL,
  35003                                            color);
  35004     } else
  35005 #endif /* BCM_TRIDENT_SUPPORT */
  35006 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  35007         || defined(BCM_TRX_SUPPORT)
  35008     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)
  35009         || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  35010         int index;
  35011         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  35012 
  35013         sal_memset(pri_map, 0, sizeof(pri_map));
  35014 
  35015 #if defined(BCM_TRIUMPH2_SUPPORT)
  35016         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  35017             int pkt_pri = 0;
  35018             return _bcm_tr2_port_vlan_priority_map_get(unit, port, 0,
  35019                                                        cfi, &pkt_pri, color);
  35020         } else
  35021 #endif /* BCM_TRIUMPH2_SUPPORT */
  35022         {
  35023             /* ING_PRI_CNG_MAP table is indexed with
  35024              * port[0:4] incoming priority[2:0] incoming CFI[0]
  35025              */
  35026             index = (port << 4) | cfi;
  35027             if (SOC_IS_TRIDENT3X(unit)) {
  35028                 SOC_IF_ERROR_RETURN(READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY,
  35029                                                           index, &pri_map));
  35030                 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m,
  35031                                                &pri_map, CNGf);
  35032             } else {
  35033                 SOC_IF_ERROR_RETURN(READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY,
  35034                                                           index, &pri_map));
  35035                 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm,
  35036                                                &pri_map, CNGf);
  35037             }
  35038         }
  35039     } else
  35040 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  35041         {
  35042             uint32 val;
  35043 
  35044             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  35045             hw_color = soc_reg_field_get(unit, CNG_MAPr, val,
  35046                                          cfi ? CFI1_CNGf : CFI0_CNGf);
  35047         }
  35048         *color = _BCM_COLOR_DECODING(unit, hw_color);
  35049         return BCM_E_NONE;
  35050     }
  35051 #endif
  35052     return BCM_E_UNAVAIL;
  35053 }
  35054 
  35055 /*
  35056  * Function:
  35057  *      bcm_esw_port_vlan_priority_map_set
  35058  * Description:
  35059  *      Define the mapping of incomming port, packet priority, and cfi bit to
  35060  *      switch internal priority and color.
  35061  * Parameters:
  35062  *      unit         - (IN) Device number
  35063  *      port         - (IN) Port number
  35064  *      pkt_pri      - (IN) Packet priority
  35065  *      cfi          - (IN) Packet CFI
  35066  *      internal_pri - (IN) Internal priority
  35067  *      color        - (IN) color
  35068  * Return Value:
  35069  *      BCM_E_XXX
  35070  * Note:
  35071  *      This API programs only the mapping table.
  35072  */
  35073 int
  35074 bcm_esw_port_vlan_priority_map_set(int unit, bcm_port_t port, int pkt_pri,
  35075                                    int cfi, int internal_pri, bcm_color_t color)
  35076 {
  35077 #ifdef BCM_TRIUMPH2_SUPPORT
  35078     int untagged = FALSE;
  35079 #endif /* BCM_TRIUMPH2_SUPPORT */
  35080 
  35081     /* Make sure port module is initialized. */
  35082     PORT_INIT(unit);
  35083 
  35084     if (!soc_feature(unit, soc_feature_color_prio_map) ||
  35085         soc_feature(unit, soc_feature_deprecated_api)) {
  35086         return BCM_E_UNAVAIL;
  35087     }
  35088 
  35089     if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) {
  35090         if (pkt_pri == -1 && cfi == -1) {
  35091 #ifdef BCM_TRIDENT_SUPPORT
  35092             untagged = TRUE;
  35093 #endif /* BCM_TRIDENT_SUPPORT */
  35094             pkt_pri = 0;
  35095             cfi = 0;
  35096         }
  35097     }
  35098 
  35099     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1 || internal_pri < 0 ) {
  35100         return BCM_E_PARAM;
  35101     }
  35102 
  35103     if (SOC_IS_TRIDENT3X(unit)) {
  35104        if (internal_pri >= (1 << soc_mem_field_length(unit, PHB_MAPPING_TBL_1m, PRIf))) {
  35105            return BCM_E_PARAM;
  35106        }
  35107     } else {
  35108        if (internal_pri >= (1 << soc_mem_field_length(unit, ING_PRI_CNG_MAPm, PRIf))) {
  35109            return BCM_E_PARAM;
  35110        }
  35111     }
  35112 
  35113 #if defined(BCM_TRIUMPH2_SUPPORT)
  35114     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  35115         if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  35116             !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  35117             return _bcm_esw_vp_ing_pri_cng_set(unit, port, untagged, pkt_pri,
  35118                                                cfi, internal_pri, color);
  35119         }
  35120     }
  35121 #endif
  35122 
  35123     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35124 
  35125 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  35126         || defined(BCM_TRX_SUPPORT)
  35127 #if defined(BCM_TRIUMPH2_SUPPORT)
  35128     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  35129 #ifdef BCM_TRIDENT3_SUPPORT
  35130         if (SOC_IS_TRIDENT3X(unit)) {
  35131             return bcm_td3_port_ing_pri_cng_set(unit, port, untagged,
  35132                                                 pkt_pri, cfi,
  35133                                                 internal_pri, color);
  35134         } else
  35135 #endif
  35136 #if defined BCM_TRIDENT_SUPPORT
  35137         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  35138             SOC_IS_TRIUMPH3(unit)) {
  35139             return bcm_td_port_ing_pri_cng_set(unit, port, untagged,
  35140                                                pkt_pri, cfi,
  35141                                                internal_pri, color);
  35142         } else
  35143 #endif /* BCM_TRIDENT_SUPPORT */
  35144         {
  35145             return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri,
  35146                                                        cfi,
  35147                                                        internal_pri, color);
  35148         }
  35149     } else
  35150 #endif
  35151     if (soc_feature(unit, soc_feature_color_prio_map)) {
  35152         int                      index;
  35153         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  35154 
  35155         sal_memset(pri_map, 0, sizeof(pri_map));
  35156 
  35157         /* ING_PRI_CNG_MAP table is indexed with
  35158          * port[0:4] incoming priority[2:0] incoming CFI[0]
  35159          */
  35160         index = (port << 4) | (pkt_pri << 1) | cfi;
  35161 
  35162         if (SOC_IS_TRIDENT3X(unit)) {
  35163             soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf,
  35164                                 internal_pri);
  35165             soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf,
  35166                                 _BCM_COLOR_ENCODING(unit, color));
  35167             SOC_IF_ERROR_RETURN
  35168                 (WRITE_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ALL, index, &pri_map));
  35169         } else {
  35170             soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf,
  35171                                 internal_pri);
  35172             soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf,
  35173                                 _BCM_COLOR_ENCODING(unit, color));
  35174             SOC_IF_ERROR_RETURN
  35175                 (WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, index, &pri_map));
  35176         }
  35177 
  35178         return BCM_E_NONE;
  35179    }
  35180 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  35181     return BCM_E_UNAVAIL;
  35182 }
  35183 
  35184 /*
  35185  * Function:
  35186  *      bcm_esw_port_vlan_priority_map_get
  35187  * Description:
  35188  *      Get the mapping of incomming port, packet priority, and cfi bit to
  35189  *      switch internal priority and color.
  35190  * Parameters:
  35191  *      unit         - (IN) Device number
  35192  *      port         - (IN) Port number
  35193  *      pkt_pri      - (IN) Packet priority
  35194  *      cfi          - (IN) Packet CFI
  35195  *      internal_pri - (OUT) Internal priority
  35196  *      color        - (OUT) color
  35197  * Return Value:
  35198  *      BCM_E_XXX
  35199  * Note:
  35200  *      This API programs only the mapping table.
  35201  */
  35202 int
  35203 bcm_esw_port_vlan_priority_map_get(int unit, bcm_port_t port, int pkt_pri,
  35204                                    int cfi, int *internal_pri,
  35205                                    bcm_color_t *color)
  35206 {
  35207 #if defined BCM_TRIUMPH2_SUPPORT
  35208     int untagged = FALSE;
  35209 #endif /* BCM_TRIUMPH2_SUPPORT */
  35210 
  35211     /* Make sure port module is initialized. */
  35212     PORT_INIT(unit);
  35213 
  35214     if (!soc_feature(unit, soc_feature_color_prio_map) ||
  35215         soc_feature(unit, soc_feature_deprecated_api)) {
  35216         return BCM_E_UNAVAIL;
  35217     }
  35218 
  35219     /* Input parameters check. */
  35220     if ((NULL == internal_pri) || (NULL == color)) {
  35221         return (BCM_E_PARAM);
  35222     }
  35223 
  35224     if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) {
  35225         if (pkt_pri == -1 && cfi == -1) {
  35226 #if defined BCM_TRIDENT_SUPPORT
  35227             untagged = TRUE;
  35228 #endif /* BCM_TRIDENT_SUPPORT */
  35229             pkt_pri = 0;
  35230             cfi = 0;
  35231         }
  35232     }
  35233 
  35234     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  35235         return BCM_E_PARAM;
  35236     }
  35237 
  35238 #if defined(BCM_TRIUMPH2_SUPPORT)
  35239     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  35240         if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  35241             !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  35242             return _bcm_esw_vp_ing_pri_cng_get(unit, port, untagged, pkt_pri,
  35243                                                cfi, internal_pri, color);
  35244         }
  35245     }
  35246 #endif
  35247 
  35248     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35249 
  35250 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  35251         || defined(BCM_TRX_SUPPORT)
  35252 #if defined(BCM_TRIUMPH2_SUPPORT)
  35253     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  35254 #ifdef BCM_TRIDENT3_SUPPORT
  35255         if (SOC_IS_TRIDENT3X(unit)) {
  35256             return bcm_td3_port_ing_pri_cng_get(unit, port, untagged,
  35257                                                 pkt_pri, cfi,
  35258                                                 internal_pri, color);
  35259         } else
  35260 #endif /* BCM_TRIDENT3_SUPPORT */
  35261 #if defined BCM_TRIDENT_SUPPORT
  35262         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  35263             SOC_IS_TRIUMPH3(unit)) {
  35264             return bcm_td_port_ing_pri_cng_get(unit, port, untagged,
  35265                                                pkt_pri, cfi,
  35266                                                internal_pri, color);
  35267         } else
  35268 #endif /* BCM_TRIDENT_SUPPORT */
  35269         {
  35270             return _bcm_tr2_port_vlan_priority_map_get(unit, port, pkt_pri,
  35271                                                        cfi, internal_pri,
  35272                                                        color);
  35273         }
  35274     } else
  35275 #endif
  35276     if (soc_feature(unit, soc_feature_color_prio_map)) {
  35277         int index, hw_color;
  35278         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  35279 
  35280         sal_memset(pri_map, 0, sizeof(pri_map));
  35281 
  35282         /* ING_PRI_CNG_MAP table is indexed with
  35283          * port[4:0] incoming priority[2:0] incoming CFI[0]
  35284          */
  35285         index = (port << 4) | (pkt_pri << 1) | cfi;
  35286 
  35287         LOG_INFO(BSL_LS_BCM_PORT,
  35288                  (BSL_META_U(unit,
  35289                              "bcm_esw_port_vlan_priority_map_get: u=%d p=%d index=%d\n"),
  35290                   unit, port, index));
  35291 
  35292         if (SOC_IS_TRIDENT3X(unit)) {
  35293             SOC_IF_ERROR_RETURN
  35294                 (READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, index, &pri_map));
  35295             *internal_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, INT_PRIf);
  35296             hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf);
  35297         } else {
  35298             SOC_IF_ERROR_RETURN
  35299                 (READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, index, &pri_map));
  35300             *internal_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf);
  35301             hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf);
  35302         }
  35303 
  35304         *color = _BCM_COLOR_DECODING(unit, hw_color);
  35305         return BCM_E_NONE;
  35306    }
  35307 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  35308     return BCM_E_UNAVAIL;
  35309 
  35310 }
  35311 
  35312 /*
  35313  * Function:
  35314  *      bcm_esw_port_vlan_priority_unmap_set
  35315  * Description:
  35316  *      Define the mapping of outgoing port, internal priority, and color to
  35317  *  outgoing packet priority and cfi bit.
  35318  * Parameters:
  35319  *      unit         - (IN) Device number
  35320  *      port         - (IN) Port number
  35321  *      internal_pri - (IN) Internal priority
  35322  *      color        - (IN) Color
  35323  *      pkt_pri      - (IN) Packet priority
  35324  *      cfi          - (IN) Packet CFI
  35325  * Return Value:
  35326  *      BCM_E_XXX
  35327  * Note:
  35328  *      This API programs only the mapping table.
  35329  */
  35330 int
  35331 bcm_esw_port_vlan_priority_unmap_set(int unit, bcm_port_t port,
  35332                                      int internal_pri, bcm_color_t color,
  35333                                      int pkt_pri, int cfi)
  35334 {
  35335     /* Make sure port module is initialized. */
  35336     PORT_INIT(unit);
  35337 
  35338 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  35339     if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
  35340         return BCM_E_UNAVAIL;
  35341     }
  35342 #endif
  35343 
  35344     if (SOC_IS_TRIDENT3X(unit)) {
  35345         return BCM_E_UNAVAIL;
  35346     }
  35347 
  35348     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35349 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  35350         || defined(BCM_TRX_SUPPORT)
  35351     if (soc_feature(unit, soc_feature_color_prio_map)) {
  35352         int index, int_pri_shift;
  35353         uint32     pri_unmap[SOC_MAX_MEM_FIELD_WORDS];
  35354         soc_mem_t  mem = EGR_PRI_CNG_MAPm;
  35355 
  35356         int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3;
  35357         if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) ||
  35358             ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  35359              (color != bcmColorRed))) {
  35360             return BCM_E_PARAM;
  35361         }
  35362         if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  35363             return BCM_E_PARAM;
  35364         }
  35365 
  35366         /* EGR_PRI_CNG_MAP table is indexed with
  35367          * port[4:0] priority[2:0] CNG [1:0]
  35368          * port[5:0] priority[3:0] CNG [1:0] (TRX)
  35369          */
  35370         index = (port << (int_pri_shift + 2)) | (internal_pri << 2) |
  35371             _BCM_COLOR_ENCODING(unit, color);
  35372 
  35373         sal_memset(pri_unmap, 0, sizeof(pri_unmap));
  35374         soc_mem_field32_set(unit, mem, &pri_unmap, PRIf, pkt_pri);
  35375         soc_mem_field32_set(unit, mem, &pri_unmap, CFIf, cfi);
  35376         SOC_IF_ERROR_RETURN
  35377             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pri_unmap));
  35378 
  35379         if ((SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit)) ||
  35380             SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  35381             egr_map_mh_entry_t  egr_map;
  35382 
  35383             sal_memset(&egr_map, 0, sizeof(egr_map));
  35384             index = (port << int_pri_shift) | (internal_pri) ;
  35385             soc_mem_field32_set(unit, EGR_MAP_MHm, &egr_map, HG_TCf, internal_pri);
  35386             SOC_IF_ERROR_RETURN(WRITE_EGR_MAP_MHm(unit, MEM_BLOCK_ALL, index, &egr_map));
  35387         }
  35388 
  35389         return BCM_E_NONE;
  35390     }
  35391 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  35392     return BCM_E_UNAVAIL;
  35393 }
  35394 
  35395 /*
  35396  * Function:
  35397  *      bcm_esw_port_vlan_priority_unmap_get
  35398  * Description:
  35399  *      Get the mapping of outgoing port, internal priority, and color to
  35400  *  outgoing packet priority and cfi bit.
  35401  * Parameters:
  35402  *      unit         - (IN) Device number
  35403  *      port         - (IN) Port number
  35404  *      internal_pri - (IN) Internal priority
  35405  *      color        - (IN) Color
  35406  *      pkt_pri      - (OUT) Packet priority
  35407  *      cfi          - (OUT) Packet CFI
  35408  * Return Value:
  35409  *      BCM_E_XXX
  35410  * Note:
  35411  *      This API programs only the mapping table.
  35412  */
  35413 int
  35414 bcm_esw_port_vlan_priority_unmap_get(int unit, bcm_port_t port,
  35415                                      int internal_pri, bcm_color_t color,
  35416                                      int *pkt_pri, int *cfi)
  35417 {
  35418     /* Make sure port module is initialized. */
  35419     PORT_INIT(unit);
  35420 
  35421 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  35422     if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
  35423         return BCM_E_UNAVAIL;
  35424     }
  35425 #endif
  35426 
  35427     if (SOC_IS_TRIDENT3X(unit)) {
  35428         return BCM_E_UNAVAIL;
  35429     }
  35430 
  35431     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35432 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  35433         || defined(BCM_TRX_SUPPORT)
  35434     if (soc_feature(unit, soc_feature_color_prio_map)) {
  35435         int index, int_pri_shift;
  35436         uint32     pri_unmap[SOC_MAX_MEM_FIELD_WORDS];
  35437         soc_mem_t  mem = EGR_PRI_CNG_MAPm;
  35438 
  35439         int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3;
  35440         if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) ||
  35441             ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  35442              (color != bcmColorRed))) {
  35443             return BCM_E_PARAM;
  35444         }
  35445 
  35446         /* EGR_PRI_CNG_MAP table is indexed with
  35447          * port[4:0] priority[2:0] CNG [1:0]
  35448          * port[5:0] priority[3:0] CNG [1:0] (TRX)
  35449          */
  35450         index = (port << (int_pri_shift + 2)) | (internal_pri << 2) |
  35451             _BCM_COLOR_ENCODING(unit, color);
  35452 
  35453         SOC_IF_ERROR_RETURN
  35454             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, pri_unmap));
  35455         *pkt_pri = soc_mem_field32_get(unit, mem, pri_unmap, PRIf);
  35456         *cfi = soc_mem_field32_get(unit, mem, pri_unmap, CFIf);
  35457         return BCM_E_NONE;
  35458     }
  35459 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  35460     return BCM_E_UNAVAIL;
  35461 }
  35462 
  35463 /*
  35464  * Function:
  35465  *      bcm_esw_port_l3_modify_set
  35466  * Description:
  35467  *      Enable/Disable ingress port based L3 unicast packet operations.
  35468  * Parameters:
  35469  *      unit - Device number
  35470  *      port - Port number
  35471  *      flags - bitmap of the packet operations to be enabled or disabled.
  35472  * Return Value:
  35473  *      BCM_E_XXX
  35474  * Notes:
  35475  *      Available on XGS3 only.
  35476  */
  35477 int
  35478 bcm_esw_port_l3_modify_set(int unit, bcm_port_t port, uint32 flags)
  35479 {
  35480 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  35481     uint64 r;
  35482     soc_reg_t reg;
  35483 
  35484     /* Make sure port module is initialized. */
  35485     PORT_INIT(unit);
  35486 
  35487     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35488     if (SOC_IS_XGS3_SWITCH(unit)) {
  35489         reg = IS_ST_PORT(unit, port) ?
  35490             IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr;
  35491     } else {
  35492         return BCM_E_UNAVAIL;
  35493     }
  35494 
  35495     if (!SOC_REG_IS_VALID(unit, reg)) {
  35496         return BCM_E_UNAVAIL;
  35497     }
  35498 
  35499     BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r));
  35500 
  35501     soc_reg64_field32_set(unit, reg, &r, L3_UC_SA_DISABLEf,
  35502                           (flags & BCM_PORT_L3_MODIFY_NO_SRCMAC) ? 1 : 0);
  35503 
  35504     soc_reg64_field32_set(unit, reg, &r, L3_UC_DA_DISABLEf,
  35505                           (flags & BCM_PORT_L3_MODIFY_NO_DSTMAC) ? 1 : 0);
  35506 
  35507     soc_reg64_field32_set(unit, reg, &r, L3_UC_TTL_DISABLEf,
  35508                           (flags & BCM_PORT_L3_MODIFY_NO_TTL) ? 1 : 0);
  35509 
  35510     soc_reg64_field32_set(unit, reg, &r, L3_UC_VLAN_DISABLEf,
  35511                           (flags & BCM_PORT_L3_MODIFY_NO_VLAN) ? 1 : 0);
  35512 
  35513     return soc_reg_set(unit, reg, port, 0, r);
  35514 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  35515     return BCM_E_UNAVAIL;
  35516 }
  35517 
  35518 /*
  35519  * Function:
  35520  *      bcm_esw_port_l3_modify_get
  35521  * Description:
  35522  *      Get ingress port based L3 unicast packet operations status.
  35523  * Parameters:
  35524  *      unit - Device number
  35525  *      port - Port number
  35526  *      flags - (OUT) pointer to uint32 where bitmap of the current L3 packet
  35527  *              operations is returned.
  35528  * Return Value:
  35529  *      BCM_E_NONE
  35530  *      BCM_E_UNAVAIL - Functionality not available
  35531  * Notes:
  35532  *      Available on XGS3 only.
  35533  */
  35534 int
  35535 bcm_esw_port_l3_modify_get(int unit, bcm_port_t port, uint32 *flags)
  35536 {
  35537 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  35538     uint64 r;
  35539     soc_reg_t reg;
  35540 
  35541     /* Make sure port module is initialized. */
  35542     PORT_INIT(unit);
  35543 
  35544     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35545     if (SOC_IS_XGS3_SWITCH(unit)) {
  35546         reg = IS_ST_PORT(unit, port) ?
  35547             IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr;
  35548     } else {
  35549         return BCM_E_UNAVAIL;
  35550     }
  35551 
  35552     if (!SOC_REG_IS_VALID(unit, reg)) {
  35553         return BCM_E_UNAVAIL;
  35554     }
  35555 
  35556     BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r));
  35557 
  35558     *flags = 0;
  35559 
  35560     if (soc_reg64_field32_get(unit, reg, r, L3_UC_SA_DISABLEf)) {
  35561         *flags |= BCM_PORT_L3_MODIFY_NO_SRCMAC;
  35562     }
  35563 
  35564     if (soc_reg64_field32_get(unit, reg, r, L3_UC_DA_DISABLEf)) {
  35565         *flags |= BCM_PORT_L3_MODIFY_NO_DSTMAC;
  35566     }
  35567 
  35568     if (soc_reg64_field32_get(unit, reg, r, L3_UC_TTL_DISABLEf)) {
  35569         *flags |= BCM_PORT_L3_MODIFY_NO_TTL;
  35570     }
  35571 
  35572     if (soc_reg64_field32_get(unit, reg, r, L3_UC_VLAN_DISABLEf)) {
  35573         *flags |= BCM_PORT_L3_MODIFY_NO_VLAN;
  35574     }
  35575 
  35576     return BCM_E_NONE;
  35577 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  35578     return BCM_E_UNAVAIL;
  35579 }
  35580 
  35581 /*
  35582  * Function:
  35583  *      bcm_esw_port_ipmc_modify_set
  35584  * Description:
  35585  *      Enable/Disable ingress port based L3 multicast packet operations.
  35586  *      If the reg EGR_IPMC_CFG2r does not contain DISABLE_TTL_CHECKf field,
  35587  *         and if flag is set , then return E_PARAM.
  35588  *             if flag is not set, then donot  validate the field.
  35589  * Parameters:
  35590  *      unit - Device number
  35591  *      port - Port number
  35592  *      flags - bitmap of the packet operations to be enabled or disabled.
  35593  * Return Value:
  35594  *      BCM_E_XXX
  35595  * Notes:
  35596  *      Available on XGS3 only.
  35597  */
  35598 int
  35599 bcm_esw_port_ipmc_modify_set(int unit, bcm_port_t port, uint32 flags)
  35600 {
  35601 #if defined(INCLUDE_L3)
  35602     int          field_count;
  35603     soc_field_t  fields[]={DISABLE_SA_REPLACEf, DISABLE_TTL_DECREMENTf,
  35604                            DISABLE_TTL_CHECKf};
  35605     uint32       values[]={0, 0, 0};
  35606 
  35607     /* Make sure port module is initialized. */
  35608     PORT_INIT(unit);
  35609 
  35610     field_count = COUNTOF(fields);
  35611     if (!soc_feature(unit, soc_feature_ip_mcast)) {
  35612         return BCM_E_UNAVAIL;
  35613     }
  35614 
  35615     if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
  35616         return BCM_E_UNAVAIL;
  35617     }
  35618 
  35619     if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) &&
  35620             !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  35621         return BCM_E_UNAVAIL;
  35622     }
  35623     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35624 
  35625 #if defined(BCM_RAPTOR1_SUPPORT)
  35626     if (SOC_IS_RAPTOR(unit)) {
  35627         return BCM_E_UNAVAIL;
  35628     }
  35629 #endif /* BCM_RAPTOR1_SUPPORT */
  35630 
  35631     values[0] = (flags & BCM_PORT_IPMC_MODIFY_NO_SRCMAC) ? 1 : 0;
  35632     values[1] = (flags & BCM_PORT_IPMC_MODIFY_NO_TTL)    ? 1 : 0;
  35633     values[2] = (flags & BCM_PORT_IPMC_CHECK_NO_TTL)     ? 1 : 0;
  35634 
  35635 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  35636     if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  35637         return soc_mem_fields32_modify(unit, EGR_IPMC_CFG2m, port,
  35638                 field_count, fields, values);
  35639     } else
  35640 #endif
  35641     {
  35642         if (values[2]) {
  35643             if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  35644                 return BCM_E_PARAM;
  35645             }
  35646         } else {
  35647             /* Donot include DISABLE_TTL_CHECKf for field validation in reg */
  35648             if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  35649                 field_count -= 1;
  35650             }
  35651         }
  35652 
  35653         return soc_reg_fields32_modify(unit, EGR_IPMC_CFG2r, port,
  35654                 field_count, fields, values);
  35655     }
  35656 #else /* INCLUDE_L3 */
  35657     return (BCM_E_UNAVAIL);
  35658 #endif /* INCLUDE_L3 */
  35659 }
  35660 
  35661 /*
  35662  * Function:
  35663  *      bcm_esw_port_ipmc_modify_get
  35664  * Description:
  35665  *      Enable/Disable ingress port based L3 multicast packet operations.
  35666  * Parameters:
  35667  *      unit - Device number
  35668  *      port - Port number
  35669  *      flags - (OUT) pointer to uint32 where bitmap of the current L3 packet
  35670  *              operations is returned.
  35671  * Return Value:
  35672  *      BCM_E_NONE
  35673  *      BCM_E_UNAVAIL - Functionality not available
  35674  * Notes:
  35675  *      Available on XGS3 only.
  35676  */
  35677 int
  35678 bcm_esw_port_ipmc_modify_get(int unit, bcm_port_t port, uint32 *flags)
  35679 {
  35680 #if defined(INCLUDE_L3)
  35681     uint32 reg_val;
  35682 
  35683     if (!soc_feature(unit, soc_feature_ip_mcast)) {
  35684         return BCM_E_UNAVAIL;
  35685     }
  35686 
  35687     if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
  35688         return BCM_E_UNAVAIL;
  35689     }
  35690 
  35691     if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) &&
  35692             !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  35693         return BCM_E_UNAVAIL;
  35694     }
  35695 
  35696 #if defined(BCM_RAPTOR1_SUPPORT)
  35697     if (SOC_IS_RAPTOR(unit)) {
  35698         return BCM_E_UNAVAIL;
  35699     }
  35700 #endif /* BCM_RAPTOR1_SUPPORT */
  35701 
  35702     /* Make sure port module is initialized. */
  35703     PORT_INIT(unit);
  35704 
  35705     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35706     if (NULL == flags) {
  35707         return (BCM_E_PARAM);
  35708     }
  35709 
  35710 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  35711     if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  35712         BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ANY, port, &reg_val));
  35713         *flags = 0;
  35714         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_SA_REPLACEf)) {
  35715             *flags |=  BCM_PORT_IPMC_MODIFY_NO_SRCMAC;
  35716         }
  35717         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_TTL_DECREMENTf)) {
  35718             *flags |=  BCM_PORT_IPMC_MODIFY_NO_TTL;
  35719         }
  35720         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_TTL_CHECKf)) {
  35721             *flags |=  BCM_PORT_IPMC_CHECK_NO_TTL;
  35722         }
  35723     } else
  35724 #endif
  35725     {
  35726         BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2r(unit, port, &reg_val));
  35727 
  35728         *flags = 0;
  35729         if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_SA_REPLACEf)) {
  35730             *flags |=  BCM_PORT_IPMC_MODIFY_NO_SRCMAC;
  35731         }
  35732         if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_TTL_DECREMENTf)) {
  35733             *flags |=  BCM_PORT_IPMC_MODIFY_NO_TTL;
  35734         }
  35735         if (SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  35736             if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val,
  35737                         DISABLE_TTL_CHECKf)) {
  35738                 *flags |=  BCM_PORT_IPMC_CHECK_NO_TTL;
  35739             }
  35740         }
  35741     }
  35742     return (BCM_E_NONE);
  35743 #else /* INCLUDE_L3 */
  35744     return (BCM_E_UNAVAIL);
  35745 #endif /* INCLUDE_L3 */
  35746 }
  35747 
  35748 /*
  35749  * Function:
  35750  *      _bcm_port_force_forward_linkscan_handler
  35751  * Description:
  35752  *      Called from linkscan handler when port toggles.
  35753  *      Adds/removes entry from LOCAL_SW_DISABLE_DEFAULT_PBM
  35754  * Parameters:
  35755  *      unit - Device number
  35756  *      info - port info
  35757  * Return Value:
  35758  *      BCM_E_XXX
  35759  */
  35760 void
  35761 _bcm_port_force_forward_linkscan_handler(int unit,
  35762                 bcm_port_t port, bcm_port_info_t *info)
  35763 {
  35764     bcm_port_t local_port;
  35765     bcm_pbmp_t *sw_disable_pbmp_linkstate =
  35766                             p_linkstate[unit].sw_disable_pbmp_linkstate;
  35767     int rv = BCM_E_NONE;
  35768 
  35769     if (!info) {
  35770         return;
  35771     }
  35772 
  35773     if (sw_disable_pbmp_linkstate == NULL) {
  35774         return;
  35775     }
  35776     if (p_linkstate[unit].num_pbmp_entry) {
  35777         PBMP_ALL_ITER(unit, local_port) {
  35778             if (BCM_PBMP_MEMBER(sw_disable_pbmp_linkstate[local_port],
  35779                                         port)) {
  35780                 if (info->linkstatus == BCM_PORT_LINK_STATUS_DOWN) {
  35781                     p_linkstate[unit].lock = 1;
  35782                     rv = bcm_esw_port_force_forward_mode_set(unit, local_port,
  35783                                     port, BCM_PORT_FORCE_FORWARD_DISABLE);
  35784                     p_linkstate[unit].lock = 0;
  35785                 } else if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) {
  35786                     p_linkstate[unit].lock = 1;
  35787                     rv = bcm_esw_port_force_forward_mode_set(unit, local_port,
  35788                                     port, BCM_PORT_FORCE_FORWARD_ALL);
  35789                     p_linkstate[unit].lock = 0;
  35790                 }
  35791                 if (BCM_FAILURE(rv)) {
  35792                     LOG_WARN(BSL_LS_BCM_PORT,
  35793                             (BSL_META_U(unit,
  35794                         "bcm_esw_port_force_forward_mode_set failed for "
  35795                             "port %d, dest_port %d, link_state %d. rv = %d\n"),
  35796                             local_port, port, info->linkstatus, rv));
  35797                 }
  35798             }
  35799         }
  35800     }
  35801 }
  35802 
  35803 #if defined(BCM_TRIUMPH3_SUPPORT)
  35804 /*
  35805  * Function:
  35806  *      _bcm_port_force_forward_init
  35807  * Purpose:
  35808  *      Initialize the port_forward entries
  35809  * Parameters:
  35810  *      unit  - SOC unit #
  35811  * Returns:
  35812  *      BCM_E_XXX
  35813  */
  35814 int
  35815 _bcm_port_force_forward_init(int unit)
  35816 {
  35817     p_linkstate[unit].num_pbmp_entry = 0;
  35818 
  35819     if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) {
  35820         sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate);
  35821         p_linkstate[unit].sw_disable_pbmp_linkstate = NULL;
  35822     }
  35823 
  35824     p_linkstate[unit].sw_disable_pbmp_linkstate = (bcm_pbmp_t*) sal_alloc(
  35825                 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS,
  35826                 "SW disable pbmp linkstate");
  35827     if (p_linkstate[unit].sw_disable_pbmp_linkstate == NULL) {
  35828         return BCM_E_MEMORY;
  35829     }
  35830     sal_memset(p_linkstate[unit].sw_disable_pbmp_linkstate, 0,
  35831                 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS);
  35832     return BCM_E_NONE;
  35833 }
  35834 
  35835 /*
  35836  * Function:
  35837  *      _bcm_port_force_forward_deinit
  35838  * Purpose:
  35839  *      Uninitialize the port_forward entries
  35840  * Parameters:
  35841  *      unit  - SOC unit #
  35842  * Returns:
  35843  *      BCM_E_XXX
  35844  */
  35845 int
  35846 _bcm_port_force_forward_deinit(int unit)
  35847 {
  35848     if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) {
  35849         sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate);
  35850         p_linkstate[unit].sw_disable_pbmp_linkstate = NULL;
  35851         p_linkstate[unit].num_pbmp_entry = 0;
  35852     }
  35853     return BCM_E_NONE;
  35854 }
  35855 
  35856 /*
  35857  * Function:
  35858  *      _bcm_port_force_forward_add
  35859  * Purpose:
  35860  *      Add/Deletes an entry into the port_forward DB.
  35861  * Parameters:
  35862  *      unit  - SOC unit #
  35863  *      local_port - Local port/Ingress port
  35864  *      egr_port - destination port. Set 0 to delete it.
  35865  * Returns:
  35866  *      BCM_E_XXX
  35867  */
  35868 int
  35869 _bcm_port_force_forward_add(int unit, bcm_port_t local_port,
  35870                                         bcm_port_t egr_port)
  35871 {
  35872     bcm_pbmp_t *sw_disable_pbmp_linkstate =
  35873                     p_linkstate[unit].sw_disable_pbmp_linkstate;
  35874     if (!sw_disable_pbmp_linkstate) {
  35875         return BCM_E_INTERNAL;
  35876     }
  35877     /* Lock is taken while calling bcm_esw_port_force_forward_mode_set
  35878      * from the linkscan handler. It is not taken when called by user.
  35879      * It is to ensure that only HW tables are written to and the
  35880      * corresponding SW datastructure remains intact.
  35881      */
  35882     if (p_linkstate[unit].lock) {
  35883         return BCM_E_NONE;
  35884     }
  35885     BCM_PBMP_PORT_SET(sw_disable_pbmp_linkstate[local_port], egr_port);
  35886     p_linkstate[unit].num_pbmp_entry++;
  35887     return BCM_E_NONE;
  35888 }
  35889 
  35890 #ifdef BCM_WARM_BOOT_SUPPORT
  35891 #define _BCM_PORT_WB_MAX_PBMP_V1_5 256
  35892 
  35893 /*
  35894  * Function:
  35895  *     _bcm_port_force_forward_sync
  35896  * Purpose:
  35897  *     Sync port_forward DB to scache.
  35898  * Parameters:
  35899  *     unit - Device unit number
  35900  *     scache_ptr - Scache pointer.
  35901  * Returns:
  35902  *     BCM_E_XXX
  35903  */
  35904 int
  35905 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr)
  35906 {
  35907     bcm_port_t local_port, dst_port;
  35908     bcm_pbmp_t *sw_disable_pbmp_linkstate = p_linkstate[unit].sw_disable_pbmp_linkstate;
  35909     int port_count = 0, iter = 0;
  35910     SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5);
  35911 
  35912     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  35913         return BCM_E_INTERNAL;
  35914     }
  35915 
  35916     PBMP_ALL_ITER(unit, local_port) {
  35917         port_count = 0;
  35918         iter = 0;
  35919         sal_memset(&port_bmp, 0, sizeof(port_bmp));
  35920         BCM_PBMP_COUNT(sw_disable_pbmp_linkstate[local_port], port_count);
  35921         if (BCM_PBMP_NOT_NULL(sw_disable_pbmp_linkstate[local_port])) {
  35922             BCM_PBMP_ITER(sw_disable_pbmp_linkstate[local_port], dst_port) {
  35923                 if(_SHR_BITDCLSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) <
  35924                    _SHR_BITDCLSIZE(dst_port)) {
  35925                     /* coverity[dead_error_line] */
  35926                     continue;
  35927                 }
  35928                 /* coverity[overrun-local] */
  35929                 SHR_BITSET(port_bmp, dst_port);
  35930                 iter++;
  35931                 if (iter >= port_count) {
  35932                     break;
  35933                 }
  35934             }
  35935         }
  35936         sal_memcpy(*scache_ptr, port_bmp, sizeof(port_bmp));
  35937         *scache_ptr += sizeof(port_bmp);
  35938     }
  35939 
  35940     return BCM_E_NONE;
  35941 }
  35942 
  35943 /*
  35944  * Function:
  35945  *     _bcm_port_force_forward_reinit
  35946  * Purpose:
  35947  *     Retrieve port_forward from hardware and scache.
  35948  * Parameters:
  35949  *     unit - Device unit number
  35950  *     scache_ptr - Scache pointer.
  35951  * Returns:
  35952  *     BCM_E_XXX
  35953  */
  35954 int
  35955 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr)
  35956 {
  35957     bcm_port_t local_port;
  35958     int idx;
  35959     bcm_pbmp_t *sw_disable_pbmp_linkstate =
  35960                             p_linkstate[unit].sw_disable_pbmp_linkstate;
  35961     SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5);
  35962 
  35963     p_linkstate[unit].num_pbmp_entry = 0;
  35964     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  35965         return BCM_E_PARAM;
  35966     }
  35967 
  35968     sal_memset(&port_bmp, 0, sizeof(port_bmp));
  35969     sal_memset(sw_disable_pbmp_linkstate, 0, sizeof(bcm_pbmp_t));
  35970     PBMP_ALL_ITER(unit, local_port) {
  35971         sal_memcpy(&port_bmp, *scache_ptr, sizeof(port_bmp));
  35972         *scache_ptr += sizeof(port_bmp);
  35973         if (!SHR_BITNULL_RANGE(port_bmp, 0, _BCM_PORT_WB_MAX_PBMP_V1_5)){
  35974             int bitcount = 0;
  35975             SHR_BITCOUNT_RANGE(port_bmp, bitcount, 0, _BCM_PORT_WB_MAX_PBMP_V1_5);
  35976             for(idx = 0; (idx < _BCM_PORT_WB_MAX_PBMP_V1_5) && (bitcount); idx++) {
  35977                 if(SHR_BITGET(port_bmp, idx)) {
  35978                     BCM_PBMP_PORT_ADD(sw_disable_pbmp_linkstate[local_port], idx);
  35979                     p_linkstate[unit].num_pbmp_entry++;
  35980                     bitcount--;
  35981                 }
  35982             }
  35983         }
  35984     }
  35985 
  35986     return BCM_E_NONE;
  35987 }
  35988 
  35989 /*
  35990  * Function:
  35991  *     _bcm_port_force_forward_scache_size
  35992  * Purpose:
  35993  *     Get the size of the port_forward for scache
  35994  * Parameters:
  35995  *     unit - Device unit number
  35996  *     size - size of scache
  35997  * Returns:
  35998  *     BCM_E_XXX
  35999  */
  36000 int
  36001 _bcm_port_force_forward_scache_size(int unit, int *size)
  36002 {
  36003     int port_forward_size;
  36004     int port_count = 0;
  36005     bcm_port_t local_port;
  36006 
  36007     if (!size) {
  36008         return BCM_E_PARAM;
  36009     }
  36010 
  36011     /* We prefer to use a predefined size of _BCM_PORT_WB_MAX_PBMP_V1_5
  36012      * for warmboot instead of bcm_pbmp_t. This is because of any future
  36013      * increase in max port count for new devices which may change the
  36014      * size of bcm_bcmp_t.
  36015      */
  36016     PBMP_ALL_ITER(unit, local_port) {
  36017         port_count++;
  36018     }
  36019     port_forward_size = SHR_BITALLOCSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) * port_count;
  36020 
  36021     *size = port_forward_size;
  36022     return BCM_E_NONE;
  36023 }
  36024 #endif /* BCM_WARM_BOOT_SUPPORT */
  36025 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  36026 
  36027 /*
  36028  * Function:
  36029  *      bcm_port_force_forward_mode_set
  36030  * Purpose:
  36031  *      Set egress override port mode.
  36032  * Parameters:
  36033  *      unit - (IN) Unit number.
  36034  *      port - (IN) Port number
  36035  *      egr_port - (IN) Egress port number
  36036  *      flags - (IN) Force forward flags from PORT_FORCE_FORWARD_*
  36037  * Returns:
  36038  *      BCM_E_xxx
  36039  * Notes:
  36040  */
  36041 int
  36042 bcm_esw_port_force_forward_mode_set(int unit, bcm_port_t port,
  36043                                     bcm_port_t egr_port, uint32 flags)
  36044 {
  36045     /* Make sure port module is initialized. */
  36046     PORT_INIT(unit);
  36047 
  36048 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \
  36049     || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  36050     if (soc_feature(unit, soc_feature_force_forward)) {
  36051 
  36052         int enable = FALSE;
  36053 
  36054         if ((0 != (flags & BCM_PORT_FORCE_FORWARD_LOCAL) &&
  36055              !SOC_IS_TRX(unit))) {
  36056             /* We don't support local only mode on pre-TRX devices */
  36057             return BCM_E_PARAM;
  36058         }
  36059 
  36060         if (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL |
  36061                            BCM_PORT_FORCE_FORWARD_LOCAL))) {
  36062             enable = TRUE;
  36063         }
  36064 
  36065         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  36066         if (enable) {
  36067             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egr_port,
  36068                                                              &egr_port));
  36069         }
  36070 
  36071 #if defined(BCM_TRIUMPH_SUPPORT)
  36072         if (SOC_IS_TR_VL(unit)) {
  36073             pbmp_t pbmp;
  36074             uint64 val;
  36075             int cpu_hg_index = 0;
  36076 
  36077             COMPILER_64_SET(val, 0, 0);
  36078             SOC_PBMP_CLEAR(pbmp);
  36079             if (enable) {
  36080                 SOC_PBMP_PORT_SET(pbmp, egr_port);
  36081             }
  36082             if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) {
  36083                 local_sw_disable_default_pbm_entry_t entry;
  36084                 sal_memset(&entry, 0, sizeof(entry));
  36085                 soc_mem_pbmp_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  36086                                        &entry, PORT_BITMAPf, &pbmp);
  36087                 BCM_IF_ERROR_RETURN
  36088                     (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  36089                                    MEM_BLOCK_ANY, port, &entry));
  36090 
  36091                 cpu_hg_index = SOC_IS_KATANA2(unit) ?
  36092                                SOC_INFO(unit).cpu_hg_pp_port_index :
  36093                                SOC_INFO(unit).cpu_hg_index;
  36094                 if (IS_CPU_PORT(unit, port)) {
  36095                     BCM_IF_ERROR_RETURN
  36096                         (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  36097                                        MEM_BLOCK_ANY, cpu_hg_index, &entry));
  36098                 }
  36099             } else {
  36100 #if defined(BCM_GREYHOUND2_SUPPORT)
  36101                 if (SOC_IS_GREYHOUND2(unit)) {
  36102                     uint64 val_hi, field_val;
  36103 
  36104                     COMPILER_64_SET(val_hi, 0, 0);
  36105                     COMPILER_64_SET(field_val,
  36106                         SOC_PBMP_WORD_GET(pbmp, 1), SOC_PBMP_WORD_GET(pbmp, 0));
  36107                     soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  36108                         &val, PORT_BITMAP_LOf, field_val);
  36109 
  36110                     COMPILER_64_SET(field_val,
  36111                         0, SOC_PBMP_WORD_GET(pbmp, 2));
  36112                     soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_HIr,
  36113                         &val_hi, PORT_BITMAP_LOf, field_val);
  36114 
  36115                     
  36116                     if (IS_ST_PORT(unit, port)) {
  36117                         BCM_IF_ERROR_RETURN
  36118                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  36119                         BCM_IF_ERROR_RETURN
  36120                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  36121                     } else {
  36122                         BCM_IF_ERROR_RETURN
  36123                             (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  36124                         BCM_IF_ERROR_RETURN
  36125                             (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  36126                         if (IS_CPU_PORT(unit, port)) {
  36127                             BCM_IF_ERROR_RETURN
  36128                                 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  36129                             BCM_IF_ERROR_RETURN
  36130                                 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  36131                         }
  36132                     }
  36133                 } else
  36134 #endif /* BCM_GREYHOUND2_SUPPORT */
  36135                 {
  36136                     soc_reg64_field32_set(unit
  36137                                           , LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  36138                                           &val, PORT_BITMAP_LOf,
  36139                                           SOC_PBMP_WORD_GET(pbmp, 0));
  36140                     if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  36141                        !SOC_IS_GREYHOUND(unit)) {
  36142                         soc_reg64_field32_set(unit,
  36143                                               LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  36144                                               &val, PORT_BITMAP_HIf,
  36145                                               SOC_PBMP_WORD_GET(pbmp, 1));
  36146                     }
  36147                     
  36148                     if (IS_ST_PORT(unit, port)) {
  36149                         BCM_IF_ERROR_RETURN
  36150                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  36151                                                                      val));
  36152                     } else {
  36153                         BCM_IF_ERROR_RETURN
  36154                             (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  36155                                                                     val));
  36156                         if (IS_CPU_PORT(unit, port)) {
  36157                             BCM_IF_ERROR_RETURN
  36158                                 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  36159                                                                          val));
  36160                         }
  36161                     }
  36162                 }
  36163             }
  36164         }  else
  36165 #endif /* BCM_TRIUMPH_SUPPORT */
  36166         {
  36167 #if defined(BCM_FIREBOLT2_SUPPORT) ||  defined(BCM_RAVEN_SUPPORT)  || \
  36168             defined(BCM_SCORPION_SUPPORT)
  36169             if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  36170                  SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) {
  36171                 BCM_IF_ERROR_RETURN
  36172                     (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port,
  36173                                          (enable) ? 1 << egr_port : 0));
  36174             } else
  36175 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
  36176             {
  36177                 BCM_IF_ERROR_RETURN
  36178                     (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port,
  36179                                     (enable) ? 1 << egr_port : 0));
  36180             }
  36181         }
  36182 
  36183 #if defined(BCM_TRIUMPH3_SUPPORT)
  36184         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  36185             int rv;
  36186             rv = _bcm_port_force_forward_add(unit, port,
  36187                             (enable) ? egr_port : 0);
  36188             if (BCM_FAILURE(rv)) {
  36189                 return rv;
  36190             }
  36191         }
  36192 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  36193 
  36194 #if defined(BCM_TRX_SUPPORT)
  36195         if (SOC_IS_TRX(unit)) {
  36196             uint32 mode;
  36197 
  36198             mode = (flags & BCM_PORT_FORCE_FORWARD_LOCAL) ?
  36199                 _BCM_TRX_PORT_FORCE_FORWARD_LOCAL :
  36200                 ((flags & BCM_PORT_FORCE_FORWARD_ALL) ?
  36201                  _BCM_TRX_PORT_FORCE_FORWARD_ALL :
  36202                  _BCM_TRX_PORT_FORCE_FORWARD_DISABLE);
  36203 
  36204             return soc_reg_field32_modify(unit, LOCAL_SW_DISABLE_CTRLr,
  36205                                           port, SW_MODEf, mode);
  36206         } else
  36207 #endif
  36208         {
  36209             return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  36210                                          LOCAL_SW_DISABLEf,
  36211                                          (enable) ? 1 : 0);
  36212         }
  36213     }
  36214 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \
  36215           || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  36216     return BCM_E_UNAVAIL;
  36217 }
  36218 
  36219 /*
  36220  * Function:
  36221  *      bcm_port_force_forward_mode_get
  36222  * Purpose:
  36223  *      Get egress override port.
  36224  * Parameters:
  36225  *      unit - (IN) Unit number.
  36226  *      port - (IN) Port number
  36227  *      egr_port - (OUT) Egress port number
  36228  *      flags - (OUT) Force forward flags from PORT_FORCE_FORWARD_*
  36229  * Returns:
  36230  *      BCM_E_xxx
  36231  * Notes:
  36232  */
  36233 int
  36234 bcm_esw_port_force_forward_mode_get(int unit, bcm_port_t port,
  36235                                     bcm_port_t *egr_port, uint32 *flags)
  36236 {
  36237     /* Make sure port module is initialized. */
  36238     PORT_INIT(unit);
  36239 
  36240 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \
  36241         || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  36242     if (soc_feature(unit, soc_feature_force_forward)) {
  36243         pbmp_t pbmp;
  36244         uint32 egr_pbm;
  36245         int ep, enabled;
  36246 
  36247         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  36248 
  36249 #if defined(BCM_TRX_SUPPORT)
  36250         if (SOC_IS_TRX(unit)) {
  36251             uint32 val_32, mode;
  36252 
  36253             BCM_IF_ERROR_RETURN
  36254                 (READ_LOCAL_SW_DISABLE_CTRLr(unit, port, &val_32));
  36255             mode = soc_reg_field_get(unit, LOCAL_SW_DISABLE_CTRLr,
  36256                                          val_32, SW_MODEf);
  36257 
  36258             if (_BCM_TRX_PORT_FORCE_FORWARD_LOCAL == mode) {
  36259                 *flags = BCM_PORT_FORCE_FORWARD_LOCAL;
  36260             } else if (_BCM_TRX_PORT_FORCE_FORWARD_ALL == mode) {
  36261                 *flags = BCM_PORT_FORCE_FORWARD_ALL;
  36262             } else {
  36263                 *flags = BCM_PORT_FORCE_FORWARD_DISABLE;
  36264             }
  36265             enabled = (BCM_PORT_FORCE_FORWARD_DISABLE != mode);
  36266         } else
  36267 #endif
  36268         {
  36269             BCM_IF_ERROR_RETURN
  36270                 (_bcm_esw_port_tab_get(unit, port, LOCAL_SW_DISABLEf, &enabled));
  36271             *flags = enabled ? BCM_PORT_FORCE_FORWARD_ALL :
  36272                 BCM_PORT_FORCE_FORWARD_DISABLE;
  36273         }
  36274 
  36275         if (enabled) {
  36276             _bcm_gport_dest_t   dest;
  36277             bcm_module_t        modid;
  36278             int                 isGport = 0;
  36279 
  36280             _bcm_gport_dest_t_init(&dest);
  36281 #if defined(BCM_TRIUMPH_SUPPORT)
  36282             if (SOC_IS_TR_VL(unit)) {
  36283                 uint64 val;
  36284 
  36285                 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) {
  36286                     local_sw_disable_default_pbm_entry_t entry;
  36287                     BCM_IF_ERROR_RETURN
  36288                         (soc_mem_read(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  36289                                       MEM_BLOCK_ANY, port, &entry));
  36290                     soc_mem_pbmp_field_get(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  36291                                            &entry, PORT_BITMAPf, &pbmp);
  36292                 } else {
  36293 #if defined(BCM_GREYHOUND2_SUPPORT)
  36294                     if (SOC_IS_GREYHOUND2(unit)) {
  36295                         BCM_IF_ERROR_RETURN
  36296                             (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, &val));
  36297 
  36298                         egr_pbm = soc_reg64_field32_get(unit,
  36299                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  36300                                                   val, OVER_LOf);
  36301                         SOC_PBMP_CLEAR(pbmp);
  36302                         SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  36303 
  36304                         egr_pbm = soc_reg64_field32_get(unit,
  36305                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  36306                                                   val, OVER_HIf);
  36307                         SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm);
  36308 
  36309                         BCM_IF_ERROR_RETURN
  36310                             (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, &val));
  36311 
  36312                         egr_pbm = soc_reg64_field32_get(unit,
  36313                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_HIr,
  36314                                                   val, OVER_LOf);
  36315                         SOC_PBMP_WORD_SET(pbmp, 2, egr_pbm);
  36316                     } else
  36317 #endif /* BCM_GREYHOUND2_SUPPORT */
  36318                     {
  36319                         BCM_IF_ERROR_RETURN
  36320                             (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  36321                                                                    &val));
  36322                         egr_pbm =
  36323                             soc_reg64_field32_get(unit,
  36324                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  36325                                                   val, PORT_BITMAP_LOf);
  36326                         SOC_PBMP_CLEAR(pbmp);
  36327                         SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  36328                         if ((egr_pbm == 0) &&
  36329                             (!SOC_IS_ENDURO(unit)) && (!SOC_IS_HURRICANEX(unit)) &&
  36330                             (!SOC_IS_GREYHOUND(unit))) {
  36331                             egr_pbm = soc_reg64_field32_get
  36332                                 (unit,  LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  36333                                  val, PORT_BITMAP_HIf);
  36334                             SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm);
  36335                         }
  36336                     }
  36337                 }
  36338             } else
  36339 #endif /* BCM_TRIUMPH_SUPPORT */
  36340             if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  36341                  SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) {
  36342                 BCM_IF_ERROR_RETURN
  36343                     (READ_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm));
  36344                 SOC_PBMP_CLEAR(pbmp);
  36345                 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  36346             } else {
  36347                 BCM_IF_ERROR_RETURN
  36348                     (READ_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm));
  36349                 SOC_PBMP_CLEAR(pbmp);
  36350                 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  36351             }
  36352             if (SOC_PBMP_IS_NULL(pbmp)) {
  36353                 return BCM_E_INTERNAL;
  36354             }
  36355             /* Convert port bitmap into port number */
  36356             SOC_PBMP_ITER(pbmp, ep) {
  36357                 break;
  36358             }
  36359             BCM_IF_ERROR_RETURN
  36360                 (bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport));
  36361             if (isGport) {
  36362                 /* ignore return code to suport devices w/out modid assigned */
  36363                 (void)bcm_esw_stk_my_modid_get(unit, &modid);
  36364 
  36365                 if (BCM_MODID_INVALID == modid) {
  36366                     dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
  36367                 } else {
  36368                     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  36369                     dest.modid = modid;
  36370                 }
  36371                 dest.port = ep;
  36372 
  36373                 BCM_IF_ERROR_RETURN
  36374                     (_bcm_esw_gport_construct(unit, &dest, &ep));
  36375             }
  36376             *egr_port = ep;
  36377         }
  36378         return BCM_E_NONE;
  36379     }
  36380 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \
  36381           || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  36382     return BCM_E_UNAVAIL;
  36383 }
  36384 
  36385 /*
  36386  * Function:
  36387  *      bcm_esw_port_force_forward_set
  36388  * Purpose:
  36389  *      This function allows packets to bypass the normal forwarding
  36390  *      logic and be sent out on a specific port instead.
  36391  * Parameters:
  36392  *      unit - Device number
  36393  *      port - Port number
  36394  *      egr_port - Egress port number
  36395  *      enable - Bypass switching logic and forward to egr_port
  36396  * Return Value:
  36397  *      BCM_E_NONE
  36398  *      BCM_E_UNAVAIL - Functionality not available
  36399  * Notes:
  36400  *      All normal ingress processing (table lookups etc.) is still
  36401  *      performed and used for contructing the Higig header if the
  36402  *      forced egress port is a Higig port.
  36403  */
  36404 int
  36405 bcm_esw_port_force_forward_set(int unit, bcm_port_t port,
  36406                                bcm_port_t egr_port, int enable)
  36407 {
  36408     return bcm_esw_port_force_forward_mode_set(unit, port, egr_port,
  36409                          enable ? BCM_PORT_FORCE_FORWARD_ALL :
  36410                                   BCM_PORT_FORCE_FORWARD_DISABLE);
  36411 }
  36412 
  36413 /*
  36414  * Function:
  36415  *      bcm_esw_port_force_forward_get
  36416  * Purpose:
  36417  *      Determine forced forwarding setting for a port.
  36418  * Parameters:
  36419  *      unit - Device number
  36420  *      port - Port number
  36421  *      egr_port - (OUT) Egress port number
  36422  *      enabled - (OUT) Forced forwarding enabled
  36423  * Return Value:
  36424  *      BCM_E_NONE
  36425  *      BCM_E_UNAVAIL - Functionality not available
  36426  * Notes:
  36427  *      If the value of enabled is zero, the value of egr_port should
  36428  *      be ignored.
  36429  */
  36430 int
  36431 bcm_esw_port_force_forward_get(int unit, bcm_port_t port,
  36432                                bcm_port_t *egr_port, int *enabled)
  36433 {
  36434     uint32 flags;
  36435 
  36436     /* Make sure port module is initialized. */
  36437     PORT_INIT(unit);
  36438 
  36439     BCM_IF_ERROR_RETURN
  36440         (bcm_esw_port_force_forward_mode_get(unit, port, egr_port, &flags));
  36441 
  36442     *enabled = (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL |
  36443                               BCM_PORT_FORCE_FORWARD_LOCAL)));
  36444     return BCM_E_NONE;
  36445 }
  36446 
  36447 #if defined(INCLUDE_L3)
  36448 /*
  36449  * Function:
  36450  *      _bcm_esw_port_ecmp_dlb_link_status_set
  36451  * Purpose:
  36452  *      Set ECMP DLB port link status.
  36453  * Parameters:
  36454  *      unit    - (IN) SOC unit number.
  36455  *      port    - (IN) Port, not Gport.
  36456  *      status  - (IN) ECMP DLB port link status.
  36457  * Returns:
  36458  *      BCM_E_xxx
  36459  */
  36460 int
  36461 _bcm_esw_port_ecmp_dlb_link_status_set(int unit, bcm_port_t port,
  36462                                        int status)
  36463 {
  36464     int rv = BCM_E_UNAVAIL;
  36465 
  36466 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  36467     if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) {
  36468         rv = _bcm_th2_l3_egress_ecmp_port_status_set(unit, port, status);
  36469     }
  36470 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
  36471 
  36472     return rv;
  36473 }
  36474 #endif /* INCLUDE_L3 */
  36475 
  36476 
  36477 #if defined(INCLUDE_L3)
  36478 /*
  36479  * Function:
  36480  *      _bcm_esw_port_ecmp_dlb_link_status_get
  36481  * Purpose:
  36482  *      Get ECMP DLB port link status.
  36483  * Parameters:
  36484  *      unit    - (IN) SOC unit number.
  36485  *      port    - (IN) Port, not Gport.
  36486  *      status  - (OUT) ECMP DLB port link status.
  36487  * Returns:
  36488  *      BCM_E_xxx
  36489  */
  36490 int
  36491 _bcm_esw_port_ecmp_dlb_link_status_get(int unit, bcm_port_t port,
  36492                                        int *status)
  36493 {
  36494     int rv = BCM_E_UNAVAIL;
  36495 
  36496     if (status == NULL) {
  36497         return BCM_E_PARAM;
  36498     }
  36499 
  36500 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  36501     if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) {
  36502        rv = _bcm_th2_l3_egress_ecmp_port_status_get(unit, port, status);
  36503     }
  36504 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
  36505 
  36506     return rv;
  36507 }
  36508 #endif /* INCLUDE_L3 */
  36509 
  36510 
  36511 
  36512 /*
  36513  * Function:
  36514  *      _bcm_esw_port_err_sym_detect_set
  36515  * Description:
  36516  *      Enable/Disable XAUI error symbol monitoring feature.
  36517  * Parameters:
  36518  *      unit - Device number
  36519  *      port - Port number
  36520  *      enable - TRUE, enable |E| monitoring feature on the port.
  36521  *               FALSE, disable |E| monitoring feature on the port.
  36522  * Return Value:
  36523  *      BCM_E_NONE
  36524  *      BCM_E_UNAVAIL - Functionality not available
  36525  */
  36526 #ifdef BCM_XGS3_SWITCH_SUPPORT
  36527 STATIC int
  36528 _bcm_esw_port_err_sym_detect_set(int unit, bcm_port_t port, int enable)
  36529 {
  36530     int rv;
  36531     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  36532 
  36533     LOG_INFO(BSL_LS_BCM_PORT,
  36534              (BSL_META_U(unit,
  36535                          "_bcm_esw_port_err_sym_detect_set: u=%d p=%d enable=%d\n"),
  36536               unit, port, enable));
  36537 
  36538     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  36539 #ifdef BCM_GXPORT_SUPPORT
  36540         || IS_GX_PORT(unit, port)
  36541 #endif /* BCM_GXPORT_SUPPORT */
  36542                                  ) {
  36543         PORT_LOCK(unit);
  36544         rv = soc_xaui_err_sym_detect_set(unit, port, enable);
  36545         PORT_UNLOCK(unit);
  36546     } else {
  36547         rv = BCM_E_UNAVAIL;
  36548     }
  36549 
  36550 
  36551     return rv;
  36552 }
  36553 #endif
  36554 
  36555 /*
  36556  * Function:
  36557  *      _bcm_esw_port_err_sym_detect_get
  36558  * Description:
  36559  *      Get the status of XAUI error symbol monitoring feature.
  36560  * Parameters:
  36561  *      unit - Device number
  36562  *      port - Port number
  36563  *      status - (OUT) TRUE, port is enabled, FALSE port is disabled.
  36564  * Return Value:
  36565  *      BCM_E_NONE
  36566  *      BCM_E_UNAVAIL - Functionality not available
  36567  */
  36568 #ifdef BCM_XGS3_SWITCH_SUPPORT
  36569 STATIC int
  36570 _bcm_esw_port_err_sym_detect_get(int unit, bcm_port_t port, int *status)
  36571 {
  36572     int rv;
  36573     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  36574 
  36575     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  36576 #ifdef BCM_GXPORT_SUPPORT
  36577         || IS_GX_PORT(unit, port)
  36578 #endif /* BCM_GXPORT_SUPPORT */
  36579                                  ) {
  36580         PORT_LOCK(unit);
  36581         rv = soc_xaui_err_sym_detect_get(unit, port, status);
  36582         PORT_UNLOCK(unit);
  36583     } else {
  36584         rv = BCM_E_UNAVAIL;
  36585     }
  36586 
  36587     LOG_INFO(BSL_LS_BCM_PORT,
  36588              (BSL_META_U(unit,
  36589                          "_bcm_esw_port_err_sym_detect_get: u=%d p=%d status=%d\n"),
  36590               unit, port, *status));
  36591 
  36592     return rv;
  36593 }
  36594 #endif
  36595 
  36596 /*
  36597  * Function:
  36598  *      _bcm_esw_port_err_sym_count_get
  36599  * Description:
  36600  *      Get the number of |E| symbol in XAUI lanes since last read.
  36601  *      The |E| symbol count is cleared on read.
  36602  * Parameters:
  36603  *      unit - Device number
  36604  *      port - Port number
  36605  *      count - (OUT) Number of |E| error since last read.
  36606  * Return Value:
  36607  *      BCM_E_NONE
  36608  *      BCM_E_UNAVAIL - Functionality not available
  36609  *      BCM_E_INIT    - Error symbol detect feature is not enabled
  36610  */
  36611 STATIC int
  36612 _bcm_esw_port_err_sym_count_get(int unit, bcm_port_t port, int *count)
  36613 {
  36614     int rv;
  36615     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  36616 
  36617     rv = BCM_E_UNAVAIL;
  36618 
  36619 #ifdef BCM_XGS3_SWITCH_SUPPORT
  36620 
  36621     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  36622 #ifdef BCM_GXPORT_SUPPORT
  36623         || IS_GX_PORT(unit, port)
  36624 #endif /* BCM_GXPORT_SUPPORT */
  36625                                  ) {
  36626         PORT_LOCK(unit);
  36627         rv = soc_xaui_err_sym_count(unit, port, count);
  36628         PORT_UNLOCK(unit);
  36629     }
  36630 #endif
  36631 
  36632     LOG_INFO(BSL_LS_BCM_PORT,
  36633              (BSL_META_U(unit,
  36634                          "_bcm_esw_port_err_sym_count_get: u=%d p=%d count=%d\n"),
  36635               unit, port, *count));
  36636 
  36637     return rv;
  36638 }
  36639 
  36640 STATIC int
  36641 _bcm_esw_port_control_bridge_set(int unit, bcm_port_t port, int value)
  36642 {
  36643     int rv = BCM_E_UNAVAIL;
  36644 
  36645 #ifdef BCM_TRIUMPH_SUPPORT
  36646     if (SOC_IS_TR_VL(unit)) {
  36647         bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  36648 
  36649         if (IS_E_PORT(unit, port)
  36650             || IS_CPU_PORT(unit, port)
  36651             || IS_HG_PORT(unit, port)) {
  36652             if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) {
  36653                 port_bridge_bmap_entry_t entry;
  36654 
  36655                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm,
  36656                             MEM_BLOCK_ANY, 0, &entry));
  36657                 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry,
  36658                         BITMAPf, &pbmp);
  36659                 if (value && !SOC_PBMP_MEMBER(pbmp, port)) {
  36660                     SOC_PBMP_PORT_ADD(pbmp, port);
  36661                 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) {
  36662                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36663                 } else {
  36664                     return BCM_E_NONE;
  36665                 }
  36666                 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry,
  36667                         BITMAPf, &pbmp);
  36668                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm,
  36669                             MEM_BLOCK_ANY, 0, &entry));
  36670             }
  36671             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_64r)) {
  36672                 uint64      buf64;           /* Buffer for reg64 value. */
  36673                 SOC_PBMP_CLEAR(pbmp);
  36674 
  36675                 BCM_IF_ERROR_RETURN
  36676                     (READ_PORT_BRIDGE_BMAP_64r(unit, &buf64));
  36677 
  36678                 /* Set l3 port bitmap. */
  36679                 SOC_PBMP_WORD_SET(pbmp, 0,
  36680                         soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r,
  36681                             buf64, BITMAP_LOf));
  36682                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  36683                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  36684                     SOC_PBMP_WORD_SET(pbmp, 1,
  36685                             soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r,
  36686                                     buf64, BITMAP_HIf));
  36687                 }
  36688 
  36689                 if (SOC_PBMP_MEMBER(pbmp, port) && value) {
  36690                     return BCM_E_NONE;
  36691                 }
  36692                 if (!SOC_PBMP_MEMBER(pbmp, port) && !value) {
  36693                     return BCM_E_NONE;
  36694                 }
  36695                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  36696                     SOC_PBMP_PORT_ADD(pbmp, port);
  36697                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  36698                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36699                 }
  36700 
  36701                 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r,
  36702                         &buf64, BITMAP_LOf,
  36703                         SOC_PBMP_WORD_GET(pbmp, 0));
  36704                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  36705                         !SOC_IS_GREYHOUND(unit)) {
  36706                     soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r,
  36707                             &buf64, BITMAP_HIf,
  36708                             SOC_PBMP_WORD_GET(pbmp, 1));
  36709                 }
  36710 
  36711                 BCM_IF_ERROR_RETURN
  36712                     (WRITE_PORT_BRIDGE_BMAP_64r(unit, buf64));
  36713             } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_LO_64r)) {
  36714                 /*
  36715                  * Both PORT_BRIDGE_BMAP_LO_64r and PORT_BRIDGE_BMAP_HI_64r
  36716                  * are expected been valid here.
  36717                  */
  36718 
  36719                 uint64      fval64, rval64;
  36720                 uint32      t_port;
  36721                 soc_reg_t   reg;
  36722                 pbmp_t      curr_pbmp;
  36723 
  36724                 BCM_PBMP_CLEAR(curr_pbmp);
  36725                 COMPILER_64_ZERO(fval64);
  36726                 COMPILER_64_ZERO(rval64);
  36727 
  36728 
  36729                 if (port < 64) {
  36730                     reg = PORT_BRIDGE_BMAP_LO_64r;
  36731                     t_port = port;
  36732                 } else {
  36733                     reg = PORT_BRIDGE_BMAP_HI_64r;
  36734                     t_port = port - 64;
  36735                 }
  36736                 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  36737                 if (BCM_SUCCESS(rv)) {
  36738                     fval64 = soc_reg64_field_get(unit, reg,
  36739                                                     rval64, BITMAPf);
  36740                     SOC_PBMP_WORD_SET(curr_pbmp, 0,
  36741                                         COMPILER_64_LO(fval64));
  36742                     SOC_PBMP_WORD_SET(curr_pbmp, 1,
  36743                                         COMPILER_64_HI(fval64));
  36744 
  36745                     if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  36746                         SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  36747                     } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  36748                         SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  36749                     } else {
  36750                         return BCM_E_NONE;
  36751                     }
  36752 
  36753                     COMPILER_64_SET(fval64,
  36754                                     SOC_PBMP_WORD_GET(curr_pbmp, 1),
  36755                                     SOC_PBMP_WORD_GET(curr_pbmp, 0));
  36756                     soc_reg64_field_set(unit, reg, &rval64,
  36757                                         BITMAPf, fval64);
  36758                     rv = soc_reg_set(unit, reg,
  36759                                         REG_PORT_ANY, 0, rval64);
  36760                 }
  36761             }
  36762 
  36763         }
  36764         if (IS_HG_PORT(unit, port)) {
  36765 
  36766             if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) {
  36767                 port_bridge_mirror_bmap_entry_t entry;
  36768 
  36769                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm,
  36770                             MEM_BLOCK_ANY, 0, &entry));
  36771                 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
  36772                         BITMAPf, &pbmp);
  36773                 /* it might be different to port_tab, so don't return */
  36774                 if (value && !SOC_PBMP_MEMBER(pbmp, port)) {
  36775                     SOC_PBMP_PORT_ADD(pbmp, port);
  36776                 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) {
  36777                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36778                 }
  36779                 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
  36780                         BITMAPf, &pbmp);
  36781                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm,
  36782                             MEM_BLOCK_ANY, 0, &entry));
  36783             }
  36784 
  36785             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_64r)) {
  36786                 uint64      buf64;           /* Buffer for reg64 value. */
  36787                 SOC_PBMP_CLEAR(pbmp);
  36788 
  36789                 BCM_IF_ERROR_RETURN
  36790                     (READ_PORT_BRIDGE_MIRROR_BMAP_64r(unit, &buf64));
  36791 
  36792                 /* Set port bitmap. */
  36793                 SOC_PBMP_WORD_SET(pbmp, 0,
  36794                         soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  36795                             buf64, BITMAP_LOf));
  36796                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  36797                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  36798                     SOC_PBMP_WORD_SET(pbmp, 1,
  36799                             soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  36800                                     buf64, BITMAP_HIf));
  36801                 }
  36802 
  36803                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  36804                     SOC_PBMP_PORT_ADD(pbmp, port);
  36805                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  36806                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36807                 } else {
  36808                     return BCM_E_NONE;
  36809                 }
  36810 
  36811                 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  36812                         &buf64, BITMAP_LOf, SOC_PBMP_WORD_GET(pbmp, 0));
  36813                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  36814                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  36815                     soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  36816                             &buf64, BITMAP_HIf, SOC_PBMP_WORD_GET(pbmp, 1));
  36817                 }
  36818 
  36819                 BCM_IF_ERROR_RETURN
  36820                     (WRITE_PORT_BRIDGE_MIRROR_BMAP_64r(unit, buf64));
  36821             } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_LOr)) {
  36822                 /*
  36823                  * Both PORT_BRIDGE_MIRROR_BMAP_LOr and PORT_BRIDGE_MIRROR_BMAP_HIr
  36824                  * are expected been valid here.
  36825                  */
  36826 
  36827                 uint64      fval64, rval64;
  36828                 uint32      t_port;
  36829                 soc_reg_t   reg;
  36830                 pbmp_t      curr_pbmp;
  36831 
  36832                 BCM_PBMP_CLEAR(curr_pbmp);
  36833                 COMPILER_64_ZERO(fval64);
  36834                 COMPILER_64_ZERO(rval64);
  36835 
  36836 
  36837                 if (port < 64) {
  36838                     reg = PORT_BRIDGE_MIRROR_BMAP_LOr;
  36839                     t_port = port;
  36840                 } else {
  36841                     reg = PORT_BRIDGE_MIRROR_BMAP_HIr;
  36842                     t_port = port - 64;
  36843                 }
  36844                 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  36845                 if (BCM_SUCCESS(rv)) {
  36846                     fval64 = soc_reg64_field_get(unit, reg,
  36847                                                     rval64, BITMAPf);
  36848                     SOC_PBMP_WORD_SET(curr_pbmp, 0,
  36849                                         COMPILER_64_LO(fval64));
  36850                     SOC_PBMP_WORD_SET(curr_pbmp, 1,
  36851                                         COMPILER_64_HI(fval64));
  36852 
  36853                     if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  36854                         SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  36855                     } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  36856                         SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  36857                     } else {
  36858                         return BCM_E_NONE;
  36859                     }
  36860 
  36861                     COMPILER_64_SET(fval64,
  36862                                     SOC_PBMP_WORD_GET(curr_pbmp, 1),
  36863                                     SOC_PBMP_WORD_GET(curr_pbmp, 0));
  36864                     soc_reg64_field_set(unit, reg, &rval64,
  36865                                         BITMAPf, fval64);
  36866                     rv = soc_reg_set(unit, reg,
  36867                                         REG_PORT_ANY, 0, rval64);
  36868                 }
  36869             }
  36870         }
  36871 
  36872         /* Allow to set bridging on higig ports as well */
  36873         return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  36874                 PORT_BRIDGEf, (value) ? 1 : 0);
  36875     }
  36876 #endif /* BCM_TRIUMPH_SUPPORT */
  36877 
  36878     if (SOC_IS_XGS3_SWITCH(unit)) {
  36879         /* Allow to set bridging on higig ports as well */
  36880         rv =_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  36881                 PORT_BRIDGEf, (value) ? 1 : 0);
  36882         BCM_IF_ERROR_RETURN(rv);
  36883 
  36884         if (IS_E_PORT(unit, port) || IS_CPU_PORT(unit, port)) {
  36885 
  36886 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  36887             defined(BCM_SCORPION_SUPPORT)
  36888             if (soc_feature(unit, soc_feature_src_trunk_port_bridge)) {
  36889                 bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  36890                 uint32      port_bridge_map;
  36891 #if defined (BCM_RAPTOR_SUPPORT)
  36892                 uint32 port_bridge_map_hi;
  36893 #endif
  36894 
  36895                 SOC_PBMP_CLEAR(pbmp);
  36896                 BCM_IF_ERROR_RETURN
  36897                     (READ_PORT_BRIDGE_BMAPr(unit, &port_bridge_map));
  36898 
  36899                 SOC_PBMP_WORD_SET(pbmp, 0,
  36900                         soc_reg_field_get(unit, PORT_BRIDGE_BMAPr,
  36901                             port_bridge_map, BITMAPf));
  36902 #if defined (BCM_RAPTOR_SUPPORT)
  36903                 if (soc_feature(unit, soc_feature_register_hi)) {
  36904                     BCM_IF_ERROR_RETURN
  36905                         (READ_PORT_BRIDGE_BMAP_HIr(unit,
  36906                                                    &port_bridge_map_hi));
  36907                     SOC_PBMP_WORD_SET(pbmp, 1,
  36908                             soc_reg_field_get(unit, PORT_BRIDGE_BMAP_HIr,
  36909                                 port_bridge_map_hi, BITMAPf));
  36910                 }
  36911 #endif
  36912                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  36913                     SOC_PBMP_PORT_ADD(pbmp, port);
  36914                     soc_reg_field_set(unit, PORT_BRIDGE_BMAPr,
  36915                             &port_bridge_map, BITMAPf,
  36916                             SOC_PBMP_WORD_GET(pbmp, 0));
  36917                     BCM_IF_ERROR_RETURN
  36918                         (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map));
  36919 #if defined (BCM_RAPTOR_SUPPORT)
  36920 
  36921                     if (soc_feature(unit, soc_feature_register_hi)) {
  36922                         soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr,
  36923                                 &port_bridge_map_hi, BITMAPf,
  36924                                 SOC_PBMP_WORD_GET(pbmp, 1));
  36925                         BCM_IF_ERROR_RETURN
  36926                             (WRITE_PORT_BRIDGE_BMAP_HIr(unit,
  36927                                                         port_bridge_map_hi));
  36928                     }
  36929 #endif
  36930                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  36931                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36932                     soc_reg_field_set(unit, PORT_BRIDGE_BMAPr,
  36933                             &port_bridge_map, BITMAPf,
  36934                             SOC_PBMP_WORD_GET(pbmp, 0));
  36935                     BCM_IF_ERROR_RETURN
  36936                         (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map));
  36937 #if defined (BCM_RAPTOR_SUPPORT)
  36938                     if (soc_feature(unit, soc_feature_register_hi)) {
  36939                         soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr,
  36940                                 &port_bridge_map_hi, BITMAPf,
  36941                                 SOC_PBMP_WORD_GET(pbmp, 1));
  36942                         BCM_IF_ERROR_RETURN
  36943                             (WRITE_PORT_BRIDGE_BMAP_HIr(unit,
  36944                                                         port_bridge_map_hi));
  36945                     }
  36946 #endif
  36947                 }
  36948             }
  36949 #endif /* BCM_RAPTOR_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  36950 
  36951         } else if (IS_HG_PORT(unit, port)) {
  36952 #ifdef BCM_SCORPION_SUPPORT
  36953             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPr)) {
  36954                 bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  36955                 uint32      port_bridge_mirror_map;
  36956 
  36957                 SOC_PBMP_CLEAR(pbmp);
  36958                 BCM_IF_ERROR_RETURN(READ_PORT_BRIDGE_MIRROR_BMAPr(unit,
  36959                             &port_bridge_mirror_map));
  36960                 SOC_PBMP_WORD_SET(pbmp, 0,
  36961                         soc_reg_field_get(unit, PORT_BRIDGE_MIRROR_BMAPr,
  36962                             port_bridge_mirror_map, BITMAPf));
  36963 
  36964                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  36965                     SOC_PBMP_PORT_ADD(pbmp, port);
  36966                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  36967                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  36968                 } else {
  36969                     return BCM_E_NONE;
  36970                 }
  36971 
  36972                 soc_reg_field_set(unit, PORT_BRIDGE_MIRROR_BMAPr,
  36973                         &port_bridge_mirror_map, BITMAPf,
  36974                         SOC_PBMP_WORD_GET(pbmp, 0));
  36975                 BCM_IF_ERROR_RETURN(WRITE_PORT_BRIDGE_MIRROR_BMAPr(unit,
  36976                             port_bridge_mirror_map));
  36977             }
  36978 #endif /* BCM_SCORPION_SUPPORT */
  36979         }
  36980     }
  36981     return rv;
  36982 }
  36983 
  36984 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  36985 STATIC int
  36986 _bcm_esw_port_regex_control_set(int unit, bcm_gport_t gport,
  36987                                 int udp, int tcp, int enable)
  36988 {
  36989     int vp = -1;
  36990     bcm_port_t local_port;
  36991     source_vp_entry_t svp_entry;
  36992     source_trunk_map_table_entry_t stm_entry;
  36993     ft_dst_port_config_entry_t ftdcfg;
  36994     bcm_module_t my_modid;
  36995     int index;
  36996     int rv;
  36997 
  36998     if (!soc_feature(unit, soc_feature_regex)) {
  36999         return BCM_E_UNAVAIL;
  37000     }
  37001 
  37002     enable = !!enable;
  37003 
  37004     if (BCM_GPORT_IS_MIM_PORT(gport)) {
  37005         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  37006         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  37007             return BCM_E_NOT_FOUND;
  37008         }
  37009     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  37010         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  37011         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  37012             return BCM_E_NOT_FOUND;
  37013         }
  37014     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  37015         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  37016     }
  37017 
  37018     if (vp >= 0) {
  37019         SOC_IF_ERROR_RETURN
  37020             (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
  37021         if (tcp) {
  37022             soc_SOURCE_VPm_field32_set(unit, &svp_entry,
  37023                                        DPI_TCP_CREATE_ENf, enable);
  37024             tcp = enable;
  37025         } else {
  37026             tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  37027                                              DPI_TCP_CREATE_ENf);
  37028         }
  37029         if (udp) {
  37030             soc_SOURCE_VPm_field32_set(unit, &svp_entry,
  37031                                        DPI_UDP_CREATE_ENf, enable);
  37032             udp = enable;
  37033         } else {
  37034             udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  37035                                              DPI_UDP_CREATE_ENf);
  37036         }
  37037         if (tcp + udp) {
  37038             soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 1);
  37039         } else {
  37040             soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 0);
  37041         }
  37042         BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
  37043     } else {
  37044         BCM_IF_ERROR_RETURN(
  37045             _bcm_esw_port_gport_validate(unit, gport, &local_port));
  37046         /* Port sanity check. */
  37047         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  37048             return (BCM_E_PORT);
  37049         }
  37050 
  37051         /* Get local module id. */
  37052         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  37053 
  37054         soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm);
  37055 
  37056         /* Calculate table index. */
  37057         rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  37058                                                    local_port, &index);
  37059 
  37060         if(BCM_FAILURE(rv)) {
  37061             soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  37062             return rv;
  37063         }
  37064 
  37065         rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
  37066                                          index, &stm_entry);
  37067         if(BCM_FAILURE(rv)) {
  37068             soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  37069             return rv;
  37070         }
  37071 
  37072         if (tcp) {
  37073             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
  37074                                                     DPI_TCP_CREATE_ENf, enable);
  37075             tcp = enable;
  37076         } else {
  37077             tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  37078                                                           DPI_TCP_CREATE_ENf);
  37079         }
  37080         if (udp) {
  37081             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
  37082                                                     DPI_UDP_CREATE_ENf, enable);
  37083             udp = enable;
  37084         } else {
  37085             udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  37086                                                           DPI_UDP_CREATE_ENf);
  37087         }
  37088         if (tcp + udp) {
  37089             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 1);
  37090         } else {
  37091             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 0);
  37092         }
  37093 
  37094         rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ALL,
  37095                                           index, &stm_entry);
  37096 
  37097         soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  37098         if(BCM_FAILURE(rv)) {
  37099             return rv;
  37100         }
  37101 
  37102         SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  37103                                                      local_port, &ftdcfg));
  37104         soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg,
  37105                                             DPI_TCP_CREATE_ENf, !!tcp);
  37106         soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg,
  37107                                             DPI_UDP_CREATE_ENf, !!udp);
  37108         if (tcp + udp) {
  37109             soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 1);
  37110         } else {
  37111             soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 0);
  37112         }
  37113         SOC_IF_ERROR_RETURN(WRITE_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  37114                                                       local_port, &ftdcfg));
  37115     }
  37116     return BCM_E_NONE;
  37117 }
  37118 
  37119 STATIC int _bcm_esw_port_regex_control_get(int unit, bcm_gport_t gport,
  37120                                            int *udp, int *tcp, int *enable)
  37121 {
  37122     int vp = -1;
  37123     bcm_port_t local_port;
  37124     source_vp_entry_t svp_entry;
  37125     source_trunk_map_table_entry_t stm_entry;
  37126     ft_dst_port_config_entry_t ftdcfg;
  37127     bcm_module_t my_modid;
  37128     int index;
  37129 
  37130     if (!soc_feature(unit, soc_feature_regex)) {
  37131         return BCM_E_UNAVAIL;
  37132     }
  37133 
  37134     if (BCM_GPORT_IS_MIM_PORT(gport)) {
  37135         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  37136         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  37137             return BCM_E_NOT_FOUND;
  37138         }
  37139     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  37140         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  37141         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  37142             return BCM_E_NOT_FOUND;
  37143         }
  37144     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  37145         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  37146     }
  37147 
  37148     if (vp >= 0) {
  37149         SOC_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
  37150         *tcp    = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_TCP_CREATE_ENf);
  37151         *udp    = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_UDP_CREATE_ENf);
  37152         *enable = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_ENABLEf);
  37153     } else {
  37154         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &local_port));
  37155         /* Port sanity check. */
  37156         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  37157             return (BCM_E_PORT);
  37158         }
  37159 
  37160         /* Get local module id. */
  37161         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  37162 
  37163         /* Calculate table index. */
  37164         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  37165                                                                   local_port, &index));
  37166 
  37167         BCM_IF_ERROR_RETURN(READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
  37168                                                          index, &stm_entry));
  37169         *tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  37170                                                        DPI_TCP_CREATE_ENf);
  37171         *udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  37172                                                        DPI_UDP_CREATE_ENf);
  37173         SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  37174                                                      local_port, &ftdcfg));
  37175         *enable = soc_FT_DST_PORT_CONFIGm_field32_get(unit, &ftdcfg, DPI_ENABLEf);
  37176     }
  37177     return BCM_E_NONE;
  37178 }
  37179 #endif
  37180 
  37181 #if defined(BCM_SHADOW_SUPPORT)
  37182 STATIC int
  37183 _bcm_port_type_shadow_support (int unit, bcm_port_t port,
  37184                                     bcm_port_control_t type)
  37185 {
  37186     LOG_INFO(BSL_LS_BCM_PORT,
  37187              (BSL_META_U(unit,
  37188                          "_bcm_port_type_shadow_support : u=%d p=%d type=%d\n"),
  37189               unit, port, (int)type));
  37190 
  37191     switch (type)
  37192     {
  37193         /* Shadoow supported port control types */
  37194         case bcmPortControlManagementPacketIp6Reserved:
  37195         case bcmPortControlManagementPacketIp4Reserved:
  37196         case bcmPortControlManagementPacketLinkConstrained:
  37197         case bcmPortControlManagementPacketGarp:
  37198         case bcmPortControlManagementPacketCos:
  37199         case bcmPortControlManagementPacketColor:
  37200         case bcmPortControlTaggedL3PacketPktPri:
  37201         case bcmPortControlTaggedMPLSPacketPktPri:
  37202         case bcmPortControlTaggedMPLSL3PacketPktPri:
  37203         case bcmPortControlRxEnable:
  37204         case bcmPortControlTxEnable:
  37205         case bcmPortControlPFCEthertype:
  37206         case bcmPortControlPFCOpcode:
  37207         case bcmPortControlPFCReceive:
  37208         case bcmPortControlPFCTransmit:
  37209         case bcmPortControlPFCClasses:
  37210         case bcmPortControlPFCPassFrames:
  37211         case bcmPortControlPFCDestMacOui:
  37212         case bcmPortControlPFCDestMacNonOui:
  37213         case bcmPortControlPFCRefreshTime:
  37214         case bcmPortControlPFCXOffTime:
  37215         case bcmPortControlEEETransmitWakeTime:
  37216         case bcmPortControlEEEReceiveWakeTime:
  37217         case bcmPortControlEEETransmitSleepTime:
  37218         case bcmPortControlEEEReceiveSleepTime:
  37219         case bcmPortControlEEETransmitQuietTime:
  37220         case bcmPortControlEEEReceiveQuietTime:
  37221         case bcmPortControlEEETransmitRefreshTime:
  37222         case bcmPortControlEEEEnable:
  37223         case bcmPortControlEEETransmitIdleTime:
  37224         case bcmPortControlEEETransmitEventCount:
  37225         case bcmPortControlEEETransmitDuration:
  37226         case bcmPortControlEEEReceiveEventCount:
  37227         case bcmPortControlEEEReceiveDuration:
  37228         case bcmPortControlEEETransmitIdleTimeHund:
  37229         case bcmPortControlEEETransmitWakeTimeHund:
  37230         case bcmPortControlEEETransmitMinLPITime:
  37231         case bcmPortControlEEETransmitMinLPITimeHund:
  37232             if (IS_IL_PORT(unit, port)) { /* No support for IL port type */
  37233                 return FALSE;
  37234             }
  37235             /* Fall through */
  37236         case bcmPortControlPrbsMode:
  37237         case bcmPortControlPrbsPolynomial:
  37238         case bcmPortControlPrbsTxEnable:
  37239         case bcmPortControlPrbsRxEnable:
  37240         case bcmPortControlPrbsTxInvertData:
  37241         case bcmPortControlPrbsRxStatus:
  37242         case bcmPortControlLanes:
  37243             return TRUE;
  37244 
  37245         default:
  37246             return FALSE;
  37247     }
  37248 }
  37249 #endif /* BCM_SHADOW_SUPPORT */
  37250 
  37251 static int
  37252 _bcm_esw_mac_rx_control(int unit, bcm_port_t port, uint8 optype, int *enable)
  37253 {
  37254     int rv = BCM_E_NONE;
  37255 
  37256     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  37257         return(bcmi_esw_portctrl_mac_rx_control(unit, port, optype, enable));
  37258     } else {
  37259         PORT_LOCK(unit);
  37260         if (optype) { /* get */
  37261             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37262                                  SOC_MAC_CONTROL_RX_SET, enable);
  37263         } else { /* set */
  37264              rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  37265                                   SOC_MAC_CONTROL_RX_SET, *enable);
  37266         }
  37267         PORT_UNLOCK(unit);
  37268     }
  37269     return rv;
  37270 }
  37271 /*
  37272  * Function:
  37273  *     bcm_esw_port_enqueue_set
  37274  * Description:
  37275  *      This function enable and disable the enqueuing
  37276  *      packets on a port
  37277  * Parameters:
  37278  *      unit      - (IN) Device number
  37279  *      port      - (IN) Port to resolve
  37280  *      enable    - (IN) TRUE to enable enqueuing
  37281  *                       FALSE to disable enqueuing
  37282  * Return Value:
  37283  *      BCM_E_XXX
  37284  */
  37285 
  37286 static int
  37287 bcm_esw_port_enqueue_set(int unit, bcm_port_t port,int enable)
  37288 {
  37289     int rv = BCM_E_NONE;
  37290 
  37291     /* Make sure port module is initialized. */
  37292     PORT_INIT(unit);
  37293 
  37294 #ifdef BCM_TRIDENT3_SUPPORT
  37295     if (SOC_IS_TRIDENT3X(unit)) {
  37296         int link;
  37297         rv = bcm_esw_port_link_status_get(unit, port, &link);
  37298         if (BCM_FAILURE(rv)) {
  37299             return rv;
  37300         }
  37301         if (link == BCM_PORT_LINK_STATUS_UP) {
  37302             /* FALSE to disable enqueuing and MMU cells drain */
  37303             PORT_LOCK(unit);
  37304             if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  37305                 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable);
  37306             } else {
  37307                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable);
  37308             }
  37309             if (BCM_FAILURE(rv)) {
  37310                 PORT_UNLOCK(unit);
  37311                 return rv;
  37312             }
  37313             PORT_UNLOCK(unit);
  37314         }
  37315     } else
  37316 #endif
  37317 #ifdef BCM_TOMAHAWK_SUPPORT
  37318     if (SOC_IS_TOMAHAWKX(unit)) {
  37319         int link;
  37320         rv = bcm_esw_port_link_status_get(unit, port, &link);
  37321         if (BCM_FAILURE(rv)) {
  37322             return rv;
  37323         }
  37324         if (link == BCM_PORT_LINK_STATUS_UP || SOC_FAST_REBOOT(unit)) {
  37325             /* FALSE to disable enqueuing and MMU cells drain */
  37326             PORT_LOCK(unit);
  37327             if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  37328                 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable);
  37329             } else {
  37330                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable);
  37331             }
  37332             if (BCM_FAILURE(rv)) {
  37333                 PORT_UNLOCK(unit);
  37334                 return rv;
  37335             }
  37336             PORT_UNLOCK(unit);
  37337         }
  37338     } else
  37339 #endif
  37340 #ifdef BCM_MONTEREY_SUPPORT
  37341     if (SOC_IS_MONTEREY(unit)) {
  37342         BCM_IF_ERROR_RETURN
  37343             (_bcm_mn_port_enqueue_set(unit,port,enable));
  37344     } else
  37345 #endif
  37346 #ifdef BCM_APACHE_SUPPORT
  37347     if (SOC_IS_APACHE(unit)) {
  37348         BCM_IF_ERROR_RETURN
  37349             (_bcm_ap_port_enqueue_set(unit,port,enable));
  37350     } else
  37351 #endif
  37352 #ifdef BCM_TRIDENT2_SUPPORT
  37353     if (SOC_IS_TD2_TT2(unit)) {
  37354         BCM_IF_ERROR_RETURN
  37355             (_bcm_td2_port_enqueue_set(unit,port,enable));
  37356     } else
  37357 #endif
  37358 #ifdef BCM_TRIDENT_SUPPORT
  37359     if (SOC_IS_TD_TT(unit)) {
  37360         BCM_IF_ERROR_RETURN
  37361             (_bcm_td_port_enqueue_set(unit,port,enable));
  37362     } else
  37363 #endif
  37364 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  37365     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) {
  37366          BCM_IF_ERROR_RETURN
  37367             (_bcm_tr3_port_enqueue_set(unit,port,enable));
  37368     } else
  37369 #endif /* BCM_TRIUMPH3_SUPPORT */
  37370 #ifdef BCM_KATANA2_SUPPORT
  37371     if (SOC_IS_KATANA2(unit)) {
  37372         BCM_IF_ERROR_RETURN
  37373             (_bcm_kt2_port_enqueue_set(unit,port,enable));
  37374     } else
  37375 #endif
  37376     {
  37377         return BCM_E_UNAVAIL;
  37378     }
  37379     return rv;
  37380 }
  37381 
  37382 /*
  37383  * Function:
  37384  *     bcm_esw_port_enqueue_get
  37385  * Description:
  37386  *      This function get enqueuing state
  37387  *      packets on a port
  37388  * Parameters:
  37389  *      unit      - (IN) Device number
  37390  *      port      - (IN) Port to resolve
  37391  *      enable    - (OUT) TRUE to when enqueuing is enabled
  37392  *                       FALSE to when enqueuing is disabled
  37393  * Return Value:
  37394  *      BCM_E_XXX
  37395  */
  37396 static int
  37397 bcm_esw_port_enqueue_get(int unit, bcm_port_t port, int *enable)
  37398 {
  37399     int rv = BCM_E_NONE;
  37400 
  37401     /* Make sure port module is initialized. */
  37402     PORT_INIT(unit);
  37403 
  37404 #ifdef BCM_TRIDENT3_SUPPORT
  37405     if (SOC_IS_TRIDENT3X(unit)) {
  37406         BCM_IF_ERROR_RETURN
  37407             (_bcm_td3_port_enable_get(unit, port, enable));
  37408     } else
  37409 #endif
  37410 #ifdef BCM_TOMAHAWK_SUPPORT
  37411     if (SOC_IS_TOMAHAWKX(unit)) {
  37412         BCM_IF_ERROR_RETURN
  37413             (_bcm_th_port_enqueue_get(unit, port, enable));
  37414     } else
  37415 #endif
  37416 #ifdef BCM_APACHE_SUPPORT
  37417     if (SOC_IS_APACHE(unit)) {
  37418         BCM_IF_ERROR_RETURN
  37419             (_bcm_ap_port_enqueue_get(unit,port,enable));
  37420     } else
  37421 #endif
  37422 #ifdef BCM_TRIDENT2_SUPPORT
  37423     if (SOC_IS_TD2_TT2(unit)) {
  37424         BCM_IF_ERROR_RETURN
  37425             (_bcm_td2_port_enqueue_get(unit,port,enable));
  37426     } else
  37427 #endif
  37428 #ifdef BCM_TRIDENT_SUPPORT
  37429     if (SOC_IS_TD_TT(unit)) {
  37430         BCM_IF_ERROR_RETURN
  37431             (_bcm_td_port_enqueue_get(unit,port,enable));
  37432     }  else
  37433 #endif
  37434     {
  37435         return BCM_E_UNAVAIL;
  37436     }
  37437     return rv;
  37438 }
  37439 
  37440 /*
  37441  * Function:
  37442  *     bcm_esw_port_drain_cells
  37443  * Description:i
  37444  *      This function will drains the MMU cells which the port
  37445  *      is holding
  37446  * Parameters:
  37447  *      unit      - (IN) Device number
  37448  *      port      - (IN) Port to resolve
  37449  *      value     - (IN) TRUE to drain the cells
  37450  *                       FALSE to just ignore
  37451  * Return Value:
  37452  *      BCM_E_XXX
  37453  */
  37454 static int
  37455 bcm_esw_port_drain_cells(int unit, bcm_port_t port, int value)
  37456 {
  37457     int rv = BCM_E_NONE;
  37458 
  37459     /* Make sure port module is initialized. */
  37460     PORT_INIT(unit);
  37461     if (value == FALSE ) {
  37462         return rv;
  37463     }
  37464 #ifdef BCM_TRIDENT3_SUPPORT
  37465     if (SOC_IS_TRIDENT3X(unit)) {
  37466         if (IS_CPU_PORT(unit, port)) {
  37467             return BCM_E_PORT;
  37468         }
  37469         /* MMU cells were drained when enqueuing is disabled */
  37470         return rv;
  37471     } else
  37472 #endif
  37473 #ifdef BCM_TOMAHAWK_SUPPORT
  37474     if (SOC_IS_TOMAHAWKX(unit)) {
  37475         if (IS_CPU_PORT(unit, port)) {
  37476             return BCM_E_PORT;
  37477         }
  37478         /* MMU cells were drained when enqueuing is disabled */
  37479         return rv;
  37480 
  37481     } else
  37482 #endif
  37483 #ifdef BCM_MONTEREY_SUPPORT
  37484     if (SOC_IS_MONTEREY(unit)) {
  37485         BCM_IF_ERROR_RETURN
  37486             (bcm_monterey_port_drain_cells(unit, port));
  37487     } else
  37488 #endif
  37489 #ifdef BCM_APACHE_SUPPORT
  37490     if (SOC_IS_APACHE(unit)) {
  37491         BCM_IF_ERROR_RETURN
  37492             (bcm_apache_port_drain_cells(unit, port));
  37493     } else
  37494 #endif
  37495 #ifdef BCM_TRIDENT2_SUPPORT
  37496     if (SOC_IS_TD2_TT2(unit)) {
  37497         BCM_IF_ERROR_RETURN
  37498             (bcm_td2_port_drain_cells(unit, port));
  37499     } else
  37500 #endif
  37501 #ifdef BCM_TRIDENT_SUPPORT
  37502     if (SOC_IS_TD_TT(unit)) {
  37503         BCM_IF_ERROR_RETURN
  37504             (bcm_td_port_drain_cells(unit, port));
  37505     } else
  37506 #endif
  37507 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  37508         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) {
  37509         BCM_IF_ERROR_RETURN
  37510             (bcm_tr3_port_drain_cells(unit, port));
  37511         } else
  37512 #endif /* BCM_TRIUMPH3_SUPPORT */
  37513 #ifdef BCM_KATANA2_SUPPORT
  37514     if (SOC_IS_KATANA2(unit)) {
  37515         BCM_IF_ERROR_RETURN
  37516             (bcm_kt2_port_drain_cells(unit, port));
  37517     } else
  37518 #endif
  37519 
  37520     {
  37521         return BCM_E_UNAVAIL;
  37522     }
  37523     return rv;
  37524 }
  37525 
  37526 /*
  37527  * Function:
  37528  *     _bcm_esw_port_llfc_set
  37529  * Description:
  37530  *      This function will set the LLFC_RX/TX_ENABLE field,
  37531  *       and LLFC_EN field can possibly be set accordingly.
  37532  * Parameters:
  37533  *      unit - (IN) Device number
  37534  *      port - (IN) Port to resolve
  37535  *      type - (IN) Enum value of the feature
  37536  *      value - (IN) Value to be set
  37537  * Return Value:
  37538  *      BCM_E_XXX
  37539  */
  37540 STATIC int
  37541 _bcm_esw_port_llfc_set(int unit, bcm_port_t port, bcm_port_control_t type, int value)
  37542 {
  37543     int rv = BCM_E_UNAVAIL;
  37544     soc_reg_t port_config;
  37545     int llfc_enable;
  37546 #ifdef BCM_TRIDENT2_SUPPORT
  37547     uint32 rval;
  37548 #endif
  37549 
  37550     if(SOC_PORT_USE_PORTCTRL(unit, port)) {
  37551         return(bcmi_esw_portctrl_llfc_set(unit,port, type, value));
  37552     }
  37553 
  37554     switch(type) {
  37555     case bcmPortControlLLFCReceive:
  37556 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  37557     case bcmPortControlSAFCReceive:
  37558 #endif
  37559 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  37560         if (SOC_IS_XGS3_SWITCH(unit)) {
  37561 
  37562             if (!SOC_PORT_VALID(unit, port)) {
  37563                 return BCM_E_PORT;
  37564             }
  37565 
  37566             BCM_IF_ERROR_RETURN
  37567                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  37568                                  SOC_MAC_CONTROL_LLFC_RX_ENABLE, value));
  37569             if (value == 0) {
  37570                 BCM_IF_ERROR_RETURN
  37571                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37572                                      SOC_MAC_CONTROL_LLFC_TX_ENABLE,
  37573                                      &llfc_enable));
  37574             } else {
  37575                 llfc_enable = TRUE;
  37576             }
  37577 
  37578             if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) {
  37579                 port_config = XLPORT_CONFIGr;
  37580             } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) {
  37581                 port_config = XPORT_CONFIGr;
  37582             } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) {
  37583                 port_config = PORT_CONFIGr;
  37584             } else {
  37585                 port_config = INVALIDr;
  37586             }
  37587 
  37588             if (port_config != INVALIDr){
  37589                 BCM_IF_ERROR_RETURN
  37590                     (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf,
  37591                                             llfc_enable ? 1 : 0));
  37592             }
  37593 
  37594             rv = BCM_E_NONE;
  37595         }
  37596 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  37597         break;
  37598     case bcmPortControlLLFCTransmit:
  37599 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  37600     case bcmPortControlSAFCTransmit:
  37601 #endif
  37602 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  37603         if (SOC_IS_XGS3_SWITCH(unit)) {
  37604             if (!SOC_PORT_VALID(unit, port)) {
  37605                 return BCM_E_PORT;
  37606             }
  37607 
  37608             BCM_IF_ERROR_RETURN
  37609                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  37610                                  SOC_MAC_CONTROL_LLFC_TX_ENABLE, value));
  37611             if (value == 0) {
  37612                 BCM_IF_ERROR_RETURN
  37613                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37614                                      SOC_MAC_CONTROL_LLFC_RX_ENABLE,
  37615                                      &llfc_enable));
  37616             } else {
  37617                 llfc_enable = TRUE;
  37618             }
  37619 
  37620             if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) {
  37621                 port_config = XLPORT_CONFIGr;
  37622             } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) {
  37623                 port_config = XPORT_CONFIGr;
  37624             } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) {
  37625                 port_config = PORT_CONFIGr;
  37626             } else {
  37627                 port_config = INVALIDr;
  37628             }
  37629 
  37630             if (port_config != INVALIDr){
  37631                 BCM_IF_ERROR_RETURN
  37632                     (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf,
  37633                                             llfc_enable ? 1 : 0));
  37634             }
  37635 
  37636 #ifdef BCM_TRIDENT2_SUPPORT
  37637             if (SOC_IS_TD2_TT2(unit)) {
  37638                 SOC_IF_ERROR_RETURN
  37639                     (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr,
  37640                                    port, 0, &rval));
  37641 
  37642                 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  37643                                   PORT_PRI_XON_ENABLEf,
  37644                                   value ? 0xffff : 0);
  37645                 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  37646                                   PORT_PAUSE_ENABLEf, value ? 0 : 1);
  37647 
  37648                 SOC_IF_ERROR_RETURN
  37649                     (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr,
  37650                                    port, 0, rval));
  37651             }
  37652 #endif
  37653 
  37654             rv = BCM_E_NONE;
  37655         }
  37656 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  37657         break;
  37658     default:
  37659         break;
  37660     }
  37661 
  37662     return rv;
  37663 }
  37664 
  37665 /*
  37666  * Function:
  37667  *     _bcm_esw_port_llfc_get
  37668  * Description:
  37669  *      This function will get the LLFC_TX/RX_ENABLE field.
  37670  * Parameters:
  37671  *      unit - (IN) Device number
  37672  *      port - (IN) Port to resolve
  37673  *      type - (IN) Enum value of the feature
  37674  *      value - (OUT) Current value of the port feature
  37675  * Return Value:
  37676  *      BCM_E_XXX
  37677  */
  37678 STATIC int
  37679 _bcm_esw_port_llfc_get(int unit, bcm_port_t port, bcm_port_control_t type, int *value)
  37680 {
  37681     int rv = BCM_E_UNAVAIL;
  37682 
  37683     if(SOC_PORT_USE_PORTCTRL(unit, port)) {
  37684         return(bcmi_esw_portctrl_llfc_get(unit,port, type, value));
  37685     }
  37686 
  37687     switch(type) {
  37688     case bcmPortControlLLFCReceive:
  37689 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  37690     case bcmPortControlSAFCReceive:
  37691 #endif
  37692 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  37693         if (SOC_IS_XGS3_SWITCH(unit)) {
  37694             if (!SOC_PORT_VALID(unit, port)) {
  37695                 return BCM_E_PORT;
  37696             }
  37697             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37698                                  SOC_MAC_CONTROL_LLFC_RX_ENABLE, value);
  37699         }
  37700 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  37701         break;
  37702     case bcmPortControlLLFCTransmit:
  37703 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  37704     case bcmPortControlSAFCTransmit:
  37705 #endif
  37706 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  37707         if (SOC_IS_XGS3_SWITCH(unit)) {
  37708             if (!SOC_PORT_VALID(unit, port)) {
  37709                 return BCM_E_PORT;
  37710             }
  37711             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37712                                  SOC_MAC_CONTROL_LLFC_TX_ENABLE, value);
  37713         }
  37714 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  37715         break;
  37716     default:
  37717         break;
  37718     }
  37719 
  37720     return rv;
  37721 }
  37722 
  37723 #ifdef BCM_TRIUMPH3_SUPPORT
  37724 STATIC int
  37725 _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value)
  37726 {
  37727     int i, incr = 1, ports = 3, okay;
  37728     int rv = BCM_E_NONE, rv1, old_value;
  37729     int retry_count = 0, mode_change = -1;
  37730     uint16 phy;
  37731     uint32 flags;
  37732     soc_info_t *si = &SOC_INFO(unit);
  37733     int phy_port = -1;
  37734     int old_port[4];
  37735     if (!SOC_PORT_VALID(unit, port)) {
  37736         return BCM_E_PORT;
  37737     }
  37738 
  37739     /* coverity[overrun-local : FALSE] */
  37740     phy_port = si->port_l2p_mapping[port];
  37741     for (i = 0; i < 4; i++) {
  37742         old_port[i] = si->flex_port_p2l_mapping[phy_port+i];
  37743     }
  37744 
  37745 _reconfig:
  37746     rv = soc_tr3_port_lanes_set(unit, port, value, &old_value, &mode_change);
  37747     if (rv != SOC_E_NONE) {
  37748         return rv;
  37749     }
  37750     if (value == 1) {
  37751 #ifdef BCM_HELIX4_SUPPORT
  37752         /* coverity[overrun-local : FALSE] */
  37753         if (SOC_IS_HELIX4(unit) && ((_tr3_port_config_id[unit] == 410) &&
  37754                 (si->port_l2p_mapping[port] == 57 || si->port_l2p_mapping[port] == 61))){
  37755             ports = 1;
  37756         }else if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) ||
  37757                (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 ||
  37758                si->port_l2p_mapping[port] == 61))){
  37759            ports = 2;
  37760         }
  37761         else
  37762 #endif
  37763         /* coverity[overrun-local : FALSE] */
  37764         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
  37765             ((_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) &&
  37766             (si->port_l2p_mapping[port] == 73 || si->port_l2p_mapping[port] == 77))) {
  37767             ports = 1;
  37768         } else {
  37769             ports = 4;
  37770         }
  37771     } else if (value == 2) {
  37772 #ifdef BCM_HELIX4_SUPPORT
  37773     if(SOC_IS_HELIX4(unit) &&((_tr3_port_config_id[unit] == 463) ||
  37774            _tr3_port_config_id[unit] == 413) && (si->port_l2p_mapping[port] == 57 ||
  37775            si->port_l2p_mapping[port] == 61)){
  37776            ports = 1;
  37777            incr = 2;
  37778        }
  37779        else
  37780 #endif
  37781        {
  37782            incr = 2;
  37783        }
  37784     } else if (value == 4) {
  37785         ports = 1;
  37786     }
  37787     if (value == 2 && old_value == 1) {
  37788 #ifdef BCM_HELIX4_SUPPORT
  37789     if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) ||
  37790         (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 ||
  37791          si->port_l2p_mapping[port] == 61))){
  37792         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, si->port_p2l_mapping[si->port_l2p_mapping[port] + 1]));
  37793       }else
  37794 #endif
  37795       {
  37796         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
  37797         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
  37798       }
  37799     } else if (value == 4 && old_value == 1) {
  37800         if ((SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 410)) ||
  37801             (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
  37802             (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12))){
  37803             if (old_port[1] > 0) {
  37804                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[1]));
  37805             }
  37806             if (old_port[2] > 0) {
  37807                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[2]));
  37808             }
  37809             if (old_port[3] > 0) {
  37810                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[3]));
  37811             }
  37812         } else {
  37813             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
  37814             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
  37815             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
  37816         }
  37817     } else if (value == 4 && old_value == 2) {
  37818         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
  37819     }
  37820     for (i = 0; i < ports; i+=incr) {
  37821         flags = 0;
  37822         phy = soc_property_port_get(unit, port + i, spn_FLEX_PORT_PHY_ADDR, 0);
  37823         if (!phy) {
  37824             SOC_IF_ERROR_RETURN(soc_tr3_phy_addr_get(unit, port + i, &phy));
  37825             flags = _SHR_PORT_PHY_INTERNAL;
  37826         }
  37827         SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + i, flags, phy));
  37828         BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + i, &okay));
  37829         LOG_VERBOSE(BSL_LS_BCM_PORT,
  37830                     (BSL_META_U(unit,
  37831                                 "Port %d probe: %d\n"), port + i, okay));
  37832         if (!okay) {
  37833             return BCM_E_INTERNAL;
  37834         }
  37835         BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + i, TRUE));
  37836     }
  37837 #ifdef BCM_WARM_BOOT_SUPPORT
  37838     if (SOC_WARM_BOOT(unit)) {
  37839         return rv;
  37840     }
  37841 #endif /* BCM_WARM_BOOT_SUPPORT */
  37842 
  37843     for (i = 0; i < ports; i+=incr) {
  37844         if (SOC_PBMP_MEMBER(si->port.disabled_bitmap, port+i)) {
  37845             continue;
  37846         }
  37847         rv1 = _bcm_tr3_port_ur_chk(unit, ports, port + i);
  37848         if (rv1 == BCM_E_PORT) {
  37849             /* Error encountered in the newly created flex ports.
  37850                Lets revert back to old mode and retry if retry count not exceeded */
  37851             if (++retry_count > _BCM_TR3_PORT_UR_RETRY_MAX) {
  37852                 return BCM_E_INTERNAL;
  37853             }
  37854             rv = soc_tr3_port_lanes_set(unit, port, old_value, &old_value, &mode_change);
  37855             if (rv != SOC_E_NONE) {
  37856                 return rv;
  37857             }
  37858             goto _reconfig;
  37859         }
  37860         if (rv1 != BCM_E_NONE) {
  37861             return rv1;
  37862         }
  37863     }
  37864 
  37865     /* Note: Following is currently a brute force solution */
  37866     for (i = 0; i < ports; i+=incr) {
  37867         if (mode_change == BCM_PORT_ENCAP_HIGIG) {
  37868             /* coverity[overrun-call : FALSE] */
  37869             BCM_IF_ERROR_RETURN
  37870                 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_HIGIG,
  37871                                            TRUE));
  37872         } else if (mode_change == BCM_PORT_ENCAP_IEEE) {
  37873             /* coverity[overrun-call : FALSE] */
  37874             BCM_IF_ERROR_RETURN
  37875                 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_IEEE,
  37876                                            TRUE));
  37877         }
  37878     }
  37879     return rv;
  37880 }
  37881 
  37882 STATIC int
  37883 _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value)
  37884 {
  37885     int rv = BCM_E_NONE;
  37886     if (!SOC_PORT_VALID(unit, port)) {
  37887         return BCM_E_PORT;
  37888     }
  37889     rv = soc_tr3_port_lanes_get(unit, port, value);
  37890     return rv;
  37891 }
  37892 #endif /* BCM_TRIUMPH3_SUPPORT */
  37893 
  37894 #ifdef BCM_TRIDENT_SUPPORT
  37895 STATIC int
  37896 _bcm_td_port_lanes_set(int unit, bcm_port_t port, int value)
  37897 {
  37898     soc_info_t *si;
  37899     int rv, okay, i;
  37900     uint32 rval, phy_mode, core_mode;
  37901     uint32 reset_status;
  37902     bcm_port_t phy_port;
  37903 
  37904     rv = READ_XLPORT_MODE_REGr(unit, port, &rval);
  37905     if (BCM_SUCCESS(rv)) {
  37906         phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  37907                                      PHY_PORT_MODEf);
  37908         core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  37909                                      CORE_PORT_MODEf);
  37910         if (phy_mode == 0) { /* single mode */
  37911             /* Case of 40G port --> 10G XFI */
  37912             if (value == 1) {
  37913                 SOC_INFO(unit).port_speed_max[port]=10000;
  37914             } else if (value == 2) {
  37915                 /* Case of single mode --> dual mode */
  37916                 SOC_INFO(unit).port_speed_max[port]=20000;
  37917                 core_mode = 1;
  37918                 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode);
  37919                 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  37920             }
  37921         } else if (phy_mode == 1) { /* dual mode */
  37922             if (value != 2 && value != 4) {
  37923                 rv = BCM_E_PARAM;
  37924             } else if (value == 4) {
  37925                 /* Case of dual mode --> single mode */
  37926                 core_mode = 0;
  37927                 SOC_INFO(unit).port_speed_max[port]=40000;
  37928             } else {
  37929                 /* case of 20G single mode --> 20G dual mode */
  37930                 core_mode = 1;
  37931             }
  37932             soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode);
  37933             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  37934         } else {  /* phy_mode == 2 */
  37935             if (value == 4) {
  37936                 /* 10G XFI --> 10G XAUI or 10G XFI --> 40G */
  37937                 if (core_mode == 0) {
  37938                     /* 10GXFI --> 40G */
  37939                     SOC_INFO(unit).port_speed_max[port]=40000;
  37940                 }
  37941             }
  37942         }
  37943     }
  37944     if (BCM_SUCCESS(rv)) {
  37945         si = &SOC_INFO(unit);
  37946         phy_port = si->port_l2p_mapping[port];
  37947         for (i = 0; i < value; i++) {
  37948             if ((si->port_p2l_mapping[phy_port + i]) == -1) {
  37949                 continue;
  37950             }
  37951             rv = soc_phyctrl_detach
  37952                 (unit, si->port_p2l_mapping[phy_port + i]);
  37953             if (BCM_FAILURE(rv)) {
  37954                 break;
  37955             }
  37956         }
  37957     }
  37958     if (BCM_SUCCESS(rv)) {
  37959         si = &SOC_INFO(unit);
  37960         si->port_num_lanes[port] = value;
  37961         if (BCM_SUCCESS(rv)) {
  37962             rv = _bcm_port_phy_probe(unit, port, &okay);
  37963         }
  37964     }
  37965 
  37966     /* Do XMAC reset when port mode is changed */
  37967     SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval));
  37968     reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf);
  37969     if (reset_status != 1) {
  37970         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
  37971         SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval));
  37972         sal_udelay(10);
  37973         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
  37974         SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval));
  37975     }
  37976 
  37977     return rv;
  37978 }
  37979 #endif /* BCM_TRIDENT_SUPPORT */
  37980 
  37981 #ifdef BCM_TRIDENT2_SUPPORT
  37982 STATIC int
  37983 _bcm_td2_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  37984 {
  37985     soc_info_t *si = &SOC_INFO(unit);
  37986     soc_td2_port_lanes_t lanes_ctrl;
  37987     int port, i;
  37988     int enable, okay;
  37989     soc_control_t *soc = SOC_CONTROL(unit);
  37990 
  37991     if(SOC_PORT_USE_PORTCTRL(unit, port_base)) {
  37992         return(bcmi_esw_td2_portctrl_lanes_set(unit, port_base, lanes));
  37993     }
  37994 
  37995     sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl));
  37996     lanes_ctrl.port_base = port_base;
  37997     lanes_ctrl.lanes = lanes;
  37998     SOC_IF_ERROR_RETURN
  37999         (soc_trident2_port_lanes_validate(unit, &lanes_ctrl));
  38000 
  38001     if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) {
  38002         return BCM_E_NONE;
  38003     }
  38004 
  38005     /* All existing ports are required to be disasbled */
  38006     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable));
  38007     if (enable) {
  38008         return BCM_E_BUSY;
  38009     }
  38010     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  38011         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38012             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38013             SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  38014             if (enable) {
  38015                 return BCM_E_BUSY;
  38016             }
  38017         }
  38018     }
  38019 
  38020     SOC_IF_ERROR_RETURN
  38021         (soc_trident2_port_lanes_set(unit, &lanes_ctrl));
  38022 
  38023     /* Detach PHY on all existing port(s) */
  38024     SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base));
  38025     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  38026         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38027             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38028             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  38029             COUNTER_LOCK(unit);
  38030             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port);
  38031             COUNTER_UNLOCK(unit);
  38032         }
  38033     }
  38034     /* Probe PHY on all port(s) after conversion */
  38035     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  38036     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE));
  38037     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  38038         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38039             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38040             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  38041             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE));
  38042             COUNTER_LOCK(unit);
  38043             SOC_PBMP_PORT_ADD(soc->counter_pbmp, port);
  38044             COUNTER_UNLOCK(unit);
  38045         }
  38046     }
  38047 
  38048     return BCM_E_NONE;
  38049 }
  38050 #endif /* BCM_TRIDENT2_SUPPORT */
  38051 
  38052 #ifdef BCM_TOMAHAWK_SUPPORT
  38053 STATIC int
  38054 _bcm_th_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  38055 {
  38056     soc_info_t *si = &SOC_INFO(unit);
  38057     soc_control_t *soc = SOC_CONTROL(unit);
  38058     soc_th_port_lanes_t lanes_ctrl;
  38059     int port, i;
  38060     int enable, okay;
  38061     int speed;
  38062 
  38063     sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl));
  38064     lanes_ctrl.port_base = port_base;
  38065     lanes_ctrl.lanes = lanes;
  38066 
  38067     /* All existing ports are required to be disabled */
  38068     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable));
  38069     if (enable) {
  38070         return BCM_E_PORT;
  38071     }
  38072     SOC_IF_ERROR_RETURN
  38073         (soc_tomahawk_port_lanes_validate(unit, &lanes_ctrl));
  38074     if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) {
  38075         return BCM_E_NONE;
  38076     }
  38077 
  38078     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  38079         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38080             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38081             SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  38082             if (enable) {
  38083                 return BCM_E_PORT;
  38084             }
  38085         }
  38086     }
  38087 
  38088     SOC_IF_ERROR_RETURN
  38089         (soc_tomahawk_port_lanes_set(unit, &lanes_ctrl));
  38090     SOC_IF_ERROR_RETURN
  38091         (soc_tomahawk_port_lanes_consolidation(unit, &lanes_ctrl));
  38092 
  38093     /* Detach PHY on all existing port(s) */
  38094     SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base));
  38095     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  38096         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38097             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38098             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  38099             COUNTER_LOCK(unit);
  38100             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port);
  38101             COUNTER_UNLOCK(unit);
  38102         }
  38103     }
  38104 
  38105     /* Probe PHY on all port(s) after conversion */
  38106     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  38107     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE));
  38108     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  38109         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38110             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38111             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  38112             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE));
  38113             COUNTER_LOCK(unit);
  38114             SOC_PBMP_PORT_ADD(soc->counter_pbmp, port);
  38115             COUNTER_UNLOCK(unit);
  38116         }
  38117     }
  38118 
  38119     /* Update port ASF setting to SAF */
  38120     /* Base Port */
  38121     speed = si->port_init_speed[port_base];
  38122     BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set
  38123                             (unit, port_base, speed, _SOC_TH_ASF_MODE_SAF));
  38124     /* Newly added ports */
  38125     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  38126         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  38127             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  38128             speed = si->port_init_speed[port];
  38129             BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set
  38130                                     (unit, port, speed, _SOC_TH_ASF_MODE_SAF));
  38131         }
  38132     }
  38133 
  38134     return BCM_E_NONE;
  38135 }
  38136 #endif /* BCM_TOMAHAWK_SUPPORT */
  38137 
  38138 #ifdef BCM_HURRICANE2_SUPPORT
  38139 STATIC int
  38140 _bcm_hu2_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  38141 {
  38142     soc_info_t *si = &SOC_INFO(unit);
  38143     int cur_lanes;
  38144     int port, phy_ports[3], phy_ports_len, i;
  38145     int okay;
  38146 
  38147     SOC_IF_ERROR_RETURN
  38148         (soc_hurricane2_port_lanes_set(unit, port_base, lanes, &cur_lanes,
  38149                                      phy_ports, &phy_ports_len));
  38150     if (lanes == cur_lanes) {
  38151         return BCM_E_NONE;
  38152     }
  38153 
  38154     if (lanes > cur_lanes) { /* port(s) to be removed */
  38155         for (i = 0; i < phy_ports_len; i++) {
  38156             port = si->port_p2l_mapping[phy_ports[i]];
  38157             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  38158         }
  38159     }
  38160 
  38161     /* The specified port */
  38162     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  38163     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, TRUE));
  38164 
  38165     if (lanes < cur_lanes) { /* port(s) to be added */
  38166         for (i = 0; i < phy_ports_len; i++) {
  38167             port = si->port_p2l_mapping[phy_ports[i]];
  38168             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  38169             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE));
  38170         }
  38171     }
  38172 
  38173     return BCM_E_NONE;
  38174 }
  38175 #endif
  38176 
  38177 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  38178 int
  38179 _bcm_sc_tr_port_pfc_tx_set(int unit, bcm_port_t port, uint32 pri_bmp)
  38180 {
  38181     int pfc_enable;
  38182     uint32 rval;
  38183     int value, val_count = 0;
  38184     soc_reg_t reg;
  38185     uint32 values[2];
  38186     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  38187                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  38188     soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf};
  38189 
  38190     if (!soc_feature(unit, soc_feature_priority_flow_control)) {
  38191         return BCM_E_UNAVAIL;
  38192     }
  38193     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38194     if (chk_gx_port && !IS_GX_PORT(unit, port)) { /* IS_GX_PORT == IS_XL_PORT */
  38195         return BCM_E_PORT;
  38196     }
  38197     if (pri_bmp >= (1U << 16)) {
  38198         return  BCM_E_PARAM;
  38199     }
  38200 
  38201     value = (pri_bmp == 0)? 0 : 1;
  38202     BCM_IF_ERROR_RETURN
  38203         (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  38204                          SOC_MAC_CONTROL_PFC_TX_ENABLE, value));
  38205     if (value == 0) {
  38206         BCM_IF_ERROR_RETURN
  38207             (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  38208                              SOC_MAC_CONTROL_PFC_RX_ENABLE,
  38209                              &pfc_enable));
  38210     } else {
  38211         pfc_enable = TRUE;
  38212     }
  38213 
  38214     if (!soc_feature(unit, soc_feature_mmu_config_property)) {
  38215         rval = 0;
  38216         if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) {
  38217            if (value) {
  38218               soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  38219                                 PORT_PRI_XON_ENABLEf, 0xff);
  38220               if (soc_reg_field_valid(unit, PORT_PRI_XON_ENABLEr,
  38221                                       PORT_PG7PAUSE_DISABLEf)) {
  38222                   soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  38223                                     PORT_PG7PAUSE_DISABLEf, 1);
  38224               }
  38225            }
  38226            BCM_IF_ERROR_RETURN
  38227               (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval));
  38228         }
  38229     } else if (SOC_IS_TRIDENT(unit)) {
  38230        rval = 0;
  38231        if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) {
  38232            if(value) {
  38233                /* Get flow_control_enable info from mmu config
  38234                 * property for each priority group, and enable
  38235                 * generation of XON/XOFF for priority group
  38236                 * accordingly. */
  38237                int idx = 0, prifc_en = 0, fval = 0;
  38238                char suffix;
  38239                for(idx = 0; idx < 8; idx ++) {
  38240                    /* By default, enable generation of XON and XOFF
  38241                     * LLFC messages for priority 7 */
  38242                    prifc_en = (idx == 7) ? 1 : 0;
  38243                    prifc_en = soc_property_port_obj_attr_get(unit,
  38244                                         port, spn_BUF, spn_PRIGROUP,
  38245                                         idx, spn_FLOW_CONTROL_ENABLE,
  38246                                         0, &suffix, prifc_en);
  38247                    if(prifc_en != 0) {
  38248                        fval |= (1 << idx);
  38249                    }
  38250                }
  38251                soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  38252                                    PORT_PRI_XON_ENABLEf, fval);
  38253            }
  38254            /* When disable PFC on port, generation of XON/XOFF
  38255             * for all priority groups must be disabled also. */
  38256            BCM_IF_ERROR_RETURN
  38257                  (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval));
  38258         }
  38259     }
  38260 
  38261     /* Port config settings */
  38262     values[0] = pfc_enable ? 1 : 0;
  38263     values[1] = 0;
  38264 
  38265     if (SOC_IS_TD2_TT2(unit)) {
  38266 #ifdef BCM_TOMAHAWK3_SUPPORT
  38267         if(SOC_IS_TOMAHAWK3(unit)) {
  38268             SOC_IF_ERROR_RETURN
  38269                 (bcm_th3_mmu_pfc_tx_config_set(unit, port,
  38270                                         pfc_enable, pri_bmp));
  38271         } else
  38272 #endif
  38273         {
  38274             SOC_IF_ERROR_RETURN
  38275                 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr,
  38276                                port, 0, &rval));
  38277             soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  38278                               PORT_PRI_XON_ENABLEf,
  38279                               pfc_enable ? pri_bmp : 0);
  38280 
  38281             soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  38282                               PORT_PAUSE_ENABLEf, pfc_enable ? 0 : 1);
  38283             SOC_IF_ERROR_RETURN
  38284                 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr,
  38285                                port, 0, rval));
  38286         }
  38287 #ifdef BCM_TOMAHAWK_SUPPORT
  38288         if (SOC_IS_TOMAHAWKX(unit) && IS_CL_PORT(unit, port)) {
  38289             soc_info_t *si;
  38290             uint64 rval64;
  38291             int phy_port_base, phy_port, lane, block_idx, pipe, clport, obm;
  38292             static const soc_reg_t obm_fc_config_regs[] = {
  38293                 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr,
  38294                 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr,
  38295                 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr,
  38296                 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr,
  38297 #ifdef BCM_TOMAHAWK2_SUPPORT
  38298                 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr,
  38299                 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr,
  38300                 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr,
  38301                 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr
  38302 #endif
  38303             };
  38304 
  38305             COMPILER_64_ZERO(rval64);
  38306             si = &SOC_INFO(unit);
  38307             phy_port = si->port_l2p_mapping[port];
  38308             phy_port_base = PORT_BLOCK_BASE_PORT(port);
  38309             lane = (phy_port - phy_port_base) & 3;
  38310             block_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, 0);
  38311             pipe = si->port_pipe[port];
  38312             clport = SOC_BLOCK_NUMBER(unit, block_idx);
  38313             if (SOC_IS_TOMAHAWK(unit)) {
  38314                 /* obm number is reversed (mirrored) in odd pipe */
  38315                 obm = pipe & 1 ? (7- (clport & 7)) : (clport & 7);
  38316             } else {
  38317                 obm = clport & 15;
  38318             }
  38319             reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe];
  38320             SOC_IF_ERROR_RETURN
  38321                 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64));
  38322             soc_reg64_field32_set(unit, reg, &rval64, FC_TYPEf, pfc_enable);
  38323             SOC_IF_ERROR_RETURN
  38324                 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64));
  38325         }
  38326 #endif /* BCM_TOMAHAWK_SUPPORT */
  38327         reg = INVALIDr;
  38328     } else if (SOC_IS_TD_TT(unit)) {
  38329         int mmu_port;
  38330         uint64 r64val;
  38331         soc_info_t *si;
  38332 
  38333         /* disable pause if pfc is enabled, vice versa */
  38334         si = &SOC_INFO(unit);
  38335         mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]];
  38336         reg = (mmu_port < 33) ? PORT_PAUSE_ENABLE0_64r : PORT_PAUSE_ENABLE1_64r;
  38337         mmu_port = (mmu_port < 33) ? mmu_port : mmu_port - 33;
  38338         SOC_IF_ERROR_RETURN(
  38339             soc_reg_get(unit, reg, REG_PORT_ANY, 0, &r64val));
  38340         if (value) {
  38341             COMPILER_64_BITCLR(r64val, mmu_port);
  38342         } else {
  38343             COMPILER_64_BITSET(r64val, mmu_port);
  38344         }
  38345         SOC_IF_ERROR_RETURN(
  38346             soc_reg_set(unit, reg, REG_PORT_ANY, 0, r64val));
  38347 
  38348         reg = XLPORT_CONFIGr;
  38349         val_count=2;
  38350     } else if (SOC_IS_SHADOW(unit)) {
  38351         reg = XLPORT_CONFIGr;
  38352         val_count=2;
  38353     } else if (SOC_IS_TRIUMPH3(unit)) {
  38354         reg = PORT_CONFIGr;
  38355         val_count=2;
  38356     }  else if (SOC_IS_SABER2(unit)) {
  38357         /* No port level config required */
  38358         reg = INVALIDr;
  38359         val_count = 0;
  38360     } else if (SOC_IS_KATANAX(unit)) {
  38361         reg = XPORT_CONFIGr;
  38362         val_count=2;
  38363     } else {
  38364         reg = INVALIDr;
  38365     }
  38366 
  38367     if (val_count > 0) {
  38368         BCM_IF_ERROR_RETURN
  38369             (soc_reg_fields32_modify(unit, reg, port,
  38370                                      COUNTOF(values), fields, values));
  38371     } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) {
  38372         if (SOC_REG_IS_VALID(unit, PPFC_ENr)) {
  38373             BCM_IF_ERROR_RETURN
  38374               (soc_reg_field32_modify(unit, PPFC_ENr, port,
  38375                                       PPFC_FEATURE_ENf,
  38376                                       pfc_enable ? 1 : 0));
  38377         }
  38378         if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) {
  38379             BCM_IF_ERROR_RETURN
  38380                 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  38381                                         PPP_ENABLEf,
  38382                                         pfc_enable ? 1 : 0));
  38383         }
  38384     }
  38385 
  38386     /* Stats enable */
  38387     BCM_IF_ERROR_RETURN
  38388         (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  38389                          SOC_MAC_CONTROL_PFC_STATS_ENABLE,
  38390                          pfc_enable ? 1 : 0));
  38391 
  38392     return BCM_E_NONE;
  38393 }
  38394 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  38395 
  38396 
  38397 /*
  38398  * Function:
  38399  *      bcm_esw_port_control_wlan_validate
  38400  * Description:
  38401  *      Checks that port control is valid for a WLAN GPORT.
  38402  *      Resolves port to expected port value for the given port control type.
  38403  * Parameters:
  38404  *      port      - (IN) Port to resolve
  38405  *      type      - (IN) Port control type
  38406  *      port_out  - (OUT) Returns port (gport or BCM format) that
  38407  *                  is expected for corresponding port control type.
  38408  * Return Value:
  38409  *      BCM_E_XXX
  38410  */
  38411 STATIC int
  38412 bcm_esw_port_control_wlan_validate(bcm_port_t port,
  38413                                    bcm_port_control_t type,
  38414                                    bcm_port_t *port_out)
  38415 {
  38416     int rv = BCM_E_PORT;
  38417     int support = FALSE;
  38418 
  38419     switch (type) {
  38420     case bcmPortControlBridge:
  38421     case bcmPortControlTrunkHashSet:
  38422     case bcmPortControlFabricTrunkHashSet:
  38423     case bcmPortControlECMPHashSet:
  38424     case bcmPortControlLoadBalanceHashSet:
  38425     case bcmPortControlLoadBalancingNumber:
  38426     case bcmPortControlIP4:
  38427     case bcmPortControlIP6:
  38428     case bcmPortControlIP4Mcast:
  38429     case bcmPortControlIP6Mcast:
  38430     case bcmPortControlMpls:
  38431     case bcmPortControlMacInMac:
  38432     case bcmPortControlSrcBmacMissToCpu:
  38433     case bcmPortControlIP4McastL2:
  38434     case bcmPortControlIP6McastL2:
  38435     case bcmPortControlFilterLookup:
  38436     case bcmPortControlFilterIngress:
  38437     case bcmPortControlPreservePacketPriority:
  38438     case bcmPortControlLearnClassEnable:
  38439     case bcmPortControlTrustIncomingVlan:
  38440     case bcmPortControlDoNotCheckVlan:
  38441     case bcmPortControlIEEE8021ASEnableIngress:
  38442     case bcmPortControlIpfixRate:
  38443     case bcmPortControlForwardStaticL2MovePkt:
  38444     case bcmPortControlTrillHashSelect:
  38445     case bcmPortControlFabricSourceKnockout:
  38446     case bcmPortControlL2GreEnable:
  38447     case bcmPortControlL2GreTunnelbasedVpnId:
  38448     case bcmPortControlL2GreDefaultTunnelEnable:
  38449     case bcmPortControlVxlanEnable:
  38450     case bcmPortControlVxlanTunnelbasedVnId:
  38451     case bcmPortControlVxlanDefaultTunnelEnable:
  38452     case bcmPortControlRegex:
  38453     case bcmPortControlRegexTcp:
  38454     case bcmPortControlRegexUdp:
  38455         support = TRUE;
  38456         break;
  38457     default:
  38458         support = FALSE;
  38459         break;
  38460     }
  38461 
  38462     if (support) {
  38463         *port_out = port;
  38464         rv = BCM_E_NONE;
  38465     }
  38466 
  38467     return rv;
  38468 }
  38469 
  38470 /*
  38471  * Function:
  38472  *      bcm_esw_port_control_proxy_validate
  38473  * Description:
  38474  *      Checks that port control is valid for a PROXY GPORT.
  38475  *      Resolves port to expected port value for the given port control type.
  38476  * Parameters:
  38477  *      unit      - (IN) Device number
  38478  *      port      - (IN) Port to resolve
  38479  *      type      - (IN) Port control type
  38480  *      port_out  - (OUT) Returns port (gport or BCM format) that
  38481  *                  is expected for corresponding port control type.
  38482  * Return Value:
  38483  *      BCM_E_XXX
  38484  */
  38485 STATIC int
  38486 bcm_esw_port_control_proxy_validate(int unit, bcm_port_t port,
  38487                                     bcm_port_control_t type,
  38488                                     bcm_port_t *port_out)
  38489 {
  38490     int rv = BCM_E_PORT;
  38491     int support = FALSE;
  38492 
  38493     /* Make sure port module is initialized. */
  38494     PORT_INIT(unit);
  38495 
  38496     if (!soc_feature(unit, soc_feature_proxy_port_property)) {
  38497         return BCM_E_PORT;
  38498     }
  38499 
  38500     switch(type) {
  38501     case bcmPortControlBridge:
  38502     case bcmPortControlTrunkHashSet:
  38503     case bcmPortControlFabricTrunkHashSet:
  38504     case bcmPortControlECMPHashSet:
  38505     case bcmPortControlLoadBalanceHashSet:
  38506     case bcmPortControlLoadBalancingNumber:
  38507     case bcmPortControlIP4:
  38508     case bcmPortControlIP6:
  38509     case bcmPortControlIP4Mcast:
  38510     case bcmPortControlIP6Mcast:
  38511     case bcmPortControlMpls:
  38512     case bcmPortControlMacInMac:
  38513     case bcmPortControlSrcBmacMissToCpu:
  38514     case bcmPortControlIP4McastL2:
  38515     case bcmPortControlIP6McastL2:
  38516     case bcmPortControlFilterLookup:
  38517     case bcmPortControlFilterIngress:
  38518     case bcmPortControlPreservePacketPriority:
  38519     case bcmPortControlLearnClassEnable:
  38520     case bcmPortControlTrustIncomingVlan:
  38521     case bcmPortControlDoNotCheckVlan:
  38522     case bcmPortControlIEEE8021ASEnableIngress:
  38523     case bcmPortControlIpfixRate:
  38524     case bcmPortControlOAMEnable:
  38525     case bcmPortControlForwardStaticL2MovePkt:
  38526     case bcmPortControlTrill:
  38527     case bcmPortControlTrillAllow:
  38528     case bcmPortControlNonTrillAllow:
  38529     case bcmPortControlTrillCoreISISToCPU:
  38530     case bcmPortControlTrillHashSelect:
  38531     case bcmPortControlNivNonVntagDrop:
  38532     case bcmPortControlNonEtagDrop:
  38533     case bcmPortControlNivVntagDrop:
  38534     case bcmPortControlEtagDrop:
  38535     case bcmPortControlNivNonVntagAdd:
  38536     case bcmPortControlNonEtagAdd:
  38537     case bcmPortControlNivVntagIngressReplace:
  38538     case bcmPortControlEtagIngressReplace:
  38539     case bcmPortControlNivVntagIngressDelete:
  38540     case bcmPortControlEtagIngressDelete:
  38541     case bcmPortControlNivRpfCheck:
  38542     case bcmPortControlExtenderRpfCheck:
  38543     case bcmPortControlNivNameSpace:
  38544     case bcmPortControlExtenderNameSpace:
  38545     case bcmPortControlUseEtagPri:
  38546     case bcmPortControlProhibitedDot1p:
  38547     case bcmPortControlFabricSourceKnockout:
  38548     case bcmPortControlMplsEntropyHashSet:
  38549     case bcmPortControlL2GreEnable:
  38550     case bcmPortControlL2GreTunnelbasedVpnId:
  38551     case bcmPortControlL2GreDefaultTunnelEnable:
  38552     case bcmPortControlVxlanEnable:
  38553     case bcmPortControlVxlanTunnelbasedVnId:
  38554     case bcmPortControlVxlanDefaultTunnelEnable:
  38555         support = TRUE;
  38556         break;
  38557     default:
  38558         support = FALSE;
  38559         break;
  38560     }
  38561 
  38562     if (support) {
  38563         *port_out = port;
  38564         rv = BCM_E_NONE;
  38565     }
  38566 
  38567     return rv;
  38568 }
  38569 
  38570 /*
  38571  * Function:
  38572  *      bcm_esw_port_control_scheduler_validate
  38573  * Description:
  38574  *      Checks that port control is valid for a SCHEDULER GPORT.
  38575  *      Resolves port to expected port value for the given port control type.
  38576  * Parameters:
  38577  *      unit      - (IN) Device number
  38578  *      port      - (IN) Port to resolve
  38579  *      type      - (IN) Port control type
  38580  *      port_out  - (OUT) Returns port (gport or BCM format) that
  38581  *                  is expected for corresponding port control type.
  38582  * Return Value:
  38583  *      BCM_E_XXX
  38584  */
  38585 STATIC int
  38586 bcm_esw_port_control_scheduler_validate(int unit, bcm_port_t port,
  38587                                         bcm_port_control_t type,
  38588                                         bcm_port_t *port_out)
  38589 {
  38590     int rv = BCM_E_PORT;
  38591     int support = FALSE;
  38592 
  38593     switch (type) {
  38594     case bcmPortControlWredDropCountUpdateEnableQueueMask:
  38595     case bcmPortControlWredDropCountUpdateEnableColorMask:
  38596         support = TRUE;
  38597         break;
  38598     default:
  38599         support = FALSE;
  38600         break;
  38601     }
  38602 
  38603     if (support) {
  38604         *port_out = port;
  38605         rv = BCM_E_NONE;
  38606     }
  38607 
  38608     return rv;
  38609 }
  38610 
  38611 /*
  38612  * Function:
  38613  *      bcm_esw_port_control_local_port_validate
  38614  * Description:
  38615  *      Checks that port control is valid for a BCM local physical port.
  38616  *      Resolves port to expected port value for the given port control type.
  38617  * Parameters:
  38618  *      unit      - (IN) Device number
  38619  *      port      - (IN) Port to resolve
  38620  *      type      - (IN) Port control type
  38621  *      port_out  - (OUT) Returns port (gport or BCM format) that
  38622  *                  is expected for corresponding port control type.
  38623  * Return Value:
  38624  *      BCM_E_XXX
  38625  *
  38626  *      Unlike the other similar routines
  38627  *      (i.e. bcm_esw_port_control_wlan_support), note that the default
  38628  *      support is VALID and checks for INVALID types, since most
  38629  *      port controls are valid for this type of port.
  38630  */
  38631 STATIC int
  38632 bcm_esw_port_control_local_port_validate(int unit, bcm_port_t port,
  38633                                          bcm_port_control_t type,
  38634                                          bcm_port_t *port_out)
  38635 {
  38636     int rv = BCM_E_PORT;
  38637     int support = TRUE;
  38638     bcm_port_t local_port;
  38639 
  38640     /* Make sure port module is initialized. */
  38641     PORT_INIT(unit);
  38642 
  38643     /* Check for valid BCM local physical port */
  38644     BCM_IF_ERROR_RETURN
  38645         (_bcm_esw_port_gport_validate(unit, port, &local_port));
  38646 
  38647     if (IS_ST_PORT(unit, local_port)) {
  38648         switch(type) {
  38649         case bcmPortControlIP4:
  38650         case bcmPortControlIP6:
  38651         case bcmPortControlIP4Mcast:
  38652         case bcmPortControlIP6Mcast:
  38653         case bcmPortControlMpls:
  38654         case bcmPortControlMacInMac:
  38655         case bcmPortControlIP4McastL2:
  38656         case bcmPortControlIP6McastL2:
  38657         case bcmPortControlIPMC4Ucast:
  38658         case bcmPortControlIPMC6Ucast:
  38659             support = FALSE;
  38660             break;
  38661         default:
  38662             support = TRUE;
  38663             break;
  38664         }
  38665     }
  38666 
  38667     if (support) {
  38668         if (!IS_E_PORT(unit, local_port)) {
  38669             switch(type) {
  38670             case bcmPortControlEEEEnable:
  38671             case bcmPortControlEEETransmitIdleTime:
  38672             case bcmPortControlEEEStatisticsClear:
  38673             case bcmPortControlEEETransmitRefreshTime:
  38674             case bcmPortControlEEETransmitSleepTime:
  38675             case bcmPortControlEEETransmitQuietTime:
  38676             case bcmPortControlEEETransmitWakeTime:
  38677             case bcmPortControlEEEReceiveSleepTime:
  38678             case bcmPortControlEEEReceiveQuietTime:
  38679             case bcmPortControlEEEReceiveWakeTime:
  38680             case bcmPortControlEEEEventCountSymmetric:
  38681             case bcmPortControlEEELinkActiveDuration:
  38682             case bcmPortControlEEEReceiveDuration:
  38683             case bcmPortControlEEETransmitEventCount:
  38684             case bcmPortControlEEETransmitDuration:
  38685             case bcmPortControlEEEReceiveEventCount:
  38686                 support = FALSE;
  38687                 break;
  38688             default:
  38689                 support = TRUE;
  38690                 break;
  38691             }
  38692         }
  38693     }
  38694 
  38695     if (support) {
  38696         *port_out = local_port;
  38697         rv = BCM_E_NONE;
  38698     }
  38699 
  38700     return rv;
  38701 }
  38702 
  38703 /*
  38704  * Function:
  38705  *      bcm_esw_port_control_validate
  38706  * Description:
  38707  *      Checks that port is valid and that control is supported
  38708  *      for the given port type.  Resolves port to expected
  38709  *      port value for the given port control type.
  38710  *      Current valid port types are:
  38711  *          GPORT WLAN
  38712  *          GPORT PROXY
  38713  *          GPORT (various types) that resolves to local physical port
  38714  *          BCM port (non-gport)
  38715  * Parameters:
  38716  *      unit      - (IN) Device number
  38717  *      port      - (IN) Port to resolve
  38718  *      type      - (IN) Port control type
  38719  *      port_out  - (OUT) Returns port (gport or BCM format) that
  38720  *                  is expected for corresponding port control type.
  38721  * Return Value:
  38722  *      BCM_E_XXX
  38723  */
  38724 STATIC int
  38725 bcm_esw_port_control_validate(int unit, bcm_port_t port,
  38726                               bcm_port_control_t type,
  38727                               bcm_port_t *port_out)
  38728 {
  38729     int rv = BCM_E_PORT;
  38730 
  38731     /* Make sure port module is initialized. */
  38732     PORT_INIT(unit);
  38733 
  38734     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  38735         rv = bcm_esw_port_control_wlan_validate(port, type, port_out);
  38736     } else if (BCM_GPORT_IS_PROXY(port)) {
  38737         rv = bcm_esw_port_control_proxy_validate(unit, port, type, port_out);
  38738     } else if (BCM_GPORT_IS_SCHEDULER(port)) {
  38739         rv = bcm_esw_port_control_scheduler_validate(unit, port,
  38740                                                      type, port_out);
  38741     } else {
  38742         rv = bcm_esw_port_control_local_port_validate(unit, port, type,
  38743                                                       port_out);
  38744     }
  38745 
  38746     return rv;
  38747 }
  38748 
  38749 
  38750 int
  38751 _bcm_esw_port_vrf_set(int unit, bcm_port_t port, int value)
  38752 {
  38753     int rv = BCM_E_UNAVAIL;
  38754 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  38755         if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) ||
  38756             !soc_feature(unit, soc_feature_l3))  {
  38757             return BCM_E_UNAVAIL;
  38758         }
  38759 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */
  38760         if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  38761             if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) {
  38762                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38763                                            VRF_IDf, value);
  38764                 BCM_IF_ERROR_RETURN(rv);
  38765                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  38766                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38767                                                VRF_PORT_ENABLEf, 0x1);
  38768                 }
  38769             } else {
  38770                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  38771                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38772                                                VRF_PORT_ENABLEf, 0x0);
  38773                     BCM_IF_ERROR_RETURN(rv);
  38774                 }
  38775                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  38776                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38777                                                VRF_IDf, 0x0);
  38778                 }
  38779             }
  38780         }
  38781 
  38782 #if defined(BCM_TRIUMPH_SUPPORT)
  38783         else {
  38784             if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, VRF_IDf)) {
  38785                 if  ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) {
  38786 #if defined(BCM_KATANA2_SUPPORT)
  38787                     if (SOC_IS_KATANA2(unit)) {
  38788                         rv = _bcm_kt2_source_trunk_map_set(unit, port,
  38789                                 VRF_IDf, value);
  38790                     } else
  38791 #endif
  38792                     {
  38793                         rv = _bcm_trx_source_trunk_map_set(unit, port,
  38794                                 VRF_IDf, value);
  38795                     }
  38796                     BCM_IF_ERROR_RETURN(rv);
  38797                     if (soc_mem_field_valid(unit, PORT_TABm,
  38798                                             PORT_OPERATIONf) ||
  38799                         SOC_IS_TRIDENT3X(unit)) {
  38800                         rv = _bcm_esw_port_tab_set(unit, port,
  38801                                                    _BCM_CPU_TABS_BOTH,
  38802                                                    PORT_OPERATIONf, 0x3);
  38803                     }
  38804                 } else {
  38805                     if (soc_mem_field_valid(unit, PORT_TABm,
  38806                                             PORT_OPERATIONf) ||
  38807                         SOC_IS_TRIDENT3X(unit)) {
  38808                         rv = _bcm_esw_port_tab_set(unit, port,
  38809                                                    _BCM_CPU_TABS_BOTH,
  38810                                                    PORT_OPERATIONf, 0x0);
  38811                     }
  38812                 }
  38813             }
  38814         }
  38815 #endif  /* BCM_TRIUMPH_SUPPORT */
  38816     return rv;
  38817 }
  38818 
  38819 int
  38820 _bcm_esw_port_vrf_get(int unit, bcm_port_t port, int *value)
  38821 {
  38822     int rv = BCM_E_UNAVAIL;
  38823 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  38824     if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) ||
  38825         !soc_feature(unit, soc_feature_l3)) {
  38826         return BCM_E_UNAVAIL;
  38827     }
  38828 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */
  38829     if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  38830         rv = _bcm_esw_port_tab_get(unit, port, VRF_PORT_ENABLEf, value);
  38831 
  38832         if ((*value == 0x1 ) && (soc_mem_field_valid(unit, PORT_TABm,
  38833                                                      VRF_IDf ))) {
  38834               rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value);
  38835         } else {
  38836               *value = 0;
  38837         }
  38838     } else if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  38839         rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value);
  38840     }
  38841 
  38842 #if defined(BCM_TRIUMPH_SUPPORT)
  38843     else {
  38844         *value = 0;
  38845         if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  38846             SOC_IS_TRIDENT3X(unit)) {
  38847             rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value);
  38848             BCM_IF_ERROR_RETURN(rv);
  38849         }
  38850         if ((*value == 0x3) &&
  38851             (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  38852                                      VRF_IDf))) {
  38853 #if defined(BCM_KATANA2_SUPPORT)
  38854             if (SOC_IS_KATANA2(unit)) {
  38855                 rv = _bcm_kt2_source_trunk_map_get(unit, port, VRF_IDf,
  38856                                            (uint32 *)value);
  38857             } else
  38858 #endif
  38859             {
  38860                 rv = _bcm_trx_source_trunk_map_get(unit, port, VRF_IDf,
  38861                                            (uint32 *)value);
  38862             }
  38863         }
  38864     }
  38865 
  38866 #endif /* BCM_TRIUMPH_SUPPORT */
  38867     return rv;
  38868 }
  38869 
  38870 #ifdef BCM_TRIDENT2_SUPPORT
  38871 STATIC void
  38872 _bcm_flex_port_phy_control_software_rx_los_get(int unit, bcm_port_t control_port) {
  38873     int        rv = BCM_E_NONE;
  38874     bcm_pbmp_t ancillary_pbmp;
  38875     bcm_port_t ancillary_port;
  38876     uint32     rx_los;
  38877 
  38878     rv = bcm_esw_port_subsidiary_ports_get(unit, control_port, &ancillary_pbmp);
  38879     if (BCM_FAILURE(rv)) {
  38880         return;
  38881     }
  38882     PBMP_ITER(ancillary_pbmp, ancillary_port) {
  38883         rv = bcm_esw_port_phy_control_get(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, &rx_los);
  38884         if (BCM_SUCCESS(rv)) {
  38885             PORT_INFO_RX_LOS_SET(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los);
  38886         }
  38887     }
  38888     return;
  38889 }
  38890 #endif
  38891 
  38892 int
  38893 bcm_esw_port_phy_fec_error_inject_set(int unit, bcm_port_t port,
  38894                                       uint16 error_control_map,
  38895                                       bcm_port_phy_fec_error_mask_t bit_error_mask)
  38896 {
  38897     int rv = BCM_E_UNAVAIL;
  38898     soc_phy_control_fec_error_mask_t error_mask;
  38899 
  38900     /* Make sure port module is initialized. */
  38901     PORT_INIT(unit);
  38902 
  38903     /* Call Port Control module */
  38904     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  38905         return bcmi_esw_portctrl_phy_fec_error_inject_set(unit, port, error_control_map, bit_error_mask);
  38906     }
  38907 
  38908     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38909 
  38910     if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  38911         return BCM_E_PORT;
  38912     }
  38913     error_mask.error_mask_bit_31_0 = bit_error_mask.error_mask_bit_31_0;
  38914     error_mask.error_mask_bit_63_32 = bit_error_mask.error_mask_bit_63_32;
  38915     error_mask.error_mask_bit_79_64 = bit_error_mask.error_mask_bit_79_64;
  38916 
  38917     PORT_LOCK(unit);
  38918     rv = soc_phyctrl_fec_error_inject_set(unit, port, error_control_map, error_mask);
  38919     PORT_UNLOCK(unit);
  38920 
  38921     return rv;
  38922 }
  38923 
  38924 int
  38925 bcm_esw_port_phy_fec_error_inject_get(int unit, bcm_port_t port,
  38926                                           uint16 *error_control_map,
  38927                                           bcm_port_phy_fec_error_mask_t *bit_error_mask)
  38928 {
  38929     int rv = BCM_E_UNAVAIL;
  38930     soc_phy_control_fec_error_mask_t error_mask;
  38931 
  38932     /* Make sure port module is initialized. */
  38933     PORT_INIT(unit);
  38934 
  38935     /* Call Port Control module */
  38936     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  38937         return bcmi_esw_portctrl_phy_fec_error_inject_get(unit, port, error_control_map, bit_error_mask);
  38938     }
  38939 
  38940     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38941 
  38942     if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  38943         return BCM_E_PORT;
  38944     }
  38945 
  38946     PORT_LOCK(unit);
  38947     rv = soc_phyctrl_fec_error_inject_get(unit, port, error_control_map, &error_mask);
  38948     PORT_UNLOCK(unit);
  38949 
  38950     bit_error_mask->error_mask_bit_31_0 = error_mask.error_mask_bit_31_0;
  38951     bit_error_mask->error_mask_bit_63_32 = error_mask.error_mask_bit_63_32;
  38952     bit_error_mask->error_mask_bit_79_64 = error_mask.error_mask_bit_79_64;
  38953 
  38954     return rv;
  38955 }
  38956 
  38957 /*
  38958  * Function:
  38959  *      _bcm_esw_port_eee_stat_clear
  38960  * Description:
  38961  *      Clear EEE statistics directly by
  38962  *      writing EEE counter register to 0
  38963  * Parameters:
  38964  *      unit - Device number
  38965  *      port - Port number
  38966  * Return Value:
  38967  *      BCM_E_XXX
  38968  */
  38969 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  38970     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  38971 STATIC int
  38972 _bcm_esw_port_eee_stat_clear(int unit, bcm_port_t port)
  38973 {
  38974     int idx;
  38975     uint64 val64;
  38976     soc_reg_t def_regs[] = {
  38977         RX_EEE_LPI_DURATION_COUNTERr,
  38978         RX_EEE_LPI_EVENT_COUNTERr,
  38979         TX_EEE_LPI_DURATION_COUNTERr,
  38980         TX_EEE_LPI_EVENT_COUNTERr
  38981     };
  38982     soc_reg_t ge_regs[] = {
  38983         GRX_EEE_LPI_DURATION_COUNTERr,
  38984         GRX_EEE_LPI_EVENT_COUNTERr,
  38985         GTX_EEE_LPI_DURATION_COUNTERr,
  38986         GTX_EEE_LPI_EVENT_COUNTERr
  38987     };
  38988     soc_reg_t *regs = def_regs;
  38989 
  38990     COMPILER_64_ZERO(val64);
  38991 
  38992     if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port)) {
  38993         regs = ge_regs;
  38994     }
  38995 
  38996     for (idx = 0; idx < sizeof(def_regs) / sizeof(def_regs[0]); idx++) {
  38997         SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, regs[idx], 0, val64));
  38998     }
  38999 
  39000     return BCM_E_NONE;
  39001 }
  39002 #endif
  39003 
  39004 /*
  39005  * Function:
  39006  *      bcm_esw_port_control_set
  39007  * Description:
  39008  *      Enable/Disable specified port feature.
  39009  * Parameters:
  39010  *      unit - Device number
  39011  *      port - Port number
  39012  *      type - Enum value of the feature
  39013  *      value - value to be set
  39014  * Return Value:
  39015  *      BCM_E_NONE
  39016  *      BCM_E_UNAVAIL - Functionality not available
  39017  */
  39018 int
  39019 bcm_esw_port_control_set(int unit, bcm_port_t port,
  39020                          bcm_port_control_t type, int value)
  39021 {
  39022     int rv = BCM_E_UNAVAIL;
  39023     int valid = 0;
  39024 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  39025     soc_reg_t egr_port_reg;
  39026 #endif
  39027 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39028     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  39029                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  39030 #endif
  39031 #if defined(BCM_GREYHOUND_SUPPORT)
  39032     int cur_val = 0;
  39033 #endif
  39034 #if defined (BCM_METROLITE_SUPPORT)
  39035     bcm_pbmp_t pbm;
  39036 #endif
  39037 #if defined(BCM_TOMAHAWK3_SUPPORT)
  39038 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry;
  39039 bcm_pbmp_t  pbmp;
  39040 #endif
  39041 
  39042     LOG_INFO(BSL_LS_BCM_PORT,
  39043              (BSL_META_U(unit,
  39044                          "bcm_port_control_set: u=%d p=%d rv=%d : %d\n"),
  39045               unit, port, value, (int)type));
  39046 
  39047     /* Make sure port module is initialized. */
  39048     PORT_INIT(unit);
  39049 
  39050     if(bcm_common_oamp_port_enable_get(unit, port) &&
  39051             (type != bcmPortControlSatEnable)) {
  39052         /* Only bcmPortControlSatEnable is permitted on oamp port */
  39053         LOG_ERROR(BSL_LS_BCM_PORT,
  39054                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  39055                    port));
  39056         return BCM_E_PARAM;
  39057     }
  39058 
  39059     /* Call Port Control module */
  39060     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  39061         /*
  39062          * Check that port control feature is valid in Port Control.
  39063          * If valid, call Port Control routine to handle feature; otherwise
  39064          * continue with rest of logic.
  39065          */
  39066         BCM_IF_ERROR_RETURN
  39067             (bcmi_esw_portctrl_control_validate(unit, type, &valid));
  39068         if (valid) {
  39069             return bcmi_esw_portctrl_control_set(unit, port, type, value);
  39070         }
  39071     }
  39072 
  39073 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  39074     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  39075                     SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) ||
  39076                     SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  39077                     EGR_PORT_64r : EGR_PORTr;
  39078 #endif
  39079 
  39080 #if defined(BCM_SHADOW_SUPPORT)
  39081     if (SOC_IS_SHADOW(unit)) {
  39082         /*  If unsupported port control type, return unavail */
  39083         if (!_bcm_port_type_shadow_support (unit, port, type)) {
  39084             return BCM_E_UNAVAIL;
  39085         }
  39086     }
  39087 #endif /* BCM_SHADOW_SUPPORT */
  39088 
  39089     if (type == bcmPortControlEsmEligibility) {
  39090 #ifdef BCM_TRIUMPH3_SUPPORT
  39091         /* For bcmPortControlEsmEligibility, a non-local port
  39092          * is accepted. For other port controls, a non-local
  39093          * port is not accepted. Hence, bcmPortControlEsmEligibility
  39094          * is implemented here, before the _bcm_esw_port_gport_validate
  39095          * procedure below.
  39096          */
  39097         return bcm_tr3_port_esm_eligible_set(unit, port, value);
  39098 #endif /* BCM_TRIUMPH3_SUPPORT */
  39099     }
  39100 
  39101 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  39102     if (
  39103 #ifdef BCM_HGPROXY_COE_SUPPORT
  39104         ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  39105         (soc_feature(unit, soc_feature_channelized_switching))) &&
  39106          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  39107          ((type == bcmPortControlVlanVpGroupIngress) ||
  39108           (type == bcmPortControlVlanVpGroupEgress))) ||
  39109 #endif
  39110         BCM_GPORT_IS_TRUNK(port) ||
  39111         BCM_GPORT_IS_VLAN_PORT(port) ||
  39112         BCM_GPORT_IS_NIV_PORT(port) ||
  39113         BCM_GPORT_IS_VXLAN_PORT(port) ||
  39114         BCM_GPORT_IS_MIM_PORT(port) ||
  39115         BCM_GPORT_IS_MPLS_PORT(port) ||
  39116         BCM_GPORT_IS_L2GRE_PORT(port) ||
  39117         BCM_GPORT_IS_FLOW_PORT(port) ||
  39118         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  39119         return bcm_td_vp_control_set(unit, port, type, value);
  39120     } else
  39121 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  39122 #if defined(BCM_KATANA2_SUPPORT)
  39123     if ((BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port))
  39124          && SOC_IS_KATANA2(unit)) {
  39125         rv = BCM_E_NONE;
  39126     } else
  39127 #endif /* BCM_KATANA2_SUPPORT */
  39128     if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) ||
  39129         (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) {
  39130         rv = BCM_E_NONE;
  39131     } else
  39132 #ifdef BCM_HGPROXY_COE_SUPPORT
  39133     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  39134         (soc_feature(unit, soc_feature_channelized_switching))) &&
  39135         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  39136         rv = BCM_E_NONE;
  39137     } else
  39138 #endif
  39139 #ifdef BCM_TRIDENT3_SUPPORT
  39140     if (soc_feature(unit, soc_feature_pp_port_control) &&
  39141         (type == bcmPortControlPacketProcssingPort) ) {
  39142         rv = BCM_E_NONE;
  39143     } else
  39144 #endif
  39145     {
  39146         rv = bcm_esw_port_control_validate(unit, port, type, &port);
  39147     }
  39148     BCM_IF_ERROR_RETURN(rv);
  39149     rv = BCM_E_UNAVAIL;
  39150 
  39151     /*
  39152      * At this point, 'port' can be:
  39153      *    GPORT WLAN
  39154      *    GPORT PROXY
  39155      *    BCM valid local port
  39156      *
  39157      * Some switch cases only handles 'port' in BCM port format
  39158      * (non-gport).  Corresponding checks must be added in those
  39159      * cases to ensure that 'port' is not a gport.
  39160      */
  39161     switch (type) {
  39162     case bcmPortControlBridge:
  39163         if (BCM_GPORT_IS_SET(port)) {
  39164             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39165                                        PORT_BRIDGEf, value);
  39166         } else {
  39167             PORT_LOCK(unit);
  39168             rv = _bcm_esw_port_control_bridge_set(unit, port, value);
  39169             PORT_UNLOCK(unit);
  39170         }
  39171         break;
  39172     case bcmPortControlTrunkHashSet:
  39173 #if defined(BCM_TRIUMPH3_SUPPORT)
  39174         if (SOC_IS_TRIUMPH3(unit)) {
  39175             return BCM_E_UNAVAIL;
  39176         } else
  39177 #endif /* BCM_TRIUMPH3_SUPPORT */
  39178         {
  39179 #if defined(BCM_BRADLEY_SUPPORT)
  39180             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  39181                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39182                                            RTAG7_HASH_CFG_SEL_TRUNKf,
  39183                                            (value) ? 1 : 0);
  39184             }
  39185 #endif /* BCM_BRADLEY_SUPPORT */
  39186         }
  39187         break;
  39188     case bcmPortControlFabricTrunkHashSet:
  39189 #if defined(BCM_TRIUMPH3_SUPPORT)
  39190         if (SOC_IS_TRIUMPH3(unit)) {
  39191             return BCM_E_UNAVAIL;
  39192         } else
  39193 #endif /* BCM_TRIUMPH3_SUPPORT */
  39194         {
  39195 #if defined(BCM_BRADLEY_SUPPORT)
  39196             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  39197                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39198                                            RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf,
  39199                                            (value) ? 1 : 0);
  39200             }
  39201 #endif /* BCM_BRADLEY_SUPPORT */
  39202         }
  39203         break;
  39204     case bcmPortControlECMPHashSet:
  39205 #if defined(BCM_TRIUMPH3_SUPPORT)
  39206         if (SOC_IS_TRIUMPH3(unit)) {
  39207             return BCM_E_UNAVAIL;
  39208         } else
  39209 #endif /* BCM_TRIUMPH3_SUPPORT */
  39210         {
  39211 #if defined(BCM_BRADLEY_SUPPORT)
  39212             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  39213                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39214                                            RTAG7_HASH_CFG_SEL_ECMPf,
  39215                                            (value) ? 1 : 0);
  39216             }
  39217 #endif /* BCM_BRADLEY_SUPPORT */
  39218         }
  39219         break;
  39220     case bcmPortControlLoadBalanceHashSet:
  39221 #if defined(BCM_TRIUMPH3_SUPPORT)
  39222         if (SOC_IS_TRIUMPH3(unit)) {
  39223             return BCM_E_UNAVAIL;
  39224         } else
  39225 #endif /* BCM_TRIUMPH3_SUPPORT */
  39226         {
  39227 #if defined(BCM_BRADLEY_SUPPORT)
  39228             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  39229                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39230                                            RTAG7_HASH_CFG_SEL_LBIDf,
  39231                                            (value) ? 1 : 0);
  39232             }
  39233 #endif /* BCM_BRADLEY_SUPPORT */
  39234         }
  39235         break;
  39236     case bcmPortControlLoadBalancingNumber:
  39237 #if defined(BCM_BRADLEY_SUPPORT)
  39238         if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  39239 #if defined(BCM_TOMAHAWK3_SUPPORT)
  39240             if (SOC_IS_TOMAHAWK3(unit)) {
  39241                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39242                                        RTAG7_PORT_LBNf,
  39243                                        (value) & 0x3f);
  39244             } else
  39245 #endif /* BCM_TOMAHAWK3_SUPPORT */
  39246             {
  39247                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39248                                        RTAG7_PORT_LBNf,
  39249                                        (value) & 0xf);
  39250             }
  39251         }
  39252 #endif /* BCM_BRADLEY_SUPPORT */
  39253         break;
  39254     case bcmPortControlErrorSymbolDetect:
  39255 #if defined(BCM_GREYHOUND_SUPPORT)
  39256         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  39257             SOC_IS_GREYHOUND2(unit)) {
  39258             rv = BCM_E_UNAVAIL;
  39259         } else
  39260 #endif /* BCM_GREYHOUND_SUPPORT */
  39261         {
  39262 #ifdef BCM_XGS3_SWITCH_SUPPORT
  39263             if (SOC_IS_XGS3_SWITCH(unit)) {
  39264                 rv = _bcm_esw_port_err_sym_detect_set(unit, port, value);
  39265             }
  39266 #endif
  39267         }
  39268         break;
  39269     case bcmPortControlErrorSymbolCount:
  39270 #if defined(BCM_GREYHOUND_SUPPORT)
  39271         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  39272             SOC_IS_GREYHOUND2(unit)) {
  39273             rv = BCM_E_UNAVAIL;
  39274         } else
  39275 #endif /* BCM_GREYHOUND_SUPPORT */
  39276         {
  39277 #ifdef BCM_XGS3_SWITCH_SUPPORT
  39278             if (SOC_IS_XGS3_SWITCH(unit)) {
  39279              int temp = 0;
  39280                 /* Error symbol count is read only and cleared on read. */
  39281                 rv = _bcm_esw_port_err_sym_count_get(unit, port, &temp);
  39282             }
  39283 #endif
  39284         }
  39285         break;
  39286 #if defined(INCLUDE_L3)
  39287     case bcmPortControlIP4:
  39288         if (SOC_IS_XGS3_SWITCH(unit)) {
  39289             if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  39290                 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER,
  39291                                            V4L3_ENABLEf, (value) ? 1 : 0);
  39292             } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  39293                 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG,
  39294                                            V4L3_ENABLEf, (value) ? 1 : 0);
  39295             } else {
  39296                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39297                                            V4L3_ENABLEf, (value) ? 1 : 0);
  39298             }
  39299 
  39300 #if defined(BCM_TRIUMPH_SUPPORT)
  39301             if (BCM_SUCCESS(rv) &&
  39302                 soc_feature(unit, soc_feature_esm_support)) {
  39303                 if (SOC_IS_TRIUMPH3(unit)) { 
  39304                     break;
  39305                 }
  39306                 if (!BCM_GPORT_IS_SET(port)) {
  39307                     rv = _bcm_tr_l3_enable(unit, port, 0, (value) ? 1 : 0);
  39308                 }
  39309             }
  39310 #endif /* BCM_TRIUMPH_SUPPORT */
  39311         }
  39312         break;
  39313     case bcmPortControlIP6:
  39314         if (SOC_IS_XGS3_SWITCH(unit)) {
  39315             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39316                                        V6L3_ENABLEf, (value) ? 1 : 0);
  39317 #if defined(BCM_TRIUMPH_SUPPORT)
  39318             if (BCM_SUCCESS(rv) &&
  39319                 soc_feature(unit, soc_feature_esm_support)) {
  39320                 if (SOC_IS_TRIUMPH3(unit)) { 
  39321                     break;
  39322                 }
  39323                 if (!BCM_GPORT_IS_SET(port)) {
  39324                     rv = _bcm_tr_l3_enable(unit, port, BCM_L3_IP6,
  39325                                            (value) ? 1 : 0);
  39326                 }
  39327             }
  39328 #endif /* BCM_TRIUMPH_SUPPORT */
  39329         }
  39330         break;
  39331     case bcmPortControlIP4Mcast:
  39332         if (SOC_IS_XGS3_SWITCH(unit)) {
  39333             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39334                                        V4IPMC_ENABLEf, (value) ? 1 : 0);
  39335         }
  39336         break;
  39337     case bcmPortControlIP6Mcast:
  39338         if (SOC_IS_XGS3_SWITCH(unit)) {
  39339             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39340                                        V6IPMC_ENABLEf, (value) ? 1 : 0);
  39341         }
  39342         break;
  39343     case bcmPortControlIPMC4Ucast:
  39344         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  39345             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39346                     IPMCV4_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0);
  39347         }
  39348         break;
  39349     case bcmPortControlIPMC6Ucast:
  39350         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  39351             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39352                     IPMCV6_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0);
  39353         }
  39354         break;
  39355     case bcmPortControlMpls:
  39356 #if defined(BCM_TRIUMPH_SUPPORT)
  39357         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39358                                    MPLS_ENABLEf, (value) ? 1 : 0);
  39359 #endif
  39360         break;
  39361     case bcmPortControlMacInMac:
  39362         if (!soc_feature(unit, soc_feature_mim)) {
  39363             break;
  39364         }
  39365 #if defined(BCM_TRIUMPH2_SUPPORT)
  39366         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39367                                    MIM_TERM_ENABLEf, (value) ? 1 : 0);
  39368         if(rv == BCM_E_NONE) {
  39369 #if defined(BCM_TRIDENT3_SUPPORT)
  39370             if(SOC_IS_TRIDENT3X(unit)) {
  39371                 int app = 0;
  39372                 if (0x0 != value)  {
  39373                     app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_ENABLE;
  39374                 } else {
  39375                     app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_DISABLE;
  39376                 }
  39377                 rv = soc_cancun_app_dest_entry_set (unit,
  39378                     PORT_TABm, port, PORT_TYPEf, app, 0x0);
  39379                 if (BCM_E_NONE != rv ) {
  39380                     LOG_ERROR(BSL_LS_BCM_L2,
  39381                         (BSL_META_U(unit,
  39382                         "MIM_MC_TERM_ENABLE cfg error\n")));
  39383                 }
  39384             } else
  39385 #endif
  39386             {
  39387                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39388                                            MIM_MC_TERM_ENABLEf, (value) ? 1 : 0);
  39389             }
  39390         }
  39391 #endif
  39392         break;
  39393 
  39394     case bcmPortControlMimUcastTermEnable:
  39395         if (!soc_feature(unit, soc_feature_mim)) {
  39396             break;
  39397         }
  39398 #if defined(BCM_TRIUMPH2_SUPPORT)
  39399         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39400                                    MIM_TERM_ENABLEf, (value) ? 1 : 0);
  39401 #endif
  39402         break;
  39403 
  39404     case bcmPortControlMimMcastTermEnable:
  39405         if (!soc_feature(unit, soc_feature_mim)) {
  39406             break;
  39407         }
  39408 #if defined(BCM_TRIUMPH2_SUPPORT)
  39409         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39410                                        MIM_MC_TERM_ENABLEf, (value) ? 1 : 0);
  39411 #endif
  39412         break;
  39413 
  39414     case bcmPortControlSrcBmacMissToCpu:
  39415 #ifdef BCM_TRIUMPH2_SUPPORT
  39416         if (SOC_IS_TRIDENT3X(unit)) { /* see SDK-124007 */
  39417             return BCM_E_UNAVAIL;
  39418         }
  39419         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  39420             SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  39421             SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) ||
  39422             SOC_IS_KATANA(unit)) {
  39423             /* 0x2: ToCPU 0x1: Drop(default) */
  39424             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39425                                        CML_BMAC_NEWf, (value) ? 0x2 : 0x1);
  39426         }
  39427 #endif /* BCM_TRIUMPH2_SUPPORT */
  39428         break;
  39429 
  39430     case bcmPortControlQosRemarkResolution:
  39431 #ifdef BCM_TRIDENT3_SUPPORT
  39432         if (SOC_IS_TRIDENT3X(unit)) {
  39433             /* Two resolution supported by TD3 hardware:
  39434              * 1: Serial resolution.
  39435              * 3: Layered resolution.
  39436              * Default is Layered resolution
  39437              */
  39438             if (value == BCM_PORT_QOS_SERIAL_RESOLUTION) {
  39439                 value = 1;
  39440             } else if (value == BCM_PORT_QOS_LAYERED_RESOLUTION) {
  39441                 value = 3;
  39442             } else {
  39443                 return BCM_E_PARAM;
  39444             }
  39445             rv = _bcm_esw_egr_port_tab_set(unit, port, QOS_CTRL_IDf, value);
  39446         }
  39447 #endif /* BCM_TRIDENT3_SUPPORT */
  39448         break;
  39449 
  39450     case bcmPortControlFabricQueue:
  39451 #if defined(BCM_TRIUMPH2_SUPPORT)
  39452         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39453 #if defined(BCM_TRIDENT3_SUPPORT)
  39454         if (SOC_IS_TRIDENT3X(unit) &&
  39455             soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  39456             rv = bcm_esw_port_egr_lport_field_set(
  39457                   unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf,
  39458                   (value) ? 1 : 0);
  39459             BCM_IF_ERROR_RETURN(rv);
  39460         }
  39461 #endif
  39462         if (IS_ST_PORT(unit, port)) {
  39463             if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) {
  39464                 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port,
  39465                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0);
  39466             }
  39467             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){
  39468                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  39469                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  39470             }
  39471         } else {
  39472 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  39473             /* Allow CPU port on TD2+ to add extended header */
  39474             if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) {
  39475                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  39476                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  39477             }
  39478 #endif
  39479 #if defined(BCM_TOMAHAWK_SUPPORT)
  39480             if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) {
  39481                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  39482                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  39483             }
  39484 #endif
  39485         }
  39486 #endif
  39487         break;
  39488 #endif /* INCLUDE_L3 */
  39489     case bcmPortControlIP4McastL2:
  39490 #if defined(BCM_TRX_SUPPORT)
  39491         if (SOC_IS_TD2_TT2(unit) &&
  39492                 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  39493                                                  IPMCV4_L2_ENABLEf)) {
  39494             rv = _bcm_trx_source_trunk_map_set(unit, port,
  39495                                   IPMCV4_L2_ENABLEf, (value) ? 1 : 0);
  39496         } else {
  39497             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39498                                     V4IPMC_L2_ENABLEf, (value) ? 1 : 0);
  39499         }
  39500 #endif /* BCM_TRX_SUPPORT */
  39501         break;
  39502     case bcmPortControlIP6McastL2:
  39503 #if defined(BCM_TRX_SUPPORT)
  39504         if (SOC_IS_TD2_TT2(unit) &&
  39505                 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  39506                                                  IPMCV6_L2_ENABLEf)) {
  39507             rv = _bcm_trx_source_trunk_map_set(unit, port,
  39508                                   IPMCV6_L2_ENABLEf, (value) ? 1 : 0);
  39509         } else {
  39510             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39511                                        V6IPMC_L2_ENABLEf, (value) ? 1 : 0);
  39512         }
  39513 #endif /* BCM_TRX_SUPPORT */
  39514         break;
  39515     case bcmPortControlPassControlFrames:
  39516         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39517 #ifdef BCM_XGS3_SWITCH_SUPPORT
  39518         if (SOC_IS_XGS3_SWITCH(unit) && IS_E_PORT(unit, port)) {
  39519             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  39520                                        PASS_CONTROL_FRAMESf,
  39521                                        (value) ? 1 : 0);
  39522         }
  39523 #endif
  39524 #ifdef BCM_XGS_SWITCH_SUPPORT
  39525         if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) ||
  39526             (IS_GE_PORT(unit, port)
  39527              && soc_feature(unit, soc_feature_unified_port)) ||
  39528             (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) {
  39529             /* Enable Control Frames in BigMAC */
  39530             if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) {
  39531                 uint32 rval32 = 0;
  39532                 PORT_LOCK(unit);
  39533                 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32);
  39534                 if (BCM_SUCCESS(rv)) {
  39535                     /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved
  39536                      * Enable  Control Frame : Set 0. Packet go through
  39537                      * Disable Control Frame : Set 1. Packet is purged.
  39538                      */
  39539                     if(value) {
  39540                         rval32 &= ~(1 << 11);
  39541                     } else {
  39542                         rval32 |= (1 << 11);
  39543                     }
  39544                     rv = WRITE_PGW_MAC_RSV_MASKr(unit, port, rval32);
  39545                 }
  39546                 PORT_UNLOCK(unit);
  39547             } else {
  39548                 PORT_LOCK(unit);
  39549 
  39550                 if (SOC_IS_SABER2(unit)) {
  39551                     if (IS_MXQ_PORT(unit, port)) {
  39552                         rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  39553                                                    PASS_PAUSE_FRAMEf, value ? 1 : 0);
  39554                         if (rv == SOC_E_NONE)
  39555                             rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  39556                                                    PASS_CONTROL_FRAMEf, value ? 1 : 0);
  39557                     } else {
  39558                         rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  39559                                                    PASS_PAUSE_FRAMEf, value ? 1 : 0);
  39560                         if (rv == SOC_E_NONE)
  39561                             rv = soc_reg_field32_modify(unit,  IECELL_CONFIGr, port,
  39562                                                    PASS_CONTROL_FRAMEf, value ? 1 : 0);
  39563                     }
  39564                 }
  39565                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39566                                      SOC_MAC_PASS_CONTROL_FRAME, value);
  39567                 PORT_UNLOCK(unit);
  39568             }
  39569         }
  39570 #endif
  39571         break;
  39572 #ifdef BCM_XGS3_SWITCH_SUPPORT
  39573     case bcmPortControlFilterLookup:
  39574 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  39575         value = value ? 1 : 0;
  39576         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39577                                        VFP_ENABLEf, value);
  39578 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  39579         break;
  39580     case bcmPortControlFilterIngress:
  39581         value = value ? 1 : 0;
  39582             /* Enable/disable ingress filtering. */
  39583         if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  39584             rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER,
  39585                                        FILTER_ENABLEf, value);
  39586         } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  39587             rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG,
  39588                                        FILTER_ENABLEf, value);
  39589         } else {
  39590             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39591                                        FILTER_ENABLEf, value);
  39592         }
  39593 
  39594         break;
  39595     case bcmPortControlFilterEgress:
  39596 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  39597         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39598         value = value ? 1 : 0;
  39599         /* Enable/disable egress filtering. */
  39600         if (SOC_REG_FIELD_VALID(unit, egr_port_reg, EFP_FILTER_ENABLEf)) {
  39601             rv = soc_reg_field32_modify(unit, egr_port_reg, port,
  39602                                         EFP_FILTER_ENABLEf, value);
  39603         } else {
  39604             rv = _bcm_esw_egr_port_tab_set(unit, port,
  39605                                           EFP_FILTER_ENABLEf, value);
  39606         }
  39607 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  39608         break;
  39609     case bcmPortControlFrameSpacingStretch:
  39610         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39611         rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39612                               SOC_MAC_CONTROL_FRAME_SPACING_STRETCH,
  39613                               value));
  39614         break;
  39615     case bcmPortControlPreservePacketPriority:
  39616 #if ((defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)) \
  39617     || defined(BCM_RAVEN_SUPPORT))
  39618         if (SOC_IS_TRIUMPH3(unit)) {
  39619             /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */
  39620             if (value) {
  39621                 /* Remap pointer to default dot1p profile */
  39622                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39623                                            DOT1P_REMAP_POINTERf, 0);
  39624             }
  39625         } else {
  39626             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39627                                        USE_INCOMING_DOT1Pf, (value) ? 1 : 0);
  39628         }
  39629 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || defined(BCM_RAVEN_SUPPORT) */
  39630 #if defined(BCM_SHADOW_SUPPORT)
  39631         if (SOC_IS_SHADOW(unit)) {
  39632             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39633             rv = soc_reg_field32_modify(unit, PRIORITY_MAPPING_SELECTr, port,
  39634                                         USE_INPUT_PRIORIYf, 1 );
  39635         }
  39636 #endif
  39637         break;
  39638     case bcmPortControlLearnClassEnable:
  39639 #if defined(BCM_TRX_SUPPORT)
  39640         if (soc_feature(unit, soc_feature_class_based_learning)) {
  39641             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39642                                        CLASS_BASED_SM_ENABLEf, value ? 1 : 0);
  39643         }
  39644 #endif /* BCM_TRX_SUPPORT */
  39645           break;
  39646     case bcmPortControlTrustIncomingVlan:
  39647 #if defined(BCM_TRIDENT3_SUPPORT)
  39648         if (SOC_IS_TRIDENT3X(unit)) {
  39649             uint32 tpid_enables = value;
  39650             if (tpid_enables) {
  39651                 uint32 tpid_index;
  39652                 /* recover tpid_index from egress */
  39653                 BCM_IF_ERROR_RETURN(
  39654                     _bcm_fb2_egr_vlan_control_field_get(
  39655                     unit, port, OUTER_TPID_INDEXf, &tpid_index));
  39656                 tpid_enables = 1 << tpid_index;
  39657             }
  39658             rv = _bcm_fb2_port_tpid_enable_set(unit, port, tpid_enables);
  39659             BCM_IF_ERROR_RETURN(rv);
  39660         }  else
  39661 #endif
  39662 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  39663         {
  39664             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39665                                    TRUST_INCOMING_VIDf, (value) ? 1 : 0);
  39666         }
  39667 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  39668           break;
  39669     case bcmPortControlDoNotCheckVlan:
  39670 #if defined(BCM_TRX_SUPPORT)
  39671 #if defined(BCM_TRIDENT3_SUPPORT)
  39672         if (SOC_IS_TRIDENT3X(unit)) {
  39673             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39674                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39675             BCM_IF_ERROR_RETURN(rv);
  39676         }
  39677 #endif
  39678         if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  39679             if (CMIC_PORT(unit) == port) {
  39680                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_HIGIG,
  39681                                            DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39682             } else {
  39683                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39684                                            DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39685             }
  39686         } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  39687                     DISABLE_VLAN_CHECKSf)) {
  39688 #if defined(BCM_KATANA2_SUPPORT)
  39689             if (SOC_IS_KATANA2(unit)) {
  39690                 rv = _bcm_kt2_source_trunk_map_set(unit, port,
  39691                         DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39692             } else
  39693 #endif
  39694             {
  39695                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  39696                         DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39697             }
  39698         }
  39699 #endif /* BCM_TRX_SUPPORT */
  39700         break;
  39701     case bcmPortControlDoNotCheckVlanFromCpu:
  39702 #if defined(BCM_TRX_SUPPORT)
  39703 #if defined(BCM_TRIDENT3_SUPPORT)
  39704         if (CMIC_PORT(unit) == port) {
  39705             if (SOC_IS_TRIDENT3X(unit)) {
  39706                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39707                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39708                 BCM_IF_ERROR_RETURN(rv);
  39709             }
  39710         }
  39711 #endif
  39712         if (CMIC_PORT(unit) == port) {
  39713             if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  39714                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  39715                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39716             } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  39717                         DISABLE_VLAN_CHECKSf)) {
  39718                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  39719                     DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  39720             }
  39721         } else {
  39722             rv = BCM_E_PORT;
  39723         }
  39724 #endif /* BCM_TRX_SUPPORT */
  39725         break;
  39726     case bcmPortControlIEEE8021ASEnableIngress:
  39727         if (soc_feature(unit, soc_feature_rx_timestamp)) {
  39728             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39729                                        IEEE_802_1AS_ENABLEf, (value) ? 1 : 0);
  39730         }
  39731         break;
  39732     case bcmPortControlIEEE8021ASEnableEgress:
  39733 #if defined(BCM_HAWKEYE_SUPPORT)
  39734         if (SOC_IS_HAWKEYE(unit)) {
  39735             rv = soc_reg_field32_modify(unit, EGR_PORTr, port,
  39736                                         IEEE_802_1AS_ENABLEf, (value) ? 1 : 0);
  39737         }
  39738 #endif /* BCM_HAWKEYE_SUPPORT */
  39739         break;
  39740     case bcmPortControlEgressVlanPriUsesPktPri:
  39741 #if defined(BCM_TRX_SUPPORT)
  39742         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  39743 #if defined (BCM_HGPROXY_COE_SUPPORT)
  39744             if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  39745                 BCM_GPORT_IS_SUBPORT_PORT(port)))
  39746 #endif
  39747             {
  39748                 BCM_IF_ERROR_RETURN(
  39749                     _bcm_esw_port_gport_validate(unit, port, &port));
  39750             }
  39751 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  39752             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  39753                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  39754                     rv = bcm_esw_port_egr_lport_field_set(unit,
  39755                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf,
  39756                         value ? 0 : 1);
  39757                 } else {
  39758 #if defined (BCM_HGPROXY_COE_SUPPORT)
  39759                     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  39760                         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  39761                         rv = bcm_esw_port_egr_lport_field_set(
  39762                                 unit, port, EGR_VLAN_CONTROL_1m,
  39763                                 REMARK_OUTER_DOT1Pf, value ? 0 : 1);
  39764                     } else
  39765 #endif
  39766                     {
  39767                         rv = soc_mem_field32_modify(
  39768                                 unit, EGR_VLAN_CONTROL_1m, port,
  39769                                 REMARK_OUTER_DOT1Pf, value ? 0 : 1);
  39770                     }
  39771                 }
  39772             } else
  39773 #endif
  39774             {
  39775                 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  39776                                             REMARK_OUTER_DOT1Pf,
  39777                                             value ? 0 : 1);
  39778 #if defined(BCM_GREYHOUND_SUPPORT)
  39779                 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  39780                     if (BCM_FAILURE(rv)) {
  39781                         return rv;
  39782                     }
  39783                     /*
  39784                      * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  39785                      * Egress VLAN internal priority mapping.
  39786                      */
  39787                     rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  39788                              (unit, (value) ? 1 : -1);
  39789                 }
  39790 #endif /* BCM_GREYHOUND_SUPPORT */
  39791             }
  39792         }
  39793 #endif /* BCM_TRX_SUPPORT */
  39794         break;
  39795     case bcmPortControlEgressModifyDscp:
  39796 #if defined(BCM_TRX_SUPPORT)
  39797         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  39798             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39799 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  39800             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  39801                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  39802                     rv = bcm_esw_port_egr_lport_field_set(unit,
  39803                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf,
  39804                         value ? 1 : 0);
  39805                 } else {
  39806                     rv = soc_mem_field32_modify(unit,
  39807                         EGR_VLAN_CONTROL_1m, port, REMARK_OUTER_DSCPf,
  39808                         value ? 1 : 0);
  39809                 }
  39810             } else
  39811 #endif
  39812             {
  39813                 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  39814                                             REMARK_OUTER_DSCPf,
  39815                                             value ? 1 : 0);
  39816             }
  39817         }
  39818 #endif /* BCM_TRX_SUPPORT */
  39819         break;
  39820     case bcmPortControlIpfixRate:
  39821 #ifdef BCM_TRIUMPH2_SUPPORT
  39822         if (soc_feature(unit, soc_feature_ipfix_rate)) {
  39823             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39824                                        IPFIX_FLOW_METER_IDf, value);
  39825         }
  39826 #endif /* BCM_TRIUMPH2_SUPPORT */
  39827         break;
  39828     case bcmPortControlCustomerQueuing:
  39829         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39830 #ifdef BCM_ENDURO_SUPPORT
  39831         if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) {
  39832             return BCM_E_UNAVAIL;
  39833         }
  39834 #endif
  39835 #ifdef BCM_HELIX5_SUPPORT
  39836         if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit) ||
  39837             SOC_IS_FIREBOLT6(unit)) {
  39838 
  39839             uint64 rval64, rval64_tmp, rval64_reset_tmp;
  39840             soc_reg_t reg;
  39841             uint32 phy_port;
  39842             uint32 mmu_port;
  39843             soc_info_t *si = &SOC_INFO(unit);
  39844 
  39845             if (value < 0 || value > 1) {
  39846                 return BCM_E_PARAM;
  39847             }
  39848 
  39849             COMPILER_64_ZERO(rval64);
  39850             COMPILER_64_ZERO(rval64_tmp);
  39851             COMPILER_64_ZERO(rval64_reset_tmp);
  39852             if (SOC_MEM_IS_VALID(unit, ING_COS_MODEm)) {
  39853                rv = soc_mem_field32_modify(unit, ING_COS_MODEm, port, COS_MODEf, value);
  39854                BCM_IF_ERROR_RETURN(rv);
  39855             } else {
  39856 
  39857                 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  39858                 BCM_IF_ERROR_RETURN(rv);
  39859                 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  39860                                   value);
  39861                 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  39862                 BCM_IF_ERROR_RETURN(rv);
  39863 
  39864                 phy_port = si->port_l2p_mapping[port];
  39865                 mmu_port = si->port_p2m_mapping[phy_port];
  39866                 mmu_port &= (SOC_HX5_MMU_PORT_STRIDE - 1);
  39867 
  39868                 if (mmu_port < 16) {
  39869                     reg = COS_MODE_SPLIT0r;  /* 2 bits per Port 0-15 */
  39870                     COMPILER_64_SET(rval64_tmp, 0, (1 << (mmu_port * 2)));
  39871                     COMPILER_64_SET(rval64_reset_tmp, 0, (3 << (mmu_port * 2)));
  39872                 } else {
  39873                     reg = COS_MODE_64_SPLIT1r; /* 1 bit per Port 16-71 */
  39874                     mmu_port -= 16;
  39875                     if (mmu_port < 32) {
  39876                         COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port));
  39877                     } else {
  39878                         COMPILER_64_SET(rval64_tmp, (1 << (mmu_port - 32)), 0);
  39879                     }
  39880                     COMPILER_64_COPY(rval64_reset_tmp, rval64_tmp);
  39881                 }
  39882 
  39883                 SOC_IF_ERROR_RETURN
  39884                     (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port],
  39885                                           0, &rval64));
  39886                 if (value) {
  39887                     COMPILER_64_OR(rval64, rval64_tmp);
  39888                 } else {
  39889                     COMPILER_64_NOT(rval64_reset_tmp);
  39890                     COMPILER_64_AND(rval64, rval64_reset_tmp);
  39891                 }
  39892                 SOC_IF_ERROR_RETURN
  39893                     (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port],
  39894                                           0, rval64));
  39895                 rv = BCM_E_NONE;
  39896                }
  39897             break;
  39898         }
  39899 #endif /* BCM_HELIX5_SUPPORT */
  39900 #ifdef BCM_TRIDENT3_SUPPORT
  39901         if (SOC_IS_TRIDENT3X(unit)) {
  39902             uint64 rval64, rval64_tmp;
  39903             soc_reg_t reg;
  39904             uint32 pipe_portNum;
  39905             soc_info_t *si = &SOC_INFO(unit);
  39906 
  39907             if (value < 0 || value > 1) {
  39908                 return BCM_E_PARAM;
  39909             }
  39910 
  39911             COMPILER_64_ZERO(rval64);
  39912             COMPILER_64_ZERO(rval64_tmp);
  39913 
  39914             rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  39915             BCM_IF_ERROR_RETURN(rv);
  39916             soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  39917                     value);
  39918             rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  39919             BCM_IF_ERROR_RETURN(rv);
  39920 
  39921             pipe_portNum = port % _TD3_PORTS_PER_PIPE;
  39922             if (pipe_portNum < 64) {
  39923                 reg = COS_MODE_64_SPLIT0r;
  39924             } else {
  39925                 reg = COS_MODE_SPLIT1r;
  39926             }
  39927 
  39928             if (pipe_portNum < 32) {
  39929                 COMPILER_64_SET(rval64_tmp, 0, (1 << pipe_portNum));
  39930             } else {
  39931                 COMPILER_64_SET(rval64_tmp, (1 << (pipe_portNum - 32)), 0);
  39932             }
  39933 
  39934             SOC_IF_ERROR_RETURN
  39935                 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port],
  39936                                           0, &rval64));
  39937             if (value) {
  39938                 COMPILER_64_OR(rval64, rval64_tmp);
  39939             } else {
  39940                 COMPILER_64_NOT(rval64_tmp);
  39941                 COMPILER_64_AND(rval64, rval64_tmp);
  39942             }
  39943 
  39944             SOC_IF_ERROR_RETURN
  39945                 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port],
  39946                                           0, rval64));
  39947             rv = BCM_E_NONE;
  39948             break;
  39949         }
  39950 #endif /* BCM_TRIDENT3_SUPPORT */
  39951 #ifdef BCM_TOMAHAWK_SUPPORT
  39952         if (SOC_IS_TOMAHAWKX(unit)) {
  39953             uint64 rval64, rval64_tmp;
  39954             int pipe, phy_port, mmu_port;
  39955             soc_info_t *si;
  39956 
  39957             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  39958 
  39959                 if (value < 0 || value > 1) {
  39960                     return BCM_E_PARAM;
  39961                 }
  39962 
  39963                 COMPILER_64_ZERO(rval64);
  39964                 COMPILER_64_ZERO(rval64_tmp);
  39965 
  39966                 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  39967                 BCM_IF_ERROR_RETURN(rv);
  39968                 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  39969                                       value);
  39970                 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  39971                 BCM_IF_ERROR_RETURN(rv);
  39972 
  39973                 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, port, &pipe));
  39974                 si = &SOC_INFO(unit);
  39975                 phy_port = si->port_l2p_mapping[port];
  39976                 mmu_port = si->port_p2m_mapping[phy_port];
  39977                 mmu_port &= (SOC_TH_MMU_PORT_STRIDE - 1);
  39978 
  39979                 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port));
  39980                 COMPILER_64_ZERO(rval64);
  39981                 SOC_IF_ERROR_RETURN
  39982                     (soc_tomahawk_xpe_reg_get(unit, COS_MODE_64r, -1, pipe, 0,
  39983                                               &rval64));
  39984                 if (value) {
  39985                     COMPILER_64_OR(rval64, rval64_tmp);
  39986                 } else {
  39987                     COMPILER_64_NOT(rval64_tmp);
  39988                     COMPILER_64_AND(rval64, rval64_tmp);
  39989                 }
  39990 
  39991                 SOC_IF_ERROR_RETURN
  39992                     (soc_tomahawk_xpe_reg_set(unit, COS_MODE_64r, -1, pipe, 0,
  39993                                               rval64));
  39994                 rv = BCM_E_NONE;
  39995             }
  39996             break;
  39997         }
  39998 #endif /* BCM_TOMAHAWK_SUPPORT */
  39999 
  40000 #ifdef BCM_TRIDENT2_SUPPORT
  40001         if (SOC_IS_TD2_TT2(unit)) {
  40002             uint32 fval = 0;
  40003             uint64 rval;
  40004 
  40005             if (value <= 4) {
  40006                 fval = value;
  40007             }
  40008 
  40009             if (!SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) {
  40010                 return BCM_E_UNAVAIL;
  40011             }
  40012 
  40013             rv = READ_ING_COS_MODE_64r(unit, port, &rval);
  40014             BCM_IF_ERROR_RETURN(rv);
  40015 
  40016             soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval,
  40017                                   QUEUE_MODEf, fval);
  40018             rv = WRITE_ING_COS_MODE_64r(unit, port, rval);
  40019             break;
  40020         }
  40021 #endif /* BCM_TRIDENT2_SUPPORT */
  40022 #ifdef BCM_TRIUMPH2_SUPPORT
  40023         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  40024             uint32 fval = 0;
  40025             if (SOC_IS_TRIUMPH3(unit)) {
  40026                 if (value <= 4) {
  40027                     fval = value;
  40028                 }
  40029             } else {
  40030                 if (value) {
  40031                     fval = 3;
  40032                 } else {
  40033                     fval = 0;
  40034                 }
  40035             }
  40036 
  40037             rv = BCM_E_UNAVAIL;
  40038 
  40039             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  40040                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) {
  40041                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  40042                                                 SELECTf, fval);
  40043                 }
  40044                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, QUEUE_MODEf)) {
  40045                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  40046                                                 QUEUE_MODEf, fval);
  40047                     /* 0 - COS1 port COS, 1 - COS2 vlan COS */
  40048                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  40049                                                 COS_MODEf, 1);
  40050 
  40051                 }
  40052             }
  40053             if (SOC_REG_IS_VALID(unit, COS_MODEr)) {
  40054                 if (SOC_REG_FIELD_VALID(unit, COS_MODEr, SELECTf)) {
  40055                     rv = soc_reg_field32_modify(unit, COS_MODEr, REG_PORT_ANY,
  40056                                                 SELECTf, fval);
  40057                 }
  40058             }
  40059 
  40060         }
  40061 #endif /* BCM_TRIUMPH2_SUPPORT */
  40062 #ifdef BCM_KATANA_SUPPORT
  40063         if (SOC_IS_KATANAX(unit)) {
  40064             uint32 ing_cos_mode ;
  40065             uint32 rqe_cos_mode;
  40066             uint32      rval = 0;
  40067 /*
  40068  * If custom queueing is enabled the ing_cos_mode is set to 1 but 1 is not
  40069  * valid for rqe_cos_mode
  40070  * setting it to 0 if the ing_cos_mode is 1.
  40071  * if value is 4 that means configure service queuing only for unicast
  40072  * traffic. i.e if value = 4 then ing_cos_mode = 3 and rqe_cos_mode 0 or 2.
  40073  */         if (value == 4) {
  40074                 ing_cos_mode = 3;
  40075             } else {
  40076                 ing_cos_mode = (value <= 3 ? value : 0);
  40077             }
  40078             if (IS_HG_PORT(unit, port)) {
  40079                 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 2 : ing_cos_mode;
  40080             } else {
  40081                 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 0 : ing_cos_mode;
  40082             }
  40083 
  40084             if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, COS_MODEf)) {
  40085                 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  40086                                             COS_MODEf, ing_cos_mode);
  40087             }
  40088 
  40089             if (SOC_IS_KATANA(unit)) {
  40090                 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval));
  40091                 soc_reg_field_set(unit, RQE_PORT_CONFIGr, &rval, COS_MODEf,
  40092                                   rqe_cos_mode);
  40093                 SOC_IF_ERROR_RETURN(WRITE_RQE_PORT_CONFIGr(unit, port, rval));
  40094             } else {
  40095 #if defined(BCM_KATANA2_SUPPORT)
  40096                 if (SOC_IS_KATANA2(unit)) {
  40097                     SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  40098                     soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, COS_MODEf,
  40099                                       rqe_cos_mode);
  40100                     SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval));
  40101                 }
  40102 #endif
  40103             }
  40104         }
  40105 #endif /* BCM_KATANA_SUPPORT */
  40106         break;
  40107 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  40108 
  40109 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT)
  40110     case bcmPortControlOAMEnable:
  40111         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  40112                                    OAM_ENABLEf, value ? 1 : 0);
  40113 #if defined(BCM_KATANA2_SUPPORT)
  40114         if (SOC_IS_KATANA2(unit)) {
  40115             rv = _bcm_esw_egr_port_tab_set(unit, port,
  40116                                    OAM_ENABLEf, value ? 1 : 0);
  40117         }
  40118 #endif
  40119         break;
  40120 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */
  40121 
  40122 #if defined(BCM_OLP_SUPPORT)
  40123     case bcmPortControlOlpEnable:
  40124 
  40125         if (soc_feature(unit, soc_feature_olp)) {
  40126             ing_en_efilter_bitmap_entry_t efilter_entry;
  40127             bcm_module_t module_id = 0;
  40128             bcm_module_t my_modid;
  40129             bcm_port_t port_id;
  40130             bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  40131             int         local_id;
  40132             uint32      olp_enable;
  40133             pbmp_t      pbmp;
  40134 
  40135             olp_enable = value ? 1 : 0;
  40136 
  40137             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  40138 
  40139             if (BCM_GPORT_IS_SET(port)) {
  40140                 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id,
  40141                             &port_id, &trunk_id, &local_id));
  40142 
  40143 #if defined(BCM_KATANA2_SUPPORT)
  40144                 if (SOC_IS_KATANA2(unit) &&
  40145                         (BCM_GPORT_IS_SUBPORT_PORT(port)) &&
  40146                         ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
  40147                          (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) {
  40148 
  40149                     LOG_ERROR(BSL_LS_BCM_L2,
  40150                             (BSL_META_U(unit,
  40151                                         "OLP is not allowed on SUBPORT. \
  40152                                         \n")));
  40153                     return BCM_E_PARAM;
  40154                 }
  40155 #endif
  40156             } else {
  40157                 port_id = port;
  40158             }
  40159             if ((module_id == 0) || (module_id == my_modid)) {
  40160 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  40161                 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  40162                     iarb_ing_port_table_entry_t entry;
  40163                     port_tab_entry_t            port_entry;
  40164                     uint64                      mac;
  40165                     int                         prefix_check = 0;
  40166 
  40167                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm,
  40168                                         MEM_BLOCK_ANY, port_id, &entry));
  40169                     soc_IARB_ING_PORT_TABLEm_field32_set(unit, &entry,
  40170                                                           OLP_ENABLEf, olp_enable);
  40171                     SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PORT_TABLEm,
  40172                                          MEM_BLOCK_ALL, port_id, &entry));
  40173 
  40174 
  40175                     /* Enable/Disable the prefix checking on the OLP port
  40176                      * If OLP is being enabled  - Disable prefix checking
  40177                      * If OLP is being disabled - Enable prefix checking if it
  40178                      *                            is configured.
  40179                      */
  40180                     prefix_check = 0;
  40181                     if (0 == olp_enable) {
  40182                         SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac));
  40183                         if (!COMPILER_64_IS_ZERO(mac)) {
  40184                             prefix_check = 1;
  40185                         }
  40186                     }
  40187                     SOC_IF_ERROR_RETURN(READ_PORT_TABm(unit,
  40188                                                        MEM_BLOCK_ANY,
  40189                                                        port_id,
  40190                                                        &port_entry));
  40191                     soc_PORT_TABm_field32_set(unit,
  40192                                               &port_entry,
  40193                                               OLP_MAC_DA_PREFIX_CHECK_ENABLEf,
  40194                                               prefix_check);
  40195 
  40196                     SOC_IF_ERROR_RETURN(WRITE_PORT_TABm(unit,
  40197                                                         MEM_BLOCK_ALL,
  40198                                                         port_id,
  40199                                                         &port_entry));
  40200                 } else
  40201 #endif
  40202                 {
  40203                     iarb_ing_physical_port_entry_t  entry;
  40204                     ing_physical_port_table_entry_t port_entry;
  40205                     uint64                          mac;
  40206                     int                             prefix_check = 0;
  40207 
  40208                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm,
  40209                                          MEM_BLOCK_ANY, port_id, &entry));
  40210                     soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry,
  40211                                          OLP_ENABLEf, olp_enable);
  40212                     SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PHYSICAL_PORTm,
  40213                                          MEM_BLOCK_ALL, port_id, &entry));
  40214 
  40215                     /* Enable/Disable the prefix checking on the OLP port
  40216                      * If OLP is being enabled  - Disable prefix checking
  40217                      * If OLP is being disabled - Enable prefix checking if it
  40218                      *                            is configured.
  40219                      */
  40220                     prefix_check = 0;
  40221                     if (0 == olp_enable) {
  40222                         SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac));
  40223                         if (!COMPILER_64_IS_ZERO(mac)) {
  40224                             prefix_check = 1;
  40225                         }
  40226                     }
  40227                     SOC_IF_ERROR_RETURN(
  40228                                    READ_ING_PHYSICAL_PORT_TABLEm(unit,
  40229                                                                  MEM_BLOCK_ANY,
  40230                                                                  port_id,
  40231                                                                  &port_entry));
  40232 
  40233                     soc_ING_PHYSICAL_PORT_TABLEm_field32_set(unit,
  40234                                                              &port_entry,
  40235                                                              OLP_MAC_DA_PREFIX_CHECK_ENABLEf,
  40236                                                              prefix_check);
  40237                     SOC_IF_ERROR_RETURN(
  40238                                    WRITE_ING_PHYSICAL_PORT_TABLEm(unit,
  40239                                                                   MEM_BLOCK_ALL,
  40240                                                                   port_id,
  40241                                                                   &port_entry));
  40242                 }
  40243                 /* Disable EFILTER */
  40244                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  40245                                        MEM_BLOCK_ANY, 0, &efilter_entry));
  40246                 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm,
  40247                                        &efilter_entry, BITMAPf, &pbmp);
  40248                 if (olp_enable) {
  40249                     SOC_PBMP_PORT_REMOVE(pbmp, port_id);
  40250                 } else {
  40251                     SOC_PBMP_PORT_ADD(pbmp, port_id);
  40252                 }
  40253                 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm,
  40254                         &efilter_entry, BITMAPf, &pbmp);
  40255                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  40256                             MEM_BLOCK_ALL, 0, &efilter_entry));
  40257             }
  40258             rv = BCM_E_NONE;
  40259         }
  40260         break;
  40261 #endif /* BCM_OLP_SUPPORT */
  40262 
  40263 #if defined(BCM_KATANA2_SUPPORT) || defined (BCM_APACHE_SUPPORT)
  40264     case bcmPortControlPortMacOui:
  40265     case bcmPortControlPortMacNonOui:
  40266 
  40267         /*
  40268          * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed
  40269          * by either of bcm_l2_station_xxx API or  bcm_switch_olp_l2_addr_xxx
  40270          *
  40271          * Use either of two set of APIs
  40272          */
  40273 
  40274         if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) {
  40275             LOG_VERBOSE(BSL_LS_BCM_L2,
  40276                         (BSL_META_U(unit,
  40277                                     "use bcm_l2_station_xxx API\n")));
  40278             return BCM_E_UNAVAIL;
  40279         }
  40280         _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API);
  40281 
  40282 #if defined(BCM_KATANA2_SUPPORT)
  40283         if (SOC_IS_KATANA2(unit) &&
  40284                  (soc_feature(unit, soc_feature_oam)  ||
  40285                   soc_feature(unit, soc_feature_sat))) {
  40286             uint32 val_lo, val_hi;
  40287             uint64 mac_field;
  40288 
  40289             PORT_LOCK(unit);
  40290 
  40291             rv = _bcm_kt2_port_mac_get(unit, port, &mac_field);
  40292 
  40293             if (BCM_FAILURE(rv)) {
  40294                 PORT_UNLOCK(unit);
  40295                 return (rv);
  40296             }
  40297 
  40298             COMPILER_64_TO_32_LO(val_lo, mac_field);
  40299             COMPILER_64_TO_32_HI(val_hi, mac_field);
  40300 
  40301             switch (type) {
  40302                 case bcmPortControlPortMacOui:
  40303                     val_lo = (val_lo & 0xffffff) | ((value & 0xff) << 24);
  40304                     val_hi = (value >> 8) & 0xffff;
  40305                     COMPILER_64_SET(mac_field, val_hi, val_lo);
  40306                     break;
  40307 
  40308                 case bcmPortControlPortMacNonOui:
  40309                     val_lo = (val_lo & 0xff000000) | (value & 0xffffff);
  40310                     COMPILER_64_SET(mac_field, val_hi, val_lo);
  40311                     break;
  40312 
  40313                 default:
  40314                      break;
  40315             }
  40316 
  40317             rv = _bcm_kt2_port_mac_set(unit, port, mac_field);
  40318             PORT_UNLOCK(unit);
  40319         }
  40320 #endif /* BCM_KATANA2_SUPPORT */
  40321 
  40322 #if defined(BCM_MONTEREY_SUPPORT)
  40323         if (SOC_IS_MONTEREY(unit)) {
  40324             PORT_LOCK(unit);
  40325             rv = _bcm_monterey_port_mac_set(unit,
  40326                                           port,
  40327                                           type == bcmPortControlPortMacOui,
  40328                                           value);
  40329             PORT_UNLOCK(unit);
  40330         }
  40331 #endif /* BCM_MONTEREY_SUPPORT */
  40332 #if defined(BCM_APACHE_SUPPORT)
  40333         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  40334             PORT_LOCK(unit);
  40335             rv = _bcm_apache_port_mac_set(unit,
  40336                                           port,
  40337                                           type == bcmPortControlPortMacOui,
  40338                                           value);
  40339             PORT_UNLOCK(unit);
  40340         }
  40341 #endif /* BCM_APACHE_SUPPORT */
  40342         break;
  40343 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT */
  40344 #ifdef BCM_TRX_SUPPORT
  40345     case bcmPortControlOamLoopback:
  40346         if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit)
  40347             && !SOC_IS_SHADOW(unit)) {
  40348             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40349 
  40350             if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr,
  40351                                     OAM_DO_NOT_MODIFYf)) {
  40352 
  40353                 rv = soc_reg_field32_modify(unit, ING_MISC_PORT_CONFIGr, port,
  40354                                             OAM_DO_NOT_MODIFYf, value ? 1 : 0);
  40355             } else {
  40356                 return BCM_E_UNAVAIL;
  40357             }
  40358         }
  40359 
  40360         break;
  40361 #endif /* BCM_TRX_SUPPORT */
  40362 
  40363     case bcmPortControlLanes:
  40364         if (soc_feature(unit, soc_feature_flexport_no_legacy)) {
  40365             return BCM_E_UNAVAIL;
  40366         }
  40367 #if defined(BCM_TRIUMPH2_SUPPORT)
  40368         if (soc_feature(unit, soc_feature_flex_port)) {
  40369             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40370 #ifdef BCM_TRIDENT_SUPPORT
  40371             if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  40372                 bcm_port_t phy_port;
  40373                 int bindex;
  40374 
  40375                 if (!SOC_PORT_VALID(unit, port)) {
  40376                     return BCM_E_PORT;
  40377                 }
  40378                 if (value != 1 && value != 2 && value != 4) {
  40379                     return BCM_E_PARAM;
  40380                 }
  40381                 /* coverity[overrun-local : FALSE] */
  40382                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  40383                 bindex = SOC_PORT_BINDEX(unit, phy_port);
  40384                 if (bindex & (value - 1)) { /* port alignment check */
  40385                     return BCM_E_PARAM;
  40386                 }
  40387             }
  40388 #endif /* BCM_TRIDENT_SUPPORT */
  40389             _bcm_esw_port_mirror_lock(unit);
  40390 
  40391 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  40392             if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) {
  40393                 rv = bcmi_xgs5_port_lanes_set(unit, port, value);
  40394             }
  40395 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  40396 #if defined(BCM_ENDURO_SUPPORT)
  40397             if (SOC_IS_ENDURO(unit)) {
  40398                 rv = _bcm_en_port_lanes_set(unit, port, value);
  40399             } else
  40400 #endif
  40401 #if defined(BCM_HURRICANE1_SUPPORT)
  40402             if (SOC_IS_HURRICANE(unit)) {
  40403                 rv = _bcm_hu_port_lanes_set(unit, port, value);
  40404             } else
  40405 #endif
  40406 #if defined(BCM_HURRICANE2_SUPPORT)
  40407             if (SOC_IS_HURRICANE2(unit)) {
  40408                 rv = _bcm_hu2_port_lanes_set(unit, port, value);
  40409             } else
  40410 #endif
  40411 #ifdef BCM_TOMAHAWK_SUPPORT
  40412             if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT3X(unit)) {
  40413                 /* coverity[overrun-call : FALSE] */
  40414                 rv = _bcm_th_port_lanes_set(unit, port, value);
  40415             } else
  40416 #endif
  40417 #if defined(BCM_MONTEREY_SUPPORT)
  40418             if (SOC_IS_MONTEREY(unit)) {
  40419                 rv = bcmi_monterey_port_lanes_set(unit, port, value);
  40420             } else
  40421 #endif
  40422 #if defined(BCM_APACHE_SUPPORT)
  40423             if (SOC_IS_APACHE(unit)) {
  40424                 rv = bcmi_apache_port_lanes_set(unit, port, value);
  40425             } else
  40426 #endif
  40427 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  40428             if (SOC_IS_TD2P_TT2P(unit)) {
  40429                 rv = bcmi_td2p_port_lanes_set(unit, port, value);
  40430             } else
  40431 #endif
  40432 #ifdef BCM_TRIDENT2_SUPPORT
  40433             if (SOC_IS_TD2_TT2(unit)) {
  40434                 rv = _bcm_td2_port_lanes_set(unit, port, value);
  40435                 _bcm_flex_port_phy_control_software_rx_los_get(unit, port);
  40436             } else
  40437 #endif
  40438 #ifdef BCM_TRIDENT_SUPPORT
  40439             if (SOC_IS_TD_TT(unit)) {
  40440                 /* coverity[overrun-call : FALSE] */
  40441                 rv = _bcm_td_port_lanes_set(unit, port, value);
  40442             } else
  40443 #endif /* BCM_TRIDENT_SUPPORT */
  40444 #ifdef BCM_SHADOW_SUPPORT
  40445             if (SOC_IS_SHADOW(unit)) {
  40446                 soc_info_t *si = NULL;
  40447                 int okay;
  40448                 int i;
  40449 
  40450                 rv = _bcm_shadow_port_lanes_set(unit, port, value);
  40451                 if (BCM_SUCCESS(rv)) {
  40452                     si = &SOC_INFO(unit);
  40453                     if (value == 1) { /* Probe other ports */
  40454                         for (i = port; i < port+4; i++) {
  40455                             rv = soc_phyctrl_detach(unit, i);
  40456                             if (SOC_FAILURE(rv)) {
  40457                                 _bcm_esw_port_mirror_unlock(unit);
  40458                                 return (rv);
  40459                             }
  40460                         }
  40461                         for (i = port; i < port+4; i++) {
  40462                             /* coverity[overrun-local : FALSE] */
  40463                             si->port_num_lanes[i] = value;
  40464                             rv = _bcm_port_probe(unit, i, &okay);
  40465                         }
  40466                     } else if (value == 4) { /* Probe other ports */
  40467                         si = &SOC_INFO(unit);
  40468                         for (i = port; i < port+4; i++) {
  40469                             rv = soc_phyctrl_detach(unit, i);
  40470                             if (SOC_FAILURE(rv)) {
  40471                                 _bcm_esw_port_mirror_unlock(unit);
  40472                                 return (rv);
  40473                             }
  40474                         }
  40475                         /* coverity[overrun-local : FALSE] */
  40476                         si->port_num_lanes[port] = value;
  40477                         rv = _bcm_port_probe(unit, port, &okay);
  40478                     }
  40479                 }
  40480             } else
  40481 #endif /* BCM_SHADOW_SUPPORT */
  40482 #ifdef BCM_TRIUMPH3_SUPPORT
  40483             if (SOC_IS_TRIUMPH3(unit)) {
  40484                 if (!SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 112 ||
  40485                     _tr3_port_config_id[unit] == 12)&&
  40486                     (port == 54 || port == 55)) {
  40487                     _bcm_esw_port_mirror_unlock(unit);
  40488                     return BCM_E_PARAM;
  40489                 }
  40490                 COUNTER_LOCK(unit);
  40491                 rv = _bcm_tr3_port_lanes_set(unit, port, value);
  40492                 COUNTER_UNLOCK(unit);
  40493             } else
  40494 #endif /* BCM_TRIUMPH3_SUPPORT */
  40495 #ifdef  BCM_METROLITE_SUPPORT
  40496              if (SOC_IS_METROLITE(unit)) {
  40497                  COUNTER_LOCK(unit);
  40498                  SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40499                  rv = _bcm_ml_port_lanes_set(unit, port, value);
  40500                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40501                  COUNTER_UNLOCK(unit);
  40502             } else
  40503 #endif /* BCM_METROLITE_SUPPORT */
  40504 #ifdef BCM_SABER2_SUPPORT
  40505             if (SOC_IS_SABER2(unit)) {
  40506                 COUNTER_LOCK(unit);
  40507                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40508                 rv = _bcm_sb2_port_lanes_set(unit, port, value);
  40509                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40510                 COUNTER_UNLOCK(unit);
  40511             } else
  40512 #endif /* BCM_SABER2_SUPPORT */
  40513 #ifdef BCM_KATANA2_SUPPORT
  40514             if (SOC_IS_KATANA2(unit)) {
  40515                 COUNTER_LOCK(unit);
  40516                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40517                 rv = _bcm_kt2_port_lanes_set(unit, port, value);
  40518                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40519                 COUNTER_UNLOCK(unit);
  40520             } else
  40521 #endif /* BCM_KATANA2_SUPPORT */
  40522             {
  40523                 rv = _bcm_tr2_port_lanes_set(unit, port, value);
  40524             }
  40525             _bcm_esw_port_mirror_unlock(unit);
  40526 #ifdef  BCM_METROLITE_SUPPORT
  40527             if (BCM_SUCCESS(rv) && SOC_IS_METROLITE(unit)) {
  40528                 COUNTER_LOCK(unit);
  40529                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40530                 rv = _bcm_ml_port_lanes_set_post_operation(unit, port);
  40531                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40532                 COUNTER_UNLOCK(unit);
  40533             } else
  40534 #endif /* BCM_METROLITE_SUPPORT */
  40535 #ifdef BCM_SABER2_SUPPORT
  40536             if (BCM_SUCCESS(rv) && SOC_IS_SABER2(unit)) {
  40537                 COUNTER_LOCK(unit);
  40538                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40539                 rv = _bcm_sb2_port_lanes_set_post_operation(unit, port);
  40540                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40541                 COUNTER_UNLOCK(unit);
  40542             } else
  40543 #endif
  40544 #ifdef BCM_KATANA2_SUPPORT
  40545             /* Dead Lock (with port lock) so calling separately */
  40546             if (BCM_SUCCESS(rv) && SOC_IS_KATANA2(unit)) {
  40547                 COUNTER_LOCK(unit);
  40548                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  40549                 rv = _bcm_kt2_port_lanes_set_post_operation(unit, port);
  40550                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  40551                 COUNTER_UNLOCK(unit);
  40552             }
  40553 #endif
  40554         }
  40555 #endif
  40556         break;
  40557 
  40558     case bcmPortControlPFCEthertype:
  40559 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40560         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40561             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40562             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40563                 /* IS_GX_PORT == IS_XL_PORT */
  40564                 return BCM_E_PORT;
  40565             }
  40566             if (value < 0 || value > 0xffff) {
  40567                 return BCM_E_PARAM;
  40568             }
  40569             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40570                                  SOC_MAC_CONTROL_PFC_TYPE, value);
  40571         }
  40572 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40573         break;
  40574 
  40575     case bcmPortControlPFCOpcode:
  40576 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40577         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40578             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40579             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40580                 /* IS_GX_PORT == IS_XL_PORT */
  40581                 return BCM_E_PORT;
  40582             }
  40583             if (value < 0 || value > 0xffff) {
  40584                 return BCM_E_PARAM;
  40585             }
  40586             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40587                                  SOC_MAC_CONTROL_PFC_OPCODE, value);
  40588         }
  40589 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40590         break;
  40591 
  40592     case bcmPortControlPFCReceive:
  40593 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40594         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40595         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40596             int pfc_enable;
  40597             int val_count = 0;
  40598             soc_reg_t reg;
  40599             uint32 values[2];
  40600             soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf};
  40601 
  40602             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40603                 /* IS_GX_PORT == IS_XL_PORT */
  40604                 return BCM_E_PORT;
  40605             }
  40606 
  40607             BCM_IF_ERROR_RETURN
  40608                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40609                                  SOC_MAC_CONTROL_PFC_RX_ENABLE, value));
  40610             if (value == 0) {
  40611                 BCM_IF_ERROR_RETURN
  40612                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  40613                                      SOC_MAC_CONTROL_PFC_TX_ENABLE,
  40614                                      &pfc_enable));
  40615             } else {
  40616                 pfc_enable = TRUE;
  40617             }
  40618 
  40619             if (SOC_IS_SC_CQ(unit)) {
  40620                 BCM_IF_ERROR_RETURN
  40621                     (soc_reg_field32_modify(unit, MMU_LLFC_RX_CONFIGr,
  40622                                             port, RX_ENABLEf, value ? 1 : 0));
  40623             }
  40624 
  40625             if (value == 0) {
  40626                 /* Disabling RX, flush MMU XOFF state */
  40627                 BCM_IF_ERROR_RETURN
  40628                     (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40629                                      SOC_MAC_CONTROL_PFC_FORCE_XON, 1));
  40630                 BCM_IF_ERROR_RETURN
  40631                     (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40632                                      SOC_MAC_CONTROL_PFC_FORCE_XON, 0));
  40633             }
  40634 
  40635             /* Port config settings */
  40636             values[0] = pfc_enable ? 1 : 0;
  40637             values[1] = 0;
  40638 
  40639             if (SOC_IS_TD2_TT2(unit)) {
  40640                 reg = INVALIDr;
  40641             } else if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) {
  40642                 reg = XLPORT_CONFIGr;
  40643                 val_count=2;
  40644             } else if (SOC_IS_TRIUMPH3(unit)) {
  40645                 reg = PORT_CONFIGr;
  40646                 val_count=2;
  40647             } else if (SOC_IS_SABER2(unit)) {
  40648                 /* No port level config required */
  40649                 reg = INVALIDr;
  40650                 val_count = 0;
  40651             } else if (SOC_IS_KATANAX(unit)) {
  40652                 reg = XPORT_CONFIGr;
  40653                 val_count=2;
  40654             } else {
  40655                 reg = INVALIDr;
  40656             }
  40657 
  40658             if (val_count > 0) {
  40659                 BCM_IF_ERROR_RETURN
  40660                     (soc_reg_fields32_modify(unit, reg, port,
  40661                                              COUNTOF(values), fields, values));
  40662             } else if (SOC_IS_TD2_TT2(unit)) {
  40663                 ;
  40664             } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) {
  40665                 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) {
  40666                     /* Feature enable */
  40667                     BCM_IF_ERROR_RETURN
  40668                         (soc_reg_field32_modify(unit, PPFC_ENr, port,
  40669                                                 PPFC_FEATURE_ENf,
  40670                                                 pfc_enable ? 1 : 0));
  40671                 }
  40672                 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) {
  40673                     BCM_IF_ERROR_RETURN
  40674                         (soc_reg_field32_modify(unit, XPORT_CONFIGr,
  40675                                                 port, PPP_ENABLEf,
  40676                                                 pfc_enable ? 1 : 0));
  40677                 }
  40678             }
  40679 
  40680             /* Stats enable */
  40681             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40682                                  SOC_MAC_CONTROL_PFC_STATS_ENABLE,
  40683                                  pfc_enable ? 1 : 0);
  40684 
  40685             if (SOC_REG_IS_VALID(unit, XPORT_TO_MMU_BKPr) && pfc_enable == 0) {
  40686                 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0));
  40687             }
  40688         }
  40689 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40690         break;
  40691 
  40692     case bcmPortControlPFCTransmit:
  40693 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40694         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40695             rv = _bcm_sc_tr_port_pfc_tx_set(unit, port, (value)? 0xffff : 0);
  40696         }
  40697 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40698         break;
  40699 
  40700     case bcmPortControlPFCClasses:
  40701 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40702         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40703             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40704             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40705                 /* IS_GX_PORT == IS_XL_PORT */
  40706                 return BCM_E_PORT;
  40707             }
  40708             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40709                                  SOC_MAC_CONTROL_PFC_CLASSES, value);
  40710         }
  40711 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40712         break;
  40713 
  40714     case bcmPortControlPFCPassFrames:
  40715 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40716         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40717             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40718             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40719                 /* IS_GX_PORT == IS_XL_PORT */
  40720                 return BCM_E_PORT;
  40721             }
  40722             if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) {
  40723                 uint32 rval32 = 0;
  40724                 soc_reg_t reg = INVALIDr;
  40725                 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  40726                     reg = PGW_MAC_RSV_MASKr;
  40727                 } else if(IS_CL_PORT(unit, port) &&
  40728                           SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  40729                     reg = CLPORT_MAC_RSV_MASKr;
  40730                 } else if(IS_XL_PORT(unit, port) &&
  40731                           SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  40732                     reg = XLPORT_MAC_RSV_MASKr;
  40733                 } else {
  40734                     reg = INVALIDr;
  40735                 }
  40736 
  40737                 if (reg != INVALIDr) {
  40738                     PORT_LOCK(unit);
  40739                     rv = soc_reg32_get(unit, reg, port, 0, &rval32);
  40740                     if (BCM_SUCCESS(rv)) {
  40741                         /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected
  40742                          * Enable  PFC Frame : Set 0. Go through
  40743                          * Disable PFC Frame : Set 1. Purged.
  40744                          */
  40745                         if(value) {
  40746                             rval32 &= ~(1 << 18);
  40747                         } else {
  40748                             rval32 |= (1 << 18);
  40749                         }
  40750                         rv = soc_reg32_set(unit, reg, port, 0, rval32);
  40751                     }
  40752                     PORT_UNLOCK(unit);
  40753                 } else {
  40754                     rv = BCM_E_UNAVAIL;
  40755                 }
  40756             } else {
  40757                 PORT_LOCK(unit);
  40758                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40759                                      SOC_MAC_CONTROL_PFC_RX_PASS, value);
  40760                 PORT_UNLOCK(unit);
  40761             }
  40762         }
  40763 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40764         break;
  40765 
  40766     case bcmPortControlPFCDestMacOui:
  40767 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40768         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40769             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40770             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40771                 /* IS_GX_PORT == IS_XL_PORT */
  40772                 return BCM_E_PORT;
  40773             }
  40774             if (value < 0 || value > 0xffffff) {
  40775                 return BCM_E_PARAM;
  40776             }
  40777             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40778                                  SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value);
  40779         }
  40780 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40781         break;
  40782 
  40783     case bcmPortControlPFCDestMacNonOui:
  40784 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  40785         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40786             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40787             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  40788                 /* IS_GX_PORT == IS_XL_PORT */
  40789                 return BCM_E_PORT;
  40790             }
  40791             if (value < 0 || value > 0xffffff) {
  40792                 return BCM_E_PARAM;
  40793             }
  40794             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40795                                  SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value);
  40796         }
  40797 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  40798         break;
  40799 
  40800     case bcmPortControlPFCRefreshTime:
  40801 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  40802         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40803             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40804             if (value < 0 || value > 0xffff) {
  40805                 return BCM_E_PARAM;
  40806             }
  40807             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40808                                  SOC_MAC_CONTROL_PFC_REFRESH_TIME, value);
  40809         }
  40810 #endif /* BCM_TRIDENT_SUPPORT */
  40811         break;
  40812 
  40813     case bcmPortControlPFCXOffTime:
  40814 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  40815         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  40816             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  40817             if (value < 0 || value > 0xffff) {
  40818                 return BCM_E_PARAM;
  40819             }
  40820             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40821                                  SOC_MAC_CONTROL_PFC_XOFF_TIME, value);
  40822         }
  40823 #endif /* BCM_TRIDENT_SUPPORT */
  40824         break;
  40825 
  40826     case bcmPortControlVrf:
  40827         rv = _bcm_esw_port_vrf_set(unit, port, value);
  40828         break;
  40829 
  40830     case bcmPortControlL3Ingress:
  40831 #if defined(BCM_TRIUMPH_SUPPORT)
  40832         if (!soc_feature(unit, soc_feature_l3_ingress_interface)) {
  40833             return BCM_E_UNAVAIL;
  40834         }
  40835 
  40836         if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) {
  40837             if ((value >= 1) && (value < soc_mem_index_count(unit, L3_IIFm))) {
  40838 #if defined(BCM_KATANA2_SUPPORT)
  40839                 if (SOC_IS_KATANA2(unit)) {
  40840                     rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, value);
  40841                 } else
  40842 #endif
  40843                 {
  40844                     rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, value);
  40845                 }
  40846                 BCM_IF_ERROR_RETURN(rv);
  40847                 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  40848                     SOC_IS_TRIDENT3X(unit)) {
  40849                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  40850                                                PORT_OPERATIONf, 0x2);
  40851                 }
  40852             } else {
  40853 #if defined(BCM_KATANA2_SUPPORT)
  40854                 if (SOC_IS_KATANA2(unit)) {
  40855                     rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, 0);
  40856                 } else
  40857 #endif
  40858                 {
  40859                     rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, 0);
  40860                 }
  40861                 BCM_IF_ERROR_RETURN(rv);
  40862                 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) {
  40863                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  40864                                                PORT_OPERATIONf, 0x0);
  40865                 }
  40866             }
  40867         }
  40868 #endif  /* BCM_TRIUMPH_SUPPORT */
  40869         break;
  40870 
  40871     case bcmPortControlL2Learn:
  40872 #if defined(BCM_TRX_SUPPORT)
  40873         if (SOC_IS_TRX(unit)) {
  40874             uint32 hw_val = 0;
  40875             bcm_port_cfg_t port_cfg;
  40876 
  40877             BCM_IF_ERROR_RETURN(
  40878                 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val));
  40879             BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg));
  40880             port_cfg.pc_cml = hw_val;
  40881             rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg);
  40882         }
  40883 #endif /* BCM_TRX_SUPPORT */
  40884           break;
  40885 
  40886     case bcmPortControlL2Move:
  40887 #if defined(BCM_TRX_SUPPORT)
  40888         if (SOC_IS_TRX(unit)) {
  40889             uint32 hw_val = 0;
  40890             bcm_port_cfg_t port_cfg;
  40891 
  40892             BCM_IF_ERROR_RETURN(
  40893                 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val));
  40894             BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg));
  40895             port_cfg.pc_cml_move = hw_val;
  40896             rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg);
  40897         }
  40898 #endif /* BCM_TRX_SUPPORT */
  40899           break;
  40900 
  40901     case bcmPortControlForwardStaticL2MovePkt:
  40902 #if defined(BCM_TRX_SUPPORT)
  40903         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  40904                                    DISABLE_STATIC_MOVE_DROPf, value ? 1 : 0);
  40905 #endif /* BCM_TRX_SUPPORT */
  40906         break;
  40907 
  40908     case bcmPortControlPrbsMode:
  40909         if (value != 0) {
  40910             return BCM_E_PARAM;
  40911         }
  40912         rv = BCM_E_NONE;
  40913         break;
  40914 
  40915     case bcmPortControlPrbsPolynomial:
  40916         /*prbs polynomial value check*/
  40917         if((value < BCM_PORT_PRBS_POLYNOMIAL_X7_X6_1)
  40918             || (value > BCM_PORT_PRBS_POLYNOMIAL_PAM4_13Q))
  40919         {
  40920             return BCM_E_PARAM;
  40921         }
  40922         PORT_LOCK(unit);
  40923         rv = soc_phyctrl_control_set(unit, port,
  40924                                      SOC_PHY_CONTROL_PRBS_POLYNOMIAL, value);
  40925         PORT_UNLOCK(unit);
  40926         break;
  40927     case bcmPortControlPrbsTxEnable:
  40928         PORT_LOCK(unit);
  40929         rv = soc_phyctrl_control_set(unit, port,
  40930                                      SOC_PHY_CONTROL_PRBS_TX_ENABLE, value);
  40931         PORT_UNLOCK(unit);
  40932         break;
  40933 
  40934     case bcmPortControlPrbsRxEnable:
  40935         PORT_LOCK(unit);
  40936         rv = soc_phyctrl_control_set(unit, port,
  40937                                      SOC_PHY_CONTROL_PRBS_RX_ENABLE, value);
  40938         PORT_UNLOCK(unit);
  40939         break;
  40940 
  40941     case bcmPortControlPrbsTxInvertData:
  40942         PORT_LOCK(unit);
  40943         rv = soc_phyctrl_control_set(unit, port,
  40944                                      SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA,
  40945                                      value);
  40946         PORT_UNLOCK(unit);
  40947         break;
  40948 
  40949     case bcmPortControlLinkFaultLocalEnable:
  40950         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40951                              SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value);
  40952         break;
  40953     case bcmPortControlLinkFaultRemoteEnable:
  40954         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40955                              SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value);
  40956         break;
  40957     case bcmPortControlSerdesDriverTune:
  40958         PORT_LOCK(unit);
  40959         rv = soc_phyctrl_control_set(unit, port,
  40960                 SOC_PHY_CONTROL_SERDES_DRIVER_TUNE, value);
  40961         PORT_UNLOCK(unit);
  40962         break;
  40963     case bcmPortControlLinkdownTransmit:
  40964         PORT_LOCK(unit);
  40965         rv = soc_phyctrl_control_set(unit, port,
  40966                 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, value);
  40967         PORT_UNLOCK(unit);
  40968         /* Most of PHYs have nothing to configure and simply return UNAVAIL*/
  40969         if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) {
  40970             BCM_IF_ERROR_RETURN(_bcm_esw_link_down_tx_set(unit, port, value));
  40971 #ifdef BCM_HURRICANE4_SUPPORT
  40972             if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  40973                 return rv;
  40974             }
  40975 #endif
  40976 #if defined(BCM_TRIUMPH3_SUPPORT)
  40977             if (SOC_REG_PORT_VALID(unit, XMAC_RX_LSS_CTRLr, port)) {
  40978                 rv = soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr,
  40979                          port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0));
  40980             } else if (SOC_REG_PORT_VALID(unit, XLMAC_RX_LSS_CTRLr, port)) {
  40981                 rv = soc_reg_field32_modify(unit, XLMAC_RX_LSS_CTRLr,
  40982                          port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0));
  40983             }
  40984 #endif
  40985         }
  40986         break;
  40987     case bcmPortControlSerdesTuneMarginMode:
  40988         PORT_LOCK(unit);
  40989         rv = soc_phyctrl_control_set(unit, port,
  40990                 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, value);
  40991         PORT_UNLOCK(unit);
  40992         break;
  40993     case bcmPortControlSerdesTuneMarginValue:
  40994         PORT_LOCK(unit);
  40995         rv = soc_phyctrl_control_set(unit, port,
  40996                 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, value);
  40997         PORT_UNLOCK(unit);
  40998         break;
  40999     case bcmPortControlStatOversize:
  41000         rv = _bcm_esw_stat_ovr_threshold_set(unit, port, value);
  41001         break;
  41002 
  41003     case bcmPortControlStatOversizeIsError:
  41004         rv = _bcm_esw_stat_ovr_error_control_set(unit, port, value);
  41005         break;
  41006 
  41007     case bcmPortControlTimestampEnable:
  41008 #if defined(BCM_HAWKEYE_SUPPORT)
  41009         if (SOC_IS_HAWKEYE(unit)) {
  41010             uint32 rval;
  41011             if (!SOC_PORT_VALID(unit, port)) {
  41012                 return BCM_E_PORT;
  41013             }
  41014             SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval));
  41015             if (value) {
  41016                 /* coverity[BAD_SHIFT: FALSE] */
  41017                 rval |= (port >= 32 ? 0 : (1 << port));
  41018             } else {
  41019                 /* coverity[BAD_SHIFT: FALSE] */
  41020                 rval &= ~(port >= 32 ? 0 : (1 << port));
  41021             }
  41022             SOC_IF_ERROR_RETURN(WRITE_EAV_ENABLE_BMAPr(unit, rval));
  41023 
  41024             /* Enable MMU */
  41025             SOC_IF_ERROR_RETURN(WRITE_MMUEAVENABLEr(unit, rval));
  41026 
  41027             /* Program EGR_PORT register */
  41028             SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval));
  41029             soc_reg_field_set(unit, EGR_PORTr, &rval, EAV_CAPABLEf, value);
  41030             SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval));
  41031 
  41032             rv = BCM_E_NONE;
  41033         } else
  41034 #endif /* BCM_HAWKEYE_SUPPORT */
  41035         if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  41036             if (IS_XL_PORT(unit, port)) {
  41037                 /* Enable/disable timesatmp on XLMAC */
  41038                 uint32 rval;
  41039                 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit,
  41040                                                              port, &rval));
  41041                 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval,
  41042                                   XLMAC_TS_DISABLEf, (value) ? 0 : 1);
  41043                 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit,
  41044                                                               port, rval));
  41045                 rv = BCM_E_NONE;
  41046             }
  41047         }
  41048         break;
  41049 
  41050     case bcmPortControlEEEEnable:
  41051         if (!SOC_PORT_VALID(unit, port)) {
  41052             return BCM_E_PORT;
  41053         }
  41054 
  41055         PORT_LOCK(unit);
  41056 
  41057 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  41058         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  41059         || defined(BCM_HURRICANE2_SUPPORT)
  41060         if (soc_feature (unit, soc_feature_eee)) {
  41061             int mac_val;
  41062             uint32 phy_val;
  41063 
  41064             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  41065                                  SOC_MAC_CONTROL_EEE_ENABLE,
  41066                                  &mac_val) != SOC_E_UNAVAIL) &&
  41067                 (soc_phyctrl_control_get(unit, port,
  41068                                          BCM_PORT_PHY_CONTROL_EEE,
  41069                                          &phy_val) != SOC_E_UNAVAIL)) {
  41070 
  41071                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  41072                  * and PHY also supports Native EEE mode
  41073                  */
  41074 
  41075                 /* a. Disable AutoGrEEEn mode by PHY if applicable */
  41076                 rv = (soc_phyctrl_control_get(unit, port,
  41077                                               BCM_PORT_PHY_CONTROL_EEE_AUTO,
  41078                                               &phy_val));
  41079 
  41080                 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  41081                     rv = soc_phyctrl_control_set(unit, port,
  41082                                                  BCM_PORT_PHY_CONTROL_EEE_AUTO,
  41083                                                  0);
  41084                 }
  41085 
  41086                 /* b. Enable/Disable Native EEE in PHY */
  41087                 rv = soc_phyctrl_control_set (unit, port,
  41088                         BCM_PORT_PHY_CONTROL_EEE, value ? 1 : 0);
  41089 
  41090                 if (SOC_SUCCESS(rv)) {
  41091                     /* EEE standard compliance Work Around:
  41092                      * Store the software copy of eee value in eee_cfg flag
  41093                      */
  41094                     eee_cfg[unit][port] = value;
  41095                     /* If (value==1), EEE will be enabled in MAC after 1 sec.
  41096                      * during linkscan update*/
  41097                     if (value == 0) {
  41098                         /* Disable EEE in MAC immediately*/
  41099                         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac,
  41100                                              unit, port,
  41101                                              SOC_MAC_CONTROL_EEE_ENABLE, 0);
  41102                     }
  41103 
  41104                     /* Notify Int-PHY to bypass LPI for native EEE mode.
  41105                      *
  41106                      * Note :
  41107                      *  1. Not all internal SerDes support the setting to
  41108                      *     enable/disable bypass LPI signal.
  41109                      *  2. Int-PHY to bypass LPI will sync with Ext-PHY's EEE
  41110                      *     enabling status for Native EEE mode.
  41111                      */
  41112                     (void)soc_phyctrl_notify(unit, port,
  41113                                             phyEventLpiBypass, value? 1: 0);
  41114                 }
  41115 
  41116             } else {
  41117                 /* If native EEE mode is not supported,
  41118                  * set PHY in AutoGrEEEn mode.
  41119                  */
  41120 
  41121                 /* a. Disable Native EEE mode in PHY if applicable */
  41122                 rv = (soc_phyctrl_control_get(unit, port,
  41123                                               BCM_PORT_PHY_CONTROL_EEE,
  41124                                               &phy_val));
  41125 
  41126                 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  41127                     rv = soc_phyctrl_control_set (unit, port,
  41128                                                   BCM_PORT_PHY_CONTROL_EEE,
  41129                                                   0);
  41130                 }
  41131 
  41132                 /* b. Enable/Disable AutoGrEEEn in PHY.
  41133                  * If PHY does not support AutoGrEEEn mode,
  41134                  * rv will be assigned SOC_E_UNAVAIL.
  41135                  */
  41136                 rv = soc_phyctrl_control_set (unit, port,
  41137                                               BCM_PORT_PHY_CONTROL_EEE_AUTO,
  41138                                               value ? 1 : 0);
  41139                 if (SOC_SUCCESS(rv)) {
  41140                     eee_cfg[unit][port] = value;
  41141                 }
  41142             }
  41143         } else
  41144 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  41145           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  41146 
  41147         {
  41148             /* For legacy devices that don't support native EEE,
  41149              * set PHY in AutoGrEEEn mode.
  41150              */
  41151             uint32 phy_val;
  41152 
  41153             /* a. Disable Native EEE mode in PHY if applicable */
  41154             rv = (soc_phyctrl_control_get(unit, port,
  41155                                           BCM_PORT_PHY_CONTROL_EEE,
  41156                                           &phy_val));
  41157 
  41158             if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  41159                 rv = soc_phyctrl_control_set (unit, port,
  41160                                               BCM_PORT_PHY_CONTROL_EEE, 0);
  41161             }
  41162 
  41163             /* b. Enable/Disable AutoGrEEEn in PHY.
  41164              * If PHY does not support AutoGrEEEn mode,
  41165              * rv will be assigned BCM_E_UNAVAIL.
  41166              */
  41167             rv = soc_phyctrl_control_set (unit, port,
  41168                                           BCM_PORT_PHY_CONTROL_EEE_AUTO,
  41169                                           value ? 1 : 0);
  41170         }
  41171 
  41172         PORT_UNLOCK(unit);
  41173 
  41174         break;
  41175 
  41176     case bcmPortControlEEEStatisticsClear:
  41177         if (!SOC_PORT_VALID(unit, port)) {
  41178             return BCM_E_PORT;
  41179         }
  41180         if (!IS_E_PORT(unit, port)) {
  41181             return BCM_E_UNAVAIL;
  41182         }
  41183 
  41184         PORT_LOCK(unit);
  41185 
  41186 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  41187     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  41188         if (soc_feature(unit, soc_feature_eee)) {
  41189             uint32 val = 0;
  41190             uint64 val64;
  41191             int mac_val;
  41192             uint32 phy_val;
  41193 
  41194             COMPILER_64_ZERO(val64);
  41195             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  41196                                  SOC_MAC_CONTROL_EEE_ENABLE, &mac_val)
  41197                  != SOC_E_UNAVAIL) &&
  41198                 (soc_phyctrl_control_get(unit, port,
  41199                                          BCM_PORT_PHY_CONTROL_EEE, &phy_val)
  41200                  != SOC_E_UNAVAIL)) {
  41201 
  41202                 if (soc_feature(unit, soc_feature_eee_stat_clear_directly) ||
  41203                     SOC_IS_TD2_TT2(unit)) {
  41204                     rv = _bcm_esw_port_eee_stat_clear(unit, port);
  41205 
  41206                     PORT_UNLOCK (unit);
  41207                     break;
  41208                 }
  41209 
  41210                 /* MAC/Switch is EEE aware (Native EEE mode is supported) */
  41211                 if (soc_feature(unit, soc_feature_unified_port)) {
  41212                     if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) {
  41213                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41214                             (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val));
  41215                         soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val,
  41216                                           CNT_MODEf, 0);
  41217                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41218                             (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val));
  41219                     }
  41220                 } else {
  41221                     if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) {
  41222                         /*set counter rollover bit to 0*/
  41223                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  41224                             READ_GE0_EEE_CONFIGr(unit, port, &val));
  41225                         soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val,
  41226                             COUNTER_ROLLOVERf, 0);
  41227                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41228                                 (WRITE_GE0_EEE_CONFIGr(unit, port, val));
  41229                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41230                                 (WRITE_GE1_EEE_CONFIGr(unit, port, val));
  41231                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41232                                 (WRITE_GE2_EEE_CONFIGr(unit, port, val));
  41233                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41234                                 (WRITE_GE3_EEE_CONFIGr(unit, port, val));
  41235                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41236                                 (WRITE_GE4_EEE_CONFIGr(unit, port, val));
  41237                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41238                                 (WRITE_GE5_EEE_CONFIGr(unit, port, val));
  41239                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41240                                 (WRITE_GE6_EEE_CONFIGr(unit, port, val));
  41241                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41242                                 (WRITE_GE7_EEE_CONFIGr(unit, port, val));
  41243                     }
  41244                 }
  41245 
  41246                 /*Read counters to clear them*/
  41247                 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port) &&
  41248                     (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) ||
  41249                      SOC_IS_GREYHOUND(unit))) {
  41250                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41251                         (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  41252                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41253                         (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  41254                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41255                         (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  41256                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41257                         (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  41258 #ifdef BCM_GREYHOUND2_SUPPORT
  41259                 } else if (SOC_IS_GREYHOUND2(unit)) {
  41260 
  41261                     if (IS_CL_PORT(unit, port)) {
  41262                         /* for port with CLMAC */
  41263                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41264                             (READ_CLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41265                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41266                             (READ_CLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41267                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41268                             (READ_CLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41269                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41270                             (READ_CLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41271                     } else if (IS_XL_PORT(unit, port)) {
  41272                         /* for port with XLMAC */
  41273                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41274                             (READ_XLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41275                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41276                             (READ_XLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41277                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41278                             (READ_XLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41279                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41280                             (READ_XLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41281 
  41282                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41283                             (READ_XLPMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41284                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41285                             (READ_XLPMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41286                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41287                             (READ_XLPMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41288                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41289                             (READ_XLPMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41290                     } else {
  41291                         /* for port with UniMAC */
  41292                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41293                             (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  41294                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41295                             (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  41296                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41297                             (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  41298                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41299                             (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  41300                     }
  41301 #endif
  41302                 } else {
  41303                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41304                         (READ_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41305                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41306                         (READ_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41307                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41308                         (READ_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  41309                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41310                         (READ_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  41311                 }
  41312 
  41313                 /*set counter rollover bit to 1*/
  41314                 if (soc_feature(unit, soc_feature_unified_port)) {
  41315                     if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) {
  41316                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41317                             (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val));
  41318                         soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val,
  41319                                           CNT_MODEf, 1);
  41320                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41321                             (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val));
  41322                     }
  41323                 } else {
  41324                     if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) {
  41325                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  41326                             READ_GE0_EEE_CONFIGr(unit, port, &val));
  41327                         soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val,
  41328                             COUNTER_ROLLOVERf, 1);
  41329                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41330                                 (WRITE_GE0_EEE_CONFIGr(unit, port, val));
  41331                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41332                                 (WRITE_GE1_EEE_CONFIGr(unit, port, val));
  41333                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41334                                 (WRITE_GE2_EEE_CONFIGr(unit, port, val));
  41335                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41336                                 (WRITE_GE3_EEE_CONFIGr(unit, port, val));
  41337                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41338                                 (WRITE_GE4_EEE_CONFIGr(unit, port, val));
  41339                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41340                                 (WRITE_GE5_EEE_CONFIGr(unit, port, val));
  41341                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41342                                 (WRITE_GE6_EEE_CONFIGr(unit, port, val));
  41343                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  41344                                 (WRITE_GE7_EEE_CONFIGr(unit, port, val));
  41345                     }
  41346                 }
  41347                 rv = BCM_E_NONE;
  41348             } else {
  41349                 /* native EEE mode is not supported, */
  41350                 rv = soc_phyctrl_control_set
  41351                     (unit, port,
  41352                      BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value);
  41353             }
  41354         } else
  41355 #endif /* BCM_HURRICANE_SUPPORT || BCM_TRIDENT_SUPPORT
  41356           || BCM_HAWKEYE_SUPPORT*/
  41357         {
  41358             /* On legacy devices that don't support native EEE,
  41359              * get counter value from PHY. If PHY does not support
  41360              * EEE counters, rv will be assigned BCM_E_UNAVAIL.
  41361              */
  41362             rv = soc_phyctrl_control_set
  41363                 (unit, port,
  41364                  BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value);
  41365         }
  41366         PORT_UNLOCK (unit);
  41367         break;
  41368 
  41369 
  41370  /**********************      EEE Mode Overview    ************************
  41371  *                      |DET|                              |  WT |
  41372  *   Signalling   |idles|   |------------------------------|     | idles   |
  41373  *   from Tx MAC  | or  |   |   Low Power Idle (LPI)       |idles|  or     |
  41374  *   to local PHY |data |   |------------------------------|     | data    |
  41375  *                          *                              *
  41376  *                          *                              *
  41377  *                          *  -------LPI state------------*
  41378  *   Local PHY    |         |  |      |  |       |  |      |   |           |
  41379  *   signaling    |   Active|Ts|  Tq  |Tr|  Tq   |Tr|  Tq  |Tw |Active     |
  41380  *   on MDI       |         |  |      |  |       |  |      |   |           |
  41381  *                          *------------------------------*
  41382  *                          *                              *
  41383  *                          *                               *
  41384  *   Signaling    |   idles |-------------------------------|id| PHY is    |
  41385  *   from LP PHY  |     or  |  Low Power Idle (LPI)         |le| ready     |
  41386  *   to Rx MAC    |   data  |-------------------------------|s | for data  |
  41387  *
  41388  *   where DET = Delay Entry Timer    WT = Tx MAC Wake Timer
  41389  */
  41390     case bcmPortControlEEETransmitIdleTime:
  41391         /* DET = Time (in microsecs) for which condition to move to LPI state
  41392          * is satisfied, at the end of which MAC TX transitions to LPI state */
  41393         if (!SOC_PORT_VALID(unit, port)) {
  41394             return BCM_E_PORT;
  41395         }
  41396 
  41397         PORT_LOCK(unit);
  41398 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT)     \
  41399     || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)     \
  41400     || defined (BCM_HURRICANE2_SUPPORT)
  41401         if (soc_feature (unit, soc_feature_eee)) {
  41402             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  41403                                  SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value);
  41404         } else
  41405 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  41406           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  41407         {
  41408             rv = BCM_E_UNAVAIL;
  41409         }
  41410         PORT_UNLOCK(unit);
  41411         break;
  41412 
  41413     case bcmPortControlEEETransmitRefreshTime:
  41414         if (!SOC_PORT_VALID(unit, port)) {
  41415             return BCM_E_PORT;
  41416         }
  41417 
  41418         PORT_LOCK(unit);
  41419         rv = soc_phyctrl_control_set(unit, port,
  41420                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, value);
  41421         PORT_UNLOCK (unit);
  41422         break;
  41423 
  41424     case bcmPortControlEEETransmitSleepTime:
  41425         if (!SOC_PORT_VALID(unit, port)) {
  41426             return BCM_E_PORT;
  41427         }
  41428         PORT_LOCK (unit);
  41429         rv = soc_phyctrl_control_set(unit, port,
  41430                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, value);
  41431         PORT_UNLOCK (unit);
  41432         break;
  41433 
  41434     case bcmPortControlEEETransmitQuietTime:
  41435         if (!SOC_PORT_VALID(unit, port)) {
  41436             return BCM_E_PORT;
  41437         }
  41438         PORT_LOCK(unit);
  41439         rv = soc_phyctrl_control_set(unit, port,
  41440                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, value);
  41441         PORT_UNLOCK (unit);
  41442         break;
  41443 
  41444     case bcmPortControlEEETransmitWakeTime:
  41445         /* Time(in microsecs) to wait before transmitter can leave LPI State*/
  41446         if (!SOC_PORT_VALID(unit, port)) {
  41447             return BCM_E_PORT;
  41448         }
  41449 
  41450         PORT_LOCK (unit);
  41451 
  41452 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  41453         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  41454         || defined(BCM_HURRICANE2_SUPPORT)
  41455             if (soc_feature (unit, soc_feature_eee)) {
  41456                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  41457                         SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value);
  41458             }
  41459 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || BCM_TRIDENT_SUPPORT ||
  41460          BCM_SHADOW_SUPPORT */
  41461 
  41462         PORT_UNLOCK (unit);
  41463         break;
  41464 
  41465      case bcmPortControlEEEReceiveSleepTime:
  41466         if (!SOC_PORT_VALID(unit, port)) {
  41467             return BCM_E_PORT;
  41468         }
  41469         PORT_LOCK (unit);
  41470         rv = soc_phyctrl_control_set(unit, port,
  41471                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, value);
  41472         PORT_UNLOCK (unit);
  41473         break;
  41474 
  41475     case bcmPortControlEEEReceiveQuietTime:
  41476         if (!SOC_PORT_VALID(unit, port)) {
  41477             return BCM_E_PORT;
  41478         }
  41479         PORT_LOCK(unit);
  41480         rv = soc_phyctrl_control_set(unit, port,
  41481                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, value);
  41482         PORT_UNLOCK(unit);
  41483         break;
  41484 
  41485     case bcmPortControlEEEReceiveWakeTime:
  41486         if (!SOC_PORT_VALID(unit, port)) {
  41487             return BCM_E_PORT;
  41488         }
  41489         if (!IS_E_PORT(unit, port)) {
  41490             return BCM_E_UNAVAIL;
  41491         }
  41492         PORT_LOCK(unit);
  41493 
  41494         rv = soc_phyctrl_control_set (unit, port,
  41495                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, value);
  41496         PORT_UNLOCK(unit);
  41497         break;
  41498 
  41499     case bcmPortControlEEEEventCountSymmetric:
  41500         if (!SOC_PORT_VALID(unit, port)) {
  41501             return BCM_E_PORT;
  41502         }
  41503         if (!IS_E_PORT(unit, port)) {
  41504             return BCM_E_UNAVAIL;
  41505         }
  41506 #if defined(BCM_HURRICANE2_SUPPORT)
  41507         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  41508             SOC_IS_GREYHOUND2(unit)) {
  41509             soc_reg_t   reg;
  41510 
  41511             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  41512                 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr :
  41513                                                CLPORT_EEE_COUNTER_MODEr;
  41514 
  41515                 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) {
  41516                     rv = soc_reg_field32_modify(unit, reg, port,
  41517                                                 MODE_BITf, (value) ? 1 : 0);
  41518                 } else {
  41519                     return BCM_E_INTERNAL;
  41520                 }
  41521             } else {
  41522                 return BCM_E_PORT;
  41523             }
  41524         } else
  41525 #endif
  41526         {
  41527 #if defined(BCM_TRIUMPH3_SUPPORT)
  41528             if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) {
  41529                 rv = soc_reg_field32_modify(unit, PORT_EEE_COUNTER_MODEr, port,
  41530                                             MODE_BITf, (value) ? 1 : 0);
  41531             }
  41532 #endif
  41533         }
  41534         break;
  41535 
  41536     case bcmPortControlEEELinkActiveDuration:
  41537         if (!SOC_PORT_VALID(unit, port)) {
  41538             return BCM_E_PORT;
  41539         }
  41540         if (!IS_E_PORT(unit, port)) {
  41541             return BCM_E_UNAVAIL;
  41542         }
  41543 #if defined(BCM_HURRICANE2_SUPPORT)
  41544         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  41545             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  41546             soc_reg_t   reg;
  41547 
  41548             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  41549                 reg = IS_XL_PORT(unit, port) ? XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  41550                                                CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  41551                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  41552                     if (value >= (1 << soc_reg_field_length(unit,
  41553                                                             reg,
  41554                                                             ONE_SECOND_TIMERf))) {
  41555                         return BCM_E_PARAM;
  41556                     }
  41557                     rv = soc_reg_field32_modify(unit,
  41558                                                 reg,
  41559                                                 port,
  41560                                                 ONE_SECOND_TIMERf,
  41561                                                 value);
  41562                 }
  41563             } else {
  41564                 return BCM_E_PORT;
  41565             }
  41566         } else
  41567 #endif
  41568         {
  41569 #if defined(BCM_TRIUMPH3_SUPPORT)
  41570             {
  41571                 soc_reg_t reg;
  41572 
  41573                 reg = IS_C_PORT(unit, port) ?
  41574                     CMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  41575                     XMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  41576                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  41577                     if (value >= (1 << soc_reg_field_length(unit, reg,
  41578                                                      ONE_SECOND_TIMERf))) {
  41579                         return BCM_E_PARAM;
  41580                     }
  41581                     rv = soc_reg_field32_modify(unit, reg, port,
  41582                                                 ONE_SECOND_TIMERf, value);
  41583                 }
  41584             }
  41585 #endif
  41586         }
  41587         break;
  41588 
  41589     case bcmPortControlRemoteCpuEnable:
  41590         if (soc_feature(unit, soc_feature_rcpu_1)) {
  41591             bcm_pbmp_t   pbmp;
  41592             uint32       rval;
  41593 
  41594             rval = 0;
  41595             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) {
  41596                 READ_CMIC_PKT_PORTSr(unit, &rval);
  41597                 SOC_PBMP_WORD_SET(pbmp, 0, rval);
  41598             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) {
  41599                 READ_CMIC_PKT_PORTS_0r(unit, &rval);
  41600                 SOC_PBMP_WORD_SET(pbmp, 0, rval);
  41601             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_0r)) {
  41602                 READ_CMIC_RPE_PKT_PORTS_0r(unit, &rval);
  41603                 SOC_PBMP_WORD_SET(pbmp, 0, rval);
  41604             }
  41605 
  41606             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) {
  41607                 READ_CMIC_PKT_PORTS_HIr(unit, &rval);
  41608                 SOC_PBMP_WORD_SET(pbmp, 1, rval);
  41609             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) {
  41610                 READ_CMIC_PKT_PORTS_1r(unit, &rval);
  41611                 SOC_PBMP_WORD_SET(pbmp, 1, rval);
  41612             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_1r)) {
  41613                 READ_CMIC_RPE_PKT_PORTS_1r(unit, &rval);
  41614                 SOC_PBMP_WORD_SET(pbmp, 1, rval);
  41615             }
  41616 
  41617             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) {
  41618                 READ_CMIC_PKT_PORTS_HI_2r(unit, &rval);
  41619                 SOC_PBMP_WORD_SET(pbmp, 2, rval);
  41620             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) {
  41621                 READ_CMIC_PKT_PORTS_2r(unit, &rval);
  41622                 SOC_PBMP_WORD_SET(pbmp, 2, rval);
  41623             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_2r)) {
  41624                 READ_CMIC_RPE_PKT_PORTS_2r(unit, &rval);
  41625                 SOC_PBMP_WORD_SET(pbmp, 2, rval);
  41626             }
  41627 
  41628             if (value) {
  41629                 SOC_PBMP_PORT_ADD(pbmp, port);
  41630             } else {
  41631                 SOC_PBMP_PORT_REMOVE(pbmp, port);
  41632             }
  41633             rval = 0;
  41634 
  41635             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) {
  41636                 soc_reg_field_set(unit, CMIC_PKT_PORTSr, &rval, PORTSf,
  41637                                  SOC_PBMP_WORD_GET(pbmp, 0));
  41638                 (void) WRITE_CMIC_PKT_PORTSr(unit, rval);
  41639             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) {
  41640                 soc_reg_field_set(unit, CMIC_PKT_PORTS_0r, &rval, PORTSf,
  41641                                  SOC_PBMP_WORD_GET(pbmp, 0));
  41642                 (void) WRITE_CMIC_PKT_PORTS_0r(unit, rval);
  41643             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_0r)) {
  41644                 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_0r, &rval, PORTSf,
  41645                                  SOC_PBMP_WORD_GET(pbmp, 0));
  41646                 (void) WRITE_CMIC_RPE_PKT_PORTS_0r(unit, rval);
  41647             }
  41648 
  41649             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) {
  41650                 rval = 0;
  41651                 soc_reg_field_set(unit, CMIC_PKT_PORTS_HIr, &rval, PORTS_HIf,
  41652                               SOC_PBMP_WORD_GET(pbmp, 1));
  41653                 (void) WRITE_CMIC_PKT_PORTS_HIr(unit, rval);
  41654             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) {
  41655                 rval = 0;
  41656                 soc_reg_field_set(unit, CMIC_PKT_PORTS_1r, &rval, PORTS_HIf,
  41657                               SOC_PBMP_WORD_GET(pbmp, 1));
  41658                 (void) WRITE_CMIC_PKT_PORTS_1r(unit, rval);
  41659             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_1r)) {
  41660                 rval = 0;
  41661                 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_1r, &rval, PORTS_HIf,
  41662                               SOC_PBMP_WORD_GET(pbmp, 1));
  41663                 (void) WRITE_CMIC_RPE_PKT_PORTS_1r(unit, rval);
  41664             }
  41665 
  41666             if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) {
  41667                 rval = 0;
  41668                 soc_reg_field_set(unit, CMIC_PKT_PORTS_HI_2r, &rval, PORTS_HIf,
  41669                               SOC_PBMP_WORD_GET(pbmp, 2));
  41670                 (void) WRITE_CMIC_PKT_PORTS_HI_2r(unit, rval);
  41671             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) {
  41672                 rval = 0;
  41673                 soc_reg_field_set(unit, CMIC_PKT_PORTS_2r, &rval, PORTS_HIf,
  41674                               SOC_PBMP_WORD_GET(pbmp, 2));
  41675                 (void) WRITE_CMIC_PKT_PORTS_2r(unit, rval);
  41676             } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_2r)) {
  41677                 rval = 0;
  41678                 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_2r, &rval, PORTS_HIf,
  41679                               SOC_PBMP_WORD_GET(pbmp, 2));
  41680                 (void) WRITE_CMIC_RPE_PKT_PORTS_2r(unit, rval);
  41681             }
  41682 
  41683             rv = BCM_E_NONE;
  41684         } else {
  41685             rv = BCM_E_UNAVAIL;
  41686         }
  41687         break;
  41688 
  41689     case bcmPortControlRemoteCpuTcMapping:
  41690         if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) {
  41691             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41692                                        REMOTE_CPU_ENf, (value) ? 1 : 0);
  41693             /* If BCM port, then set property in LPORT table too */
  41694             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41695                 rv = bcm_esw_port_lport_field_set(unit, port,
  41696                                                   LPORT_PROFILE_LPORT_TAB,
  41697                                                   REMOTE_CPU_ENf,
  41698                                                   (value) ? 1 : 0);
  41699             }
  41700         } else {
  41701             rv = BCM_E_UNAVAIL;
  41702         }
  41703         break;
  41704 
  41705     case bcmPortControlTrill:
  41706 #if defined(BCM_TRIDENT_SUPPORT)
  41707         if (soc_feature(unit, soc_feature_trill)) {
  41708             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41709                                        TRILL_ENABLEf, (value) ? 1 : 0);
  41710             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41711                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, TRILL_ENABLEf)) {
  41712                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41713                                                 TRILL_ENABLEf,
  41714                                                 (value) ? 1 : 0);
  41715                 }
  41716             }
  41717         }
  41718 #endif /* BCM_TRIDENT_SUPPORT */
  41719        break;
  41720 
  41721     case bcmPortControlTrillAllow:
  41722 #if defined(BCM_TRIDENT_SUPPORT)
  41723          if (soc_feature(unit, soc_feature_trill)) {
  41724              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41725                                         ALLOW_TRILL_FRAMESf,
  41726                                         (value) ? 1 : 0);
  41727              if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41728                  if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  41729                                          ALLOW_TRILL_FRAMESf)) {
  41730                      rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41731                                                  ALLOW_TRILL_FRAMESf,
  41732                                                  (value) ? 1 : 0);
  41733                  }
  41734              }
  41735          }
  41736 #endif /* BCM_TRIDENT_SUPPORT */
  41737          break;
  41738 
  41739     case bcmPortControlNonTrillAllow:
  41740 #if defined(BCM_TRIDENT_SUPPORT)
  41741          if (soc_feature(unit, soc_feature_trill)) {
  41742              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41743                                         ALLOW_NON_TRILL_FRAMESf,
  41744                                         (value) ? 1 : 0);
  41745              if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41746                  if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  41747                                          ALLOW_NON_TRILL_FRAMESf)) {
  41748                      rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41749                                                  ALLOW_NON_TRILL_FRAMESf,
  41750                                                  (value) ? 1 : 0);
  41751                  }
  41752              }
  41753          }
  41754 #endif /* BCM_TRIDENT_SUPPORT */
  41755          break;
  41756 
  41757     case bcmPortControlTrillCoreISISToCPU:
  41758 #if defined(BCM_TRIDENT_SUPPORT)
  41759          if (soc_feature(unit, soc_feature_trill)) {
  41760              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41761                                         COPY_CORE_IS_IS_TO_CPUf,
  41762                                         (value) ? 1 : 0);
  41763          }
  41764 #endif /* BCM_TRIDENT_SUPPORT */
  41765          break;
  41766 
  41767     case bcmPortControlTrillHashSelect:
  41768 #if defined(BCM_TRIUMPH3_SUPPORT)
  41769         if (SOC_IS_TRIUMPH3(unit)) {
  41770             return BCM_E_UNAVAIL;
  41771         } else
  41772 #endif /* BCM_TRIUMPH3_SUPPORT */
  41773         {
  41774 #if defined(BCM_TRIDENT_SUPPORT)
  41775              if (soc_feature(unit, soc_feature_trill)) {
  41776                    rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41777                             RTAG7_HASH_CFG_SEL_TRILL_ECMPf, (value) ? 1 : 0);
  41778              }
  41779 #endif /* BCM_TRIDENT_SUPPORT */
  41780         }
  41781          break;
  41782 
  41783     case bcmPortControlNivAccessVirtualInterfaceId:
  41784     case bcmPortControlExtendedPortVid:
  41785 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41786         if (soc_feature(unit, soc_feature_niv) ||
  41787             soc_feature(unit, soc_feature_port_extension)) {
  41788             int mod_port_index;
  41789 
  41790             if ((value < 0) || (value > 0xfff)) {
  41791                 return BCM_E_PARAM;
  41792             }
  41793             BCM_IF_ERROR_RETURN(
  41794                  _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41795                                        NIV_VIF_IDf, value));
  41796             BCM_IF_ERROR_RETURN(
  41797                 _bcm_esw_src_mod_port_table_index_get_from_port(
  41798                     unit, port, &mod_port_index));
  41799             SOC_IF_ERROR_RETURN(
  41800                 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, mod_port_index,
  41801                                        SRC_NIV_VIF_IDf, value));
  41802 
  41803             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  41804                 SOC_IS_GREYHOUND2(unit)) {
  41805                 uint64 val64;
  41806 
  41807                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  41808                 if (BCM_SUCCESS(rv)) {
  41809                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  41810                         &val64,
  41811                         NIV_VIF_IDf, value);
  41812                 }
  41813                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  41814             } else {
  41815                  rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_VIF_IDf, value);
  41816             }
  41817          }
  41818 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41819          break;
  41820 
  41821     case bcmPortControlNivNonVntagDrop:
  41822     case bcmPortControlNonEtagDrop:
  41823 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41824          if (soc_feature(unit, soc_feature_niv) ||
  41825              soc_feature(unit, soc_feature_port_extension)) {
  41826              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41827                      DISCARD_IF_VNTAG_NOT_PRESENTf, (value) ? 1 : 0);
  41828          }
  41829 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT*/
  41830          break;
  41831 
  41832     case bcmPortControlNivVntagDrop:
  41833     case bcmPortControlEtagDrop:
  41834 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41835          if (soc_feature(unit, soc_feature_niv) ||
  41836              soc_feature(unit, soc_feature_port_extension)) {
  41837              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41838                      DISCARD_IF_VNTAG_PRESENTf, (value) ? 1 : 0);
  41839          }
  41840 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41841          break;
  41842 
  41843     case bcmPortControlSubportPktTagDrop:
  41844 #if defined(BCM_KATANA2_SUPPORT)
  41845         if (soc_feature(unit, soc_feature_lltag)) {
  41846             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41847                      DISCARD_IF_LLTAG_PRESENTf, (value) ? 1 : 0);
  41848         }
  41849 #endif  /* BCM_KATANA2_SUPPORT */
  41850         break;
  41851 
  41852     case bcmPortControlNoSubportPktTagDrop:
  41853 #if defined(BCM_KATANA2_SUPPORT)
  41854         if (soc_feature(unit, soc_feature_lltag)) {
  41855             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41856                      DISCARD_IF_LLTAG_NOT_PRESENTf, (value) ? 1 : 0);
  41857         }
  41858 #endif  /* BCM_KATANA2_SUPPORT */
  41859         break;
  41860 
  41861     case bcmPortControlNivNonVntagAdd:
  41862     case bcmPortControlNonEtagAdd:
  41863 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41864          if (soc_feature(unit, soc_feature_niv) ||
  41865                  soc_feature(unit, soc_feature_port_extension)) {
  41866              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41867                      VNTAG_ACTIONS_IF_NOT_PRESENTf,
  41868                      (value) ?
  41869                      ((type == bcmPortControlNonEtagAdd) ? 2 : VNTAG_ADD) :
  41870                      VNTAG_NOOP);
  41871          }
  41872 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41873          break;
  41874 
  41875     case bcmPortControlNivVntagIngressReplace:
  41876     case bcmPortControlEtagIngressReplace:
  41877 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41878          if (soc_feature(unit, soc_feature_niv) ||
  41879                  soc_feature(unit, soc_feature_port_extension)) {
  41880              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41881                      VNTAG_ACTIONS_IF_PRESENTf,
  41882                      (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  41883          }
  41884 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41885          break;
  41886 
  41887     case bcmPortControlNivVntagEgressReplace:
  41888     case bcmPortControlEtagEgressReplace:
  41889 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41890          if (soc_feature(unit, soc_feature_niv) ||
  41891                  soc_feature(unit, soc_feature_port_extension)) {
  41892             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  41893                 SOC_IS_GREYHOUND2(unit)) {
  41894                 uint64 val64;
  41895 
  41896                 if (type == bcmPortControlEtagEgressReplace) {
  41897                     return BCM_E_UNAVAIL;
  41898                 }
  41899 
  41900                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  41901                 if (BCM_SUCCESS(rv)) {
  41902                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  41903                         &val64,
  41904                         VNTAG_ACTIONS_IF_PRESENTf,
  41905                         (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  41906                 }
  41907                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  41908             } else {
  41909                  rv = _bcm_esw_egr_port_tab_set(
  41910                           unit, port, VNTAG_ACTIONS_IF_PRESENTf,
  41911                           (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  41912             }
  41913          }
  41914 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41915          break;
  41916 
  41917     case bcmPortControlNivVntagIngressDelete:
  41918     case bcmPortControlEtagIngressDelete:
  41919 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41920          if (soc_feature(unit, soc_feature_niv) ||
  41921                  soc_feature(unit, soc_feature_port_extension)) {
  41922              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41923                      VNTAG_ACTIONS_IF_PRESENTf,
  41924                      (value) ? VNTAG_DELETE : VNTAG_NOOP);
  41925          }
  41926 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41927          break;
  41928 
  41929     case bcmPortControlNivVntagEgressDelete:
  41930     case bcmPortControlEtagEgressDelete:
  41931 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41932          if (soc_feature(unit, soc_feature_niv) ||
  41933                  soc_feature(unit, soc_feature_port_extension)) {
  41934             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  41935                 SOC_IS_GREYHOUND2(unit)) {
  41936                 uint64 val64;
  41937                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  41938                 if (BCM_SUCCESS(rv)) {
  41939                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  41940                         &val64,
  41941                         VNTAG_ACTIONS_IF_PRESENTf,
  41942                         (value) ? VNTAG_DELETE : VNTAG_NOOP);
  41943                 }
  41944                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  41945             } else {
  41946                 rv = _bcm_esw_egr_port_tab_set(
  41947                          unit, port, VNTAG_ACTIONS_IF_PRESENTf,
  41948                          (value) ? VNTAG_DELETE: VNTAG_NOOP);
  41949             }
  41950          }
  41951 #endif /* BCM_TRIDENT_SUPPORT  || BCM_GREYHOUND_SUPPORT */
  41952          break;
  41953 
  41954     case bcmPortControlNivRpfCheck:
  41955     case bcmPortControlExtenderRpfCheck:
  41956 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41957          if (soc_feature(unit, soc_feature_niv) ||
  41958                  soc_feature(unit, soc_feature_port_extension)) {
  41959              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41960                      NIV_RPF_CHECK_ENABLEf, (value) ? 1 : 0);
  41961          }
  41962 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41963          break;
  41964 
  41965     case bcmPortControlNivSourceKnockout:
  41966     case bcmPortControlExtenderSourceKnockout:
  41967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41968          if (soc_feature(unit, soc_feature_niv) ||
  41969                  soc_feature(unit, soc_feature_port_extension)) {
  41970             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  41971                 SOC_IS_GREYHOUND2(unit)) {
  41972                 uint64 val64;
  41973                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  41974                 if (BCM_SUCCESS(rv)) {
  41975                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  41976                         &val64,
  41977                         NIV_PRUNE_ENABLEf,
  41978                         (value) ? 1 : 0);
  41979                 }
  41980                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  41981             } else {
  41982                  rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_PRUNE_ENABLEf,
  41983                                                 (value) ? 1 : 0);
  41984             }
  41985          }
  41986 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41987          break;
  41988 
  41989     case bcmPortControlNivForwardPort:
  41990     case bcmPortControlExtenderForwardPort:
  41991 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41992          if (soc_feature(unit, soc_feature_niv) ||
  41993              soc_feature(unit, soc_feature_port_extension)) {
  41994              int mod_port_index;
  41995              bcm_module_t mod_out;
  41996              bcm_port_t port_out;
  41997              bcm_trunk_t trunk_out;
  41998              int id_out;
  41999              int tx_dest_port;
  42000 
  42001              if (value == -1) {
  42002                  BCM_IF_ERROR_RETURN
  42003                      (_bcm_esw_port_tab_set(unit, port,
  42004                                             _BCM_CPU_TABS_ETHER,
  42005                                             NIV_UPLINK_PORTf, 1));
  42006                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  42007                     SOC_IS_GREYHOUND2(unit)) {
  42008                     uint64 val64;
  42009                     rv = READ_EGR_PORT_64r(unit, port, &val64);
  42010                     if (BCM_SUCCESS(rv)) {
  42011                         soc_reg64_field32_set(unit, EGR_PORT_64r,
  42012                             &val64,
  42013                             NIV_UPLINK_PORTf, 1);
  42014                     }
  42015                     rv = WRITE_EGR_PORT_64r(unit, port, val64);
  42016                 } else {
  42017                     BCM_IF_ERROR_RETURN(
  42018                         _bcm_esw_egr_port_tab_set(unit, port,
  42019                                                   NIV_UPLINK_PORTf, 1));
  42020                     BCM_IF_ERROR_RETURN(
  42021                         _bcm_esw_src_mod_port_table_index_get_from_port(
  42022                             unit, port, &mod_port_index));
  42023                     SOC_IF_ERROR_RETURN(
  42024                         soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm,
  42025                                                mod_port_index,
  42026                                                SRC_IS_NIV_UPLINK_PORTf, 1));
  42027                  }
  42028                  rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42029                                             NIV_VIF_LOOKUP_ENABLEf, 1);
  42030              } else {
  42031                 BCM_IF_ERROR_RETURN
  42032                     (_bcm_esw_gport_resolve(unit, value, &mod_out, &port_out,
  42033                                              &trunk_out, &id_out));
  42034                 if (id_out != -1) {
  42035                     return BCM_E_PARAM;
  42036                 }
  42037 
  42038                 if (soc_feature(unit, soc_feature_generic_dest)) {
  42039                     uint32 dval;
  42040                     if (trunk_out != -1) {
  42041                         dval = _soc_mem_dest_value_construct(unit,
  42042                                     SOC_MEM_FIF_DEST_LAG, trunk_out);
  42043                     } else {
  42044                         dval = _soc_mem_dest_value_construct(unit,
  42045                                     SOC_MEM_FIF_DEST_DGPP,
  42046                                     mod_out << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | port_out);
  42047                     }
  42048                     BCM_IF_ERROR_RETURN
  42049                         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42050                                                DESTINATIONf, dval));
  42051                 } else {
  42052                     if (trunk_out != -1) {
  42053                         tx_dest_port = (1 << SOC_TRUNK_BIT_POS(unit)) + trunk_out;
  42054                     } else {
  42055 #if defined(BCM_METROLITE_SUPPORT)
  42056                    /* Metrolite DGLP still uses 7 bits for ports like saber2 */
  42057                       if (SOC_IS_METROLITE(unit)) {
  42058                           tx_dest_port = ((mod_out << 7) | (port_out));
  42059                       } else
  42060 #endif
  42061                           tx_dest_port = mod_out * (SOC_PORT_ADDR_MAX(unit) + 1) +
  42062                                     port_out;
  42063                     }
  42064 
  42065                     BCM_IF_ERROR_RETURN
  42066                         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42067                                                TX_DEST_PORTf, tx_dest_port));
  42068                 }
  42069                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42070                                            TX_DEST_PORT_ENABLEf, 1);
  42071             }
  42072         }
  42073 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  42074          break;
  42075 
  42076     case bcmPortControlNivType:
  42077         if (soc_feature(unit, soc_feature_niv)) {
  42078              if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  42079                 SOC_IS_GREYHOUND2(unit)) {
  42080 #if defined(BCM_GREYHOUND_SUPPORT)
  42081                  rv = bcm_gh_port_niv_type_set(unit, port, value);
  42082 #endif /* BCM_GREYHOUND_SUPPORT */
  42083             } else {
  42084 #if defined(BCM_TRIDENT_SUPPORT)
  42085                  rv = bcm_td_port_niv_type_set(unit, port, value);
  42086 #endif /* BCM_TRIDENT_SUPPORT */
  42087             }
  42088         }
  42089          break;
  42090 
  42091     case bcmPortControlExtenderType:
  42092         if (soc_feature(unit, soc_feature_port_extension)) {
  42093             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  42094                 SOC_IS_GREYHOUND2(unit)) {
  42095 #if defined(BCM_GREYHOUND_SUPPORT)
  42096                  rv = bcm_gh_port_extender_type_set(unit, port, value);
  42097 #endif /* BCM_GREYHOUND_SUPPORT */
  42098             } else {
  42099 #if defined(BCM_TRIUMPH3_SUPPORT)
  42100                  rv = bcm_tr3_port_extender_type_set(unit, port, value);
  42101 #endif /* BCM_TRIUMPH3_SUPPORT */
  42102             }
  42103         }
  42104          break;
  42105 
  42106     case bcmPortControlNivNameSpace:
  42107     case bcmPortControlExtenderNameSpace:
  42108 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  42109          if (soc_feature(unit, soc_feature_niv) ||
  42110                  soc_feature(unit, soc_feature_port_extension)) {
  42111              if ((value < 0) || (value > 0xfff)) {
  42112                  return BCM_E_PARAM;
  42113              }
  42114              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42115                      NIV_NAMESPACEf, value);
  42116          }
  42117 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  42118          break;
  42119 
  42120     case bcmPortControlEtagPcpDeSelect:
  42121 #if defined(INCLUDE_L3)
  42122         if (soc_feature(unit, soc_feature_port_extension)) {
  42123             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  42124                 SOC_IS_GREYHOUND2(unit)) {
  42125 #if defined(BCM_GREYHOUND_SUPPORT)
  42126                 rv = bcm_gh_port_etag_pcp_de_source_set(unit, port, value);
  42127 #endif /* BCM_GREYHOUND_SUPPORT */
  42128             } else {
  42129 #if defined(BCM_TRIUMPH3_SUPPORT)
  42130                 rv = bcm_tr3_port_etag_pcp_de_source_set(unit, port, value);
  42131 #endif /* BCM_TRIUMPH3_SUPPORT */
  42132             }
  42133         }
  42134 #endif /* INCLUDE_L3 */
  42135          break;
  42136 
  42137     case bcmPortControlEtagPcp:
  42138 #if defined(BCM_TRIUMPH3_SUPPORT)
  42139          if (soc_feature(unit, soc_feature_port_extension)) {
  42140              if ((value < 0) || (value > 7)) {
  42141                  return BCM_E_PARAM;
  42142              }
  42143              if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_PCPf)) {
  42144                  BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
  42145                                      EGR_ING_PORTm, port,
  42146                                      ETAG_PCPf, value));
  42147              }
  42148              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42149                      ETAG_PCPf, value);
  42150          }
  42151 #endif /* BCM_TRIUMPH3_SUPPORT */
  42152 #if defined(BCM_GREYHOUND_SUPPORT)
  42153         if (soc_feature(unit, soc_feature_port_extension)) {
  42154             if ((value < 0) || (value > 7)) {
  42155                 return BCM_E_PARAM;
  42156             }
  42157             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42158                     ETAG_PCPf, value);
  42159         }
  42160 #endif /* BCM_GREYHOUND_SUPPORT */
  42161          break;
  42162 
  42163     case bcmPortControlEtagDe:
  42164 #if defined(BCM_TRIUMPH3_SUPPORT)
  42165          if (soc_feature(unit, soc_feature_port_extension)) {
  42166              if ((value < 0) || (value > 1)) {
  42167                  return BCM_E_PARAM;
  42168              }
  42169              if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_DEf)) {
  42170                  BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
  42171                                      EGR_ING_PORTm, port,
  42172                                      ETAG_DEf, value));
  42173              }
  42174              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42175                      ETAG_DEf, value);
  42176          }
  42177 #endif /* BCM_TRIUMPH3_SUPPORT */
  42178 #if defined(BCM_GREYHOUND_SUPPORT)
  42179          if (soc_feature(unit, soc_feature_port_extension)) {
  42180             if ((value < 0) || (value > 1)) {
  42181                 return BCM_E_PARAM;
  42182             }
  42183             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42184                            ETAG_DEf, value);
  42185          }
  42186 #endif /* BCM_GREYHOUND_SUPPORT */
  42187          break;
  42188 
  42189     case bcmPortControlUseEtagPri:
  42190 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  42191         if (soc_feature(unit, soc_feature_port_extension)) {
  42192             if ((value < 0) || (value > 1)) {
  42193                 return BCM_E_PARAM;
  42194             }
  42195             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42196                                        PHB_FROM_ETAGf, value);
  42197 #if defined(BCM_GREYHOUND_SUPPORT)
  42198             if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  42199                 if (BCM_FAILURE(rv)) {
  42200                     return rv;
  42201                 }
  42202                 /*
  42203                  * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  42204                  * ETAG internal priority mapping.
  42205                  */
  42206                 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  42207                          (unit, (value) ? 1 : -1);
  42208             }
  42209 #endif /* BCM_GREYHOUND_SUPPORT */
  42210         }
  42211 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  42212          break;
  42213 
  42214     case bcmPortControlUseSubportPktTagPri:
  42215 #if defined(BCM_KATANA2_SUPPORT)
  42216          if (soc_feature(unit, soc_feature_lltag)) {
  42217              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42218                      PHB_FROM_LLTAGf, value);
  42219          }
  42220 #endif /* BCM_KATANA2_SUPPORT */
  42221          break;
  42222 
  42223     case bcmPortControlProhibitedDot1p:
  42224 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  42225          rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42226                  PROHIBITED_DOT1Pf, value);
  42227 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  42228          break;
  42229 
  42230     case bcmPortControlFabricSourceKnockout:
  42231         if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, REMOVE_HG_HDR_SRC_PORTf) ||
  42232             SOC_IS_TRIDENT3X(unit)) {
  42233             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42234                                 REMOVE_HG_HDR_SRC_PORTf, (value) ? 1 : 0);
  42235 
  42236             if (!SOC_IS_TOMAHAWK3(unit)) {
  42237                 /* If BCM port, then set property in LPORT table too */
  42238                 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  42239                     rv = bcm_esw_port_lport_field_set(unit, port,
  42240                                                   LPORT_PROFILE_LPORT_TAB,
  42241                                                   ALLOW_SRC_MODf, value);
  42242                 }
  42243             }
  42244         }
  42245         break;
  42246     case bcmPortControlRxEnable:
  42247         rv = _bcm_esw_mac_rx_control(unit, port, 0, &value);
  42248         break;
  42249     case bcmPortControlTxEnable:
  42250 
  42251         if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  42252             /* Use egress scheduling control if available */
  42253             uint32 val;
  42254             if (value > 0) {
  42255                 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42256                     /* Port tx was never stopped */
  42257                     rv = BCM_E_NONE;
  42258                     break;
  42259                 }
  42260                 /* Restore values */
  42261                 val = PORT(unit, port).cosmask;
  42262                 rv =  soc_reg_field32_modify(unit, COSMASKr, port,
  42263                                              COSMASKf, val);
  42264                 /* clear flag */
  42265                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  42266             } else {
  42267                 uint32 rval;
  42268                 /* Read and save current values */
  42269                 SOC_IF_ERROR_RETURN(READ_COSMASKr(unit, port, &rval));
  42270                 PORT(unit, port).cosmask = soc_reg_field_get(unit, COSMASKr,
  42271                                                              rval, COSMASKf);
  42272                 /* set flag */
  42273                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  42274                 /* Disable Tx */
  42275                 val = (1 << soc_reg_field_length(unit, COSMASKr,
  42276                                                  COSMASKf)) - 1;
  42277                 rv =  soc_reg_field32_modify(unit, COSMASKr, port,
  42278                                              COSMASKf, val);
  42279             }
  42280 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  42281         } else if  (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) {
  42282             rv = BCM_E_NONE;
  42283             if (value > 0 ) {
  42284                 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42285                     /* Port tx already enabled */
  42286                     break;
  42287                 }
  42288                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  42289                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 1));
  42290             } else {
  42291                 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42292                     /* Port tx already disabled */
  42293                     break;
  42294                 }
  42295                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  42296                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 0));
  42297             }
  42298             break;
  42299 #endif
  42300         } else if ((SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr)) ||
  42301                     (SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { /* Use egress metering control if available */
  42302                 uint32 rval1 = 0, rval2 = 0;
  42303                 if (value > 0 ) {
  42304                     if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42305                         /* Port tx was never stopped */
  42306                         break;
  42307                     }
  42308                 /* Restore values */
  42309                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port,
  42310                                                             &rval1));
  42311                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port,
  42312                                                             &rval2));
  42313                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  42314                                   REFRESHf, PORT(unit, port).m_info.refresh);
  42315                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  42316                                   THD_SELf, PORT(unit, port).m_info.threshold);
  42317                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  42318                                   BUCKETf, PORT(unit, port).m_info.bucket);
  42319                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  42320                                   IN_PROFILE_FLAGf,
  42321                                   PORT(unit, port).m_info.in_profile);
  42322                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port,
  42323                                                              rval1));
  42324                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port,
  42325                                                              rval2));
  42326                 /* clear flag */
  42327                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  42328                 rv = BCM_E_NONE;
  42329 
  42330             } else {
  42331                 /* Read and save current values */
  42332                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port,
  42333                                                             &rval1));
  42334                 PORT(unit, port).m_info.refresh =
  42335                     soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1,
  42336                                       REFRESHf);
  42337                 PORT(unit, port).m_info.threshold =
  42338                     soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1,
  42339                                       THD_SELf);
  42340                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port,
  42341                                                             &rval2));
  42342                 PORT(unit, port).m_info.bucket =
  42343                     soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2,
  42344                                       BUCKETf);
  42345                 PORT(unit, port).m_info.in_profile =
  42346                     soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2,
  42347                                       IN_PROFILE_FLAGf);
  42348                 /* set flag */
  42349                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  42350                 /* Disable Tx */
  42351                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  42352                                   REFRESHf, 0);
  42353                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  42354                                   THD_SELf, 1);
  42355                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  42356                                   BUCKETf, 0x100000);
  42357                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  42358                                   IN_PROFILE_FLAGf, 1);
  42359                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port,
  42360                                                              rval1));
  42361                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port,
  42362                                                              rval2));
  42363                 rv = BCM_E_NONE;
  42364             }
  42365         } else {
  42366             int (*port_tx_enable_set) (int, soc_port_t, int);
  42367 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  42368             if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit)) {
  42369                 port_tx_enable_set = soc_td2_port_traffic_egr_enable_set;
  42370             } else
  42371 #endif
  42372 #if defined(BCM_TRIDENT3_SUPPORT)
  42373             if (SOC_IS_TRIDENT3X(unit)) {
  42374                 port_tx_enable_set = soc_td3_port_traffic_egr_enable_set;
  42375             } else
  42376 #endif
  42377 #if defined(BCM_MONTEREY_SUPPORT)
  42378             if (SOC_IS_MONTEREY(unit)) {
  42379                 port_tx_enable_set = soc_monterey_port_traffic_egr_enable_set;
  42380             } else
  42381 #endif
  42382 #if defined(BCM_APACHE_SUPPORT)
  42383             if (SOC_IS_APACHE(unit)) {
  42384                 port_tx_enable_set = soc_apache_port_traffic_egr_enable_set;
  42385             } else
  42386 #endif
  42387 #if defined(BCM_TOMAHAWK_SUPPORT)
  42388             if (SOC_IS_TOMAHAWKX(unit)) {
  42389                 port_tx_enable_set = soc_tomahawk_port_traffic_egr_enable_set;
  42390             } else
  42391 #endif
  42392             {
  42393                 port_tx_enable_set = NULL;
  42394             }
  42395             if (port_tx_enable_set != NULL ) {
  42396                 rv = BCM_E_NONE;
  42397                 if (value > 0 ) {
  42398                     if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42399                         /* Port tx was never stopped */
  42400                         break;
  42401                     }
  42402                     PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  42403                     BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 1)));
  42404                 } else {
  42405                     if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  42406                         /* Port tx alrady enabled */
  42407                         break;
  42408                     }
  42409                     PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  42410                     BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 0)));
  42411                 }
  42412                 break;
  42413             } else {
  42414                 rv = BCM_E_UNAVAIL;
  42415             }
  42416         }
  42417         break;
  42418     case bcmPortControlMplsEntropyHashSet:
  42419 #if defined(BCM_TRIUMPH3_SUPPORT)
  42420         if (SOC_IS_TRIUMPH3(unit)) {
  42421             return BCM_E_UNAVAIL;
  42422         } else
  42423 #endif /* BCM_TRIUMPH3_SUPPORT */
  42424 #if defined(BCM_KATANA2_SUPPORT)
  42425         if (SOC_IS_KATANA2(unit)) {
  42426             return BCM_E_UNAVAIL;
  42427         } else
  42428 #endif /* BCM_KATANA2_SUPPORT */
  42429         {
  42430 #if defined(BCM_KATANA_SUPPORT)
  42431             if (soc_feature(unit, soc_feature_mpls)) {
  42432                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42433                                            RTAG7_HASH_CFG_SEL_ENTROPY_LABELf,
  42434                                            (value) ? 1 : 0);
  42435             }
  42436 #endif /* BCM_KATANA_SUPPORT */
  42437         }
  42438         break;
  42439 
  42440     case bcmPortControlL2GreEnable:
  42441 #if defined(BCM_TRIUMPH3_SUPPORT)
  42442         if (soc_feature(unit, soc_feature_l2gre)
  42443 #if defined(BCM_TRIDENT3_SUPPORT)
  42444             || soc_feature(unit, soc_feature_flex_flow)
  42445 #endif
  42446             ) {
  42447             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42448                                        L2GRE_TERMINATION_ALLOWEDf,
  42449                                        (value) ? 1 : 0);
  42450         }
  42451 #endif /* BCM_TRIUMPH3_SUPPORT */
  42452        break;
  42453 
  42454     case bcmPortControlL2GreTunnelbasedVpnId:
  42455 #if defined(BCM_TRIUMPH3_SUPPORT)
  42456         if (soc_feature(unit, soc_feature_l2gre)
  42457 #if defined(BCM_TRIDENT3_SUPPORT)
  42458             || soc_feature(unit, soc_feature_flex_flow)
  42459 #endif
  42460             ) {
  42461             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42462                                        L2GRE_VPNID_LOOKUP_KEY_TYPEf,
  42463                                        (value) ? 1 : 0);
  42464 
  42465             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  42466                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  42467                                         L2GRE_VFI_LOOKUP_KEY_TYPEf)) {
  42468                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  42469                                                 L2GRE_VFI_LOOKUP_KEY_TYPEf,
  42470                                                 (value) ? 1 : 0);
  42471                 }
  42472             }
  42473         }
  42474 #endif /* BCM_TRIUMPH3_SUPPORT */
  42475        break;
  42476 
  42477     case bcmPortControlL2GreDefaultTunnelEnable:
  42478 #if defined(BCM_TRIUMPH3_SUPPORT)
  42479         if (soc_feature(unit, soc_feature_l2gre)
  42480 #if defined(BCM_TRIDENT3_SUPPORT)
  42481             || soc_feature(unit, soc_feature_flex_flow)
  42482 #endif
  42483             ) {
  42484             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42485                                        L2GRE_DEFAULT_SVP_ENABLEf,
  42486                                        (value) ? 1 : 0);
  42487         }
  42488 #endif /* BCM_TRIUMPH3_SUPPORT */
  42489        break;
  42490 
  42491     case bcmPortControlVxlanEnable:
  42492 #if defined(BCM_TRIDENT2_SUPPORT)
  42493         if ((soc_feature(unit, soc_feature_vxlan)) ||
  42494             (soc_feature(unit, soc_feature_flex_flow))) {
  42495             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42496                                        VXLAN_TERMINATION_ALLOWEDf,
  42497                                        (value) ? 1 : 0);
  42498         }
  42499 #endif /* BCM_TRIDENT2_SUPPORT */
  42500        break;
  42501 
  42502     case bcmPortControlVxlanTunnelbasedVnId:
  42503 #if defined(BCM_TRIDENT2_SUPPORT)
  42504         if ((soc_feature(unit, soc_feature_vxlan)) ||
  42505             (soc_feature(unit, soc_feature_flex_flow))) {
  42506             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42507                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf,
  42508                                        (value) ? 1 : 0);
  42509             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  42510                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  42511                                         VXLAN_VFI_LOOKUP_KEY_TYPEf)) {
  42512                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  42513                                                 VXLAN_VFI_LOOKUP_KEY_TYPEf,
  42514                                                 (value) ? 1 : 0);
  42515                 }
  42516             }
  42517 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT)
  42518             if (BCM_SUCCESS(rv) && SOC_IS_TRIDENT3X(unit)) {
  42519                 rv = _bcm_esw_td3_port_cmh_ctrl_set(unit, port, type, value);
  42520             }
  42521 #endif
  42522         }
  42523 #endif /* BCM_TRIDENT2_SUPPORT */
  42524     break;
  42525     case bcmPortControlVxlanVpnAssignmentCriteria:
  42526 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  42527         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  42528             if ((value < bcmPortVxlanVpnAssignOnVnid)
  42529                 || (value > bcmPortVxlanVpnAssignOnVnidOuterVlanSrcIp)) {
  42530                 return BCM_E_PARAM;
  42531             }
  42532             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42533                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  42534         }
  42535 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  42536     break;
  42537     case bcmPortControlVxlanTerminationMatchCriteria:
  42538 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  42539         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  42540             if ((value < bcmPortVxlanTerminationMatchDstIp)
  42541                 || (value > bcmPortVxlanTerminationMatchOuterVlanDstIp)) {
  42542                 return BCM_E_PARAM;
  42543             }
  42544             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42545                                        VXLAN_TERMINATION_LOOKUP_TYPEf, value);
  42546         }
  42547 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  42548     break;
  42549     case bcmPortControlVxlanGportAssignmentCriteria:
  42550 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  42551         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  42552             if ((value < bcmPortVxlanGportAssignOnSrcIp)
  42553                 || (value > bcmPortVxlanGportAssignOnOuterVlanSrcIp)) {
  42554                 return BCM_E_PARAM;
  42555             }
  42556             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42557                                        VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value);
  42558         }
  42559 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  42560     break;
  42561     case bcmPortControlVxlanDefaultTunnelEnable:
  42562 #if defined(BCM_TRIDENT2_SUPPORT)
  42563         if ((soc_feature(unit, soc_feature_vxlan)) ||
  42564             (soc_feature(unit, soc_feature_flex_flow))) {
  42565             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42566                                        VXLAN_DEFAULT_SVP_ENABLEf,
  42567                                        (value) ? 1 : 0);
  42568         }
  42569 #endif /* BCM_TRIDENT2_SUPPORT */
  42570     break;
  42571 
  42572 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  42573     case bcmPortControlRegex:
  42574         if (!SOC_IS_TRIUMPH3(unit)) {
  42575             return BCM_E_UNAVAIL;
  42576         }
  42577         rv = _bcm_esw_port_regex_control_set(unit, port, 1, 1, !!value);
  42578         break;
  42579     case bcmPortControlRegexTcp:
  42580         if (!SOC_IS_TRIUMPH3(unit)) {
  42581             return BCM_E_UNAVAIL;
  42582         }
  42583         rv = _bcm_esw_port_regex_control_set(unit, port, 0, 1, !!value);
  42584         break;
  42585     case bcmPortControlRegexUdp:
  42586         if (!SOC_IS_TRIUMPH3(unit)) {
  42587             return BCM_E_UNAVAIL;
  42588         }
  42589         rv = _bcm_esw_port_regex_control_set(unit, port, 1, 0, !!value);
  42590         break;
  42591 #endif
  42592 #ifdef BCM_SHADOW_SUPPORT
  42593     case bcmPortControlManagementPacketIp6Reserved:
  42594         if (!SOC_IS_SHADOW(unit)) {
  42595             return BCM_E_UNAVAIL;
  42596         }
  42597         PORT_LOCK(unit);
  42598         if (value == 0) {
  42599             /* Clear the MGMT Frame classification */
  42600             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42601                                         IPV6_RESVf, 0);
  42602         } else {
  42603             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42604                                         IPV6_RESVf, 1);
  42605         }
  42606         PORT_UNLOCK(unit);
  42607         break;
  42608     case bcmPortControlManagementPacketIp4Reserved:
  42609         if (!SOC_IS_SHADOW(unit)) {
  42610             return BCM_E_UNAVAIL;
  42611         }
  42612         PORT_LOCK(unit);
  42613         if (value == 0) {
  42614             /* Clear the MGMT Frame classification */
  42615             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42616                                         IPV6_RESVf, 0);
  42617         } else {
  42618             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42619                                         IPV4_RESVf, 1);
  42620         }
  42621         PORT_UNLOCK(unit);
  42622         break;
  42623     case bcmPortControlManagementPacketLinkConstrained:
  42624         if (!SOC_IS_SHADOW(unit)) {
  42625             return BCM_E_UNAVAIL;
  42626         }
  42627         PORT_LOCK(unit);
  42628         if (value == 0) {
  42629             /* Clear the MGMT Frame classification */
  42630             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42631                                         LINK_CONSTf, 0);
  42632         } else {
  42633             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42634                                         LINK_CONSTf, 1);
  42635         }
  42636         PORT_UNLOCK(unit);
  42637         break;
  42638     case bcmPortControlManagementPacketGarp:
  42639         if (!SOC_IS_SHADOW(unit)) {
  42640             return BCM_E_UNAVAIL;
  42641         }
  42642         PORT_LOCK(unit);
  42643         if (value == 0) {
  42644             /* Clear the MGMT Frame classification */
  42645             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42646                                         DOT1D_GARPf, 0);
  42647         } else {
  42648             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  42649                                         DOT1D_GARPf, 1);
  42650         }
  42651         PORT_UNLOCK(unit);
  42652         break;
  42653     case bcmPortControlManagementPacketCos:
  42654         if (!SOC_IS_SHADOW(unit)) {
  42655             return BCM_E_UNAVAIL;
  42656         }
  42657         PORT_LOCK(unit);
  42658         if ((value >= 0) && (value <= 7)) {
  42659             /* Clear the MGMT Frame classification */
  42660             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42661                                         MGMT_FRAME_COSf, value);
  42662         } else {
  42663             rv = BCM_E_PARAM;
  42664         }
  42665         PORT_UNLOCK(unit);
  42666         break;
  42667     case bcmPortControlManagementPacketColor:
  42668         rv = BCM_E_UNAVAIL;
  42669         break;
  42670     case bcmPortControlTaggedL3PacketPktPri:
  42671         if (!SOC_IS_SHADOW(unit)) {
  42672             return BCM_E_UNAVAIL;
  42673         }
  42674         PORT_LOCK(unit);
  42675         switch ((bcm_port_cos_remap_t)value) {
  42676         case BCM_PORT_COS_REMAP_VLAN_PRI:
  42677             /* Clear the MGMT Frame classification */
  42678             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42679                                         SELECT5f, 0);
  42680         break;
  42681         case BCM_PORT_COS_REMAP_DSCP:
  42682             /* Clear the MGMT Frame classification */
  42683             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42684                                         SELECT5f, 2);
  42685         break;
  42686         default:
  42687             rv = BCM_E_PARAM;
  42688         }
  42689         PORT_UNLOCK(unit);
  42690         break;
  42691     case bcmPortControlTaggedMPLSPacketPktPri:
  42692         if (!SOC_IS_SHADOW(unit)) {
  42693             return BCM_E_UNAVAIL;
  42694         }
  42695         PORT_LOCK(unit);
  42696         switch ((bcm_port_cos_remap_t)value) {
  42697         case BCM_PORT_COS_REMAP_VLAN_PRI:
  42698             /* Clear the MGMT Frame classification */
  42699             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42700                                         SELECT3f, 0);
  42701         break;
  42702         case BCM_PORT_COS_REMAP_EXP:
  42703             /* Clear the MGMT Frame classification */
  42704             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42705                                         SELECT3f, 1);
  42706         break;
  42707         default:
  42708             rv = BCM_E_PARAM;
  42709         }
  42710         PORT_UNLOCK(unit);
  42711         break;
  42712     case bcmPortControlTaggedMPLSL3PacketPktPri:
  42713         if (!SOC_IS_SHADOW(unit)) {
  42714             return BCM_E_UNAVAIL;
  42715         }
  42716         PORT_LOCK(unit);
  42717         switch(value) {
  42718         case BCM_PORT_COS_REMAP_VLAN_PRI:
  42719             /* Clear the MGMT Frame classification */
  42720             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42721                                         SELECT7f, 0);
  42722         break;
  42723         case BCM_PORT_COS_REMAP_DSCP:
  42724             /* Clear the MGMT Frame classification */
  42725             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42726                                         SELECT7f, 2);
  42727         break;
  42728         case BCM_PORT_COS_REMAP_EXP:
  42729             /* Clear the MGMT Frame classification */
  42730             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  42731                                         SELECT7f, 1);
  42732         break;
  42733         default:
  42734             rv = BCM_E_PARAM;
  42735         }
  42736         PORT_UNLOCK(unit);
  42737         break;
  42738 
  42739 #endif
  42740 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  42741     case bcmPortControlFieldEgressClassSelect:
  42742 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  42743         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  42744             rv = _bcm_td2p_port_control_egress_class_select_set(unit, port, value);
  42745         } else
  42746 #endif
  42747         {
  42748             rv = _bcm_trx_port_control_egress_class_select_set(unit, port, value);
  42749         }
  42750         break;
  42751 #endif
  42752 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  42753     case bcmPortControlFieldHiGigClassSelect:
  42754 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  42755         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  42756             rv = _bcm_td2p_port_control_higig_class_select_set(unit, port, value);
  42757         } else
  42758 #endif
  42759         {
  42760             rv = _bcm_trx_port_control_higig_class_select_set(unit, port, value);
  42761         }
  42762         break;
  42763 #endif
  42764     case bcmPortControlSubportTagEnable:
  42765 
  42766 #if defined (BCM_HGPROXY_COE_SUPPORT)
  42767         if((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) ||
  42768             (soc_feature(unit, soc_feature_channelized_switching))) {
  42769             rv = bcmi_xgs5_port_control_subtag_status_set(unit, port, value);
  42770         }
  42771 #endif
  42772 #if defined (BCM_KATANA2_SUPPORT)
  42773         if (soc_feature(unit, soc_feature_subtag_coe)) {
  42774             if (SOC_IS_KATANA2(unit)) {
  42775                 rv = bcm_kt2_port_control_subtag_status_set(unit, port, value);
  42776             }
  42777 #if defined (BCM_METROLITE_SUPPORT)
  42778             /*In Metrolite physical port PP port is [re]used for the subports
  42779              * to achieve the MAX number of streams.*/
  42780             if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){
  42781                 BCM_PBMP_CLEAR(pbm);
  42782                 BCM_PBMP_PORT_ADD(pbm, port);
  42783                 if(value){
  42784                     bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm);
  42785                 }else{
  42786                     bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm);
  42787                 }
  42788             }
  42789 #endif
  42790         }
  42791 #endif
  42792         break;
  42793 
  42794     case bcmPortControlLinkPhyEnable:
  42795 #if defined (BCM_KATANA2_SUPPORT)
  42796         if (soc_feature(unit, soc_feature_linkphy_coe)) {
  42797             if (SOC_IS_KATANA2(unit)) {
  42798                 rv = bcm_kt2_port_control_linkphy_status_set(unit, port, value);
  42799             }
  42800 #if defined (BCM_METROLITE_SUPPORT)
  42801             /*In Metrolite physical port PP port is [re]used for the subports
  42802              * to achieve the MAX number of streams.*/
  42803             if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){
  42804                 BCM_PBMP_CLEAR(pbm);
  42805                 BCM_PBMP_PORT_ADD(pbm, port);
  42806                 if(value){
  42807                     bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm);
  42808                 }else{
  42809                     bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm);
  42810                 }
  42811             }
  42812 #endif
  42813         }
  42814 #endif
  42815         break;
  42816 
  42817 #if defined(BCM_TRIDENT2_SUPPORT)
  42818 
  42819     case bcmPortControlFcoeRouteEnable:
  42820         if (soc_feature(unit, soc_feature_fcoe)) {
  42821 #ifdef BCM_TRIDENT3_SUPPORT
  42822             if (SOC_IS_TRIDENT3X(unit)) {
  42823                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42824                                            FCOE_ROUTE_ENABLEf,
  42825                                            (value) ? 1 : 0);
  42826                 if ((rv == BCM_E_NONE) &&
  42827                     SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  42828                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) {
  42829                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  42830                                                 FCOE_ROUTE_ENABLEf,
  42831                                                 (value) ? 1 : 0);
  42832                 }
  42833             } else
  42834 #endif
  42835             {
  42836                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) {
  42837                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42838                                                FCOE_ROUTE_ENABLEf,
  42839                                                (value) ? 1 : 0);
  42840                 }
  42841                 if ((rv == BCM_E_NONE) &&
  42842                     SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  42843                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) {
  42844                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  42845                                                 FCOE_ROUTE_ENABLEf,
  42846                                                 (value) ? 1 : 0);
  42847                 }
  42848             }
  42849         }
  42850         break;
  42851 
  42852     case bcmPortControlFcoeVftEnable:
  42853         if (soc_feature(unit, soc_feature_fcoe)) {
  42854             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) {
  42855                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42856                                            FCOE_VFT_ENABLEf, (value) ? 1 : 0);
  42857             }
  42858         }
  42859         break;
  42860 
  42861     case bcmPortControlFcoeZoneCheckEnable:
  42862         if (soc_feature(unit, soc_feature_fcoe)) {
  42863             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  42864                                     FCOE_ZONE_CHECK_ENABLEf))) {
  42865                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42866                                            FCOE_ZONE_CHECK_ENABLEf,
  42867                                            (value) ? 1 : 0);
  42868             }
  42869         }
  42870         break;
  42871 
  42872     case bcmPortControlFcoeSourceBindCheckEnable:
  42873         if (soc_feature(unit, soc_feature_fcoe)) {
  42874             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  42875                                     FCOE_SRC_BIND_CHECK_ENABLEf)) {
  42876                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42877                                            FCOE_SRC_BIND_CHECK_ENABLEf,
  42878                                            (value) ? 1 : 0);
  42879             }
  42880         }
  42881         break;
  42882 
  42883     case bcmPortControlFcoeFpmaPrefixCheckEnable:
  42884         if (soc_feature(unit, soc_feature_fcoe)) {
  42885             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  42886                                     FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
  42887                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42888                                            FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf,
  42889                                            (value) ? 1 : 0);
  42890             }
  42891         }
  42892         break;
  42893 
  42894     case bcmPortControlFcoeDoNotLearn:
  42895         if (soc_feature(unit, soc_feature_fcoe)) {
  42896             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) {
  42897                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42898                                            FCOE_DO_NOT_LEARNf,
  42899                                            (value) ? 1 : 0);
  42900             }
  42901         }
  42902         break;
  42903 
  42904     case bcmPortControlFcoeNetworkPort:
  42905         if (soc_feature(unit, soc_feature_fcoe)) {
  42906             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) {
  42907                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42908                                            FCOE_NETWORK_PORTf,
  42909                                            (value) ? 1 : 0);
  42910             }
  42911         }
  42912         break;
  42913 
  42914     case bcmPortControlFcoeFabricSel:
  42915         if (soc_feature(unit, soc_feature_fcoe)) {
  42916             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) {
  42917                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42918                                            FCOE_FABRIC_SELf, value);
  42919             }
  42920         }
  42921         break;
  42922 
  42923     case bcmPortControlFcoeFabricId:
  42924         if (soc_feature(unit, soc_feature_fcoe)) {
  42925 #ifdef BCM_TRIDENT3_SUPPORT
  42926             if (SOC_IS_TRIDENT3X(unit)) {
  42927                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42928                                                FCOE_FABRIC_IDf, value);
  42929             } else
  42930 #endif
  42931             {
  42932                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) {
  42933                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42934                                                FCOE_FABRIC_IDf, value);
  42935                 }
  42936             }
  42937         }
  42938         break;
  42939 
  42940     case bcmPortControlFcoeFabricPri:
  42941         if (soc_feature(unit, soc_feature_fcoe)) {
  42942 #ifdef BCM_TRIDENT3_SUPPORT
  42943             if (SOC_IS_TRIDENT3X(unit)) {
  42944                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42945                                                FCOE_FABRIC_PRIf, value);
  42946             } else
  42947 #endif
  42948             {
  42949                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) {
  42950                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42951                                                FCOE_FABRIC_PRIf, value);
  42952                 }
  42953             }
  42954         }
  42955         break;
  42956 
  42957     case bcmPortControlFcoeFcCrcAction:
  42958         if (soc_feature(unit, soc_feature_fcoe)) {
  42959             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  42960                                     FCOE_FC_CRC_ACTIONf)) {
  42961                 /* 2 bits but only 0,1 are valid */
  42962                 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  42963                                             FCOE_FC_CRC_ACTIONf, value);
  42964             }
  42965         }
  42966         break;
  42967 
  42968     case bcmPortControlFcoeFcCrcRecompute:
  42969         if (soc_feature(unit, soc_feature_fcoe)) {
  42970             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  42971                 SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  42972                                     FCOE_FC_CRC_RECOMPUTEf)) {
  42973                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  42974                                             FCOE_FC_CRC_RECOMPUTEf, value);
  42975             }
  42976         }
  42977         break;
  42978 
  42979     case bcmPortControlFcoeFcEofIgnore:
  42980         if (soc_feature(unit, soc_feature_fcoe)) {
  42981             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  42982                                     FCOE_FC_EOF_IGNOREf)) {
  42983                 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  42984                                             FCOE_FC_EOF_IGNOREf,
  42985                                             (value) ? 1 : 0);
  42986             }
  42987         }
  42988         break;
  42989 
  42990     case bcmPortControlFcoeTranslateKeyFirst:
  42991     case bcmPortControlFcoeTranslateKeySecond:
  42992         if (soc_feature(unit, soc_feature_fcoe)) {
  42993 
  42994             /* first, translate value to HW value */
  42995             int key_type = 0;
  42996             int key_type_value;
  42997             int use_port = 0;
  42998 
  42999             switch (value) {
  43000                 case bcmFcoeVsanTranslateKeyPortDouble:
  43001                 use_port = 1; /* fall thru */
  43002                 case bcmFcoeVsanTranslateKeyDouble:
  43003                     key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
  43004                     break;
  43005                 case bcmFcoeVsanTranslateKeyPortOuterTag:
  43006                 use_port = 1; /* fall thru */
  43007                 case bcmFcoeVsanTranslateKeyOuterTag:
  43008                     key_type = VLXLT_HASH_KEY_TYPE_OTAG;
  43009                     break;
  43010                 case bcmFcoeVsanTranslateKeyPortInnerTag:
  43011                 use_port = 1; /* fall thru */
  43012                 case bcmFcoeVsanTranslateKeyInnerTag:
  43013                     key_type = VLXLT_HASH_KEY_TYPE_ITAG;
  43014                     break;
  43015                 case bcmFcoeVsanTranslateKeyPortOuter:
  43016                 use_port = 1; /* fall thru */
  43017                 case bcmFcoeVsanTranslateKeyOuter:
  43018                     key_type = VLXLT_HASH_KEY_TYPE_OVID;
  43019                     break;
  43020                 case bcmFcoeVsanTranslateKeyPortInner:
  43021                 use_port = 1; /* fall thru */
  43022                 case bcmFcoeVsanTranslateKeyInner:
  43023                     key_type = VLXLT_HASH_KEY_TYPE_IVID;
  43024                     break;
  43025                 case bcmFcoeVsanTranslateKeyPortOuterPri:
  43026                 use_port = 1; /* fall thru */
  43027                 case bcmFcoeVsanTranslateKeyOuterPri:
  43028                     key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
  43029                     break;
  43030                 case bcmFcoeVsanTranslateKeyPortDoubleVsan:
  43031                 use_port = 1; /* fall thru */
  43032                 case bcmFcoeVsanTranslateKeyDoubleVsan:
  43033                     key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
  43034                     break;
  43035                 case bcmFcoeVsanTranslateKeyPortInnerVsan:
  43036                 use_port = 1; /* fall thru */
  43037                 case bcmFcoeVsanTranslateKeyInnerVsan:
  43038                     key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN;
  43039                     break;
  43040                 case bcmFcoeVsanTranslateKeyPortOuterVsan:
  43041                 use_port = 1; /* fall thru */
  43042                 case bcmFcoeVsanTranslateKeyOuterVsan:
  43043                     key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN;
  43044                     break;
  43045                 default:
  43046                     return BCM_E_PARAM;
  43047             }
  43048 
  43049             BCM_IF_ERROR_RETURN(
  43050                 _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type,
  43051                                                        &key_type_value));
  43052 
  43053             if (type == bcmPortControlFcoeTranslateKeyFirst) {
  43054                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) {
  43055                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  43056                                                FCOE_VT_KEY_TYPE_1f,
  43057                                                key_type_value);
  43058                 }
  43059                 if (BCM_SUCCESS(rv)) {
  43060                     rv = _bcm_esw_port_config_set(unit, port,
  43061                                                   _bcmPortVTKeyPortFirst,
  43062                                                   use_port);
  43063                 }
  43064             } else {
  43065                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) {
  43066                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  43067                                                FCOE_VT_KEY_TYPE_2f,
  43068                                                key_type_value);
  43069                 }
  43070                 if (BCM_SUCCESS(rv)) {
  43071                     rv = _bcm_esw_port_config_set(unit, port,
  43072                                                   _bcmPortVTKeyPortSecond,
  43073                                                   use_port);
  43074                 }
  43075             }
  43076         }
  43077         break;
  43078 
  43079     case bcmPortControlFcoeTranslateKeyFirstEgress:
  43080     case bcmPortControlFcoeTranslateKeySecondEgress:
  43081         if (soc_feature(unit, soc_feature_fcoe)) {
  43082 
  43083             /* first, translate value to HW value */
  43084             int key_type_value = 0;
  43085 
  43086             switch (value) {
  43087                 case bcmFcoeVsanTranslateKeyEgressDoubleVsan:
  43088                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
  43089                     break;
  43090                 case bcmFcoeVsanTranslateKeyEgressVsan:
  43091                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_VSAN;
  43092                     break;
  43093                 case bcmFcoeVsanTranslateKeyEgressInnerVsan:
  43094                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN;
  43095                     break;
  43096                 case bcmFcoeVsanTranslateKeyEgressOuterVsan:
  43097                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN;
  43098                     break;
  43099                 case bcmFcoeVsanTranslateKeyEgressDouble:
  43100                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID;
  43101                     break;
  43102                 case bcmFcoeVsanTranslateKeyEgressInner:
  43103                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID;
  43104                     break;
  43105                 case bcmFcoeVsanTranslateKeyEgressOuter:
  43106                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID;
  43107                     break;
  43108                 default:
  43109                     return BCM_E_PARAM;
  43110             }
  43111 
  43112             if (type == bcmPortControlFcoeTranslateKeyFirstEgress) {
  43113                 if (SOC_IS_TRIDENT3X(unit) ||
  43114                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) {
  43115                     rv = _bcm_esw_egr_port_tab_set(unit, port,
  43116                                                    FCOE_VT_LOOKUP_1f,
  43117                                                    key_type_value);
  43118                 }
  43119             } else {
  43120                 if (SOC_IS_TRIDENT3X(unit) ||
  43121                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) {
  43122                     rv = _bcm_esw_egr_port_tab_set(unit, port,
  43123                                                    FCOE_VT_LOOKUP_2f,
  43124                                                    key_type_value);
  43125                 }
  43126             }
  43127         }
  43128         break;
  43129 
  43130 #endif  /* TRIDENT2 */
  43131     case bcmPortControlEEEMode:
  43132         if (soc_feature(unit, soc_feature_eee_bb_mode)) {
  43133             uint32 rval = 0;
  43134             uint32 fval = 0;
  43135             uint32 temp = 0;
  43136             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  43137                 soc_reg_t eee_bb_reg;
  43138                 int phy_port;
  43139                 int mmu_port;
  43140                 int offset;
  43141 
  43142                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  43143                 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  43144                 if (mmu_port < 32) {
  43145                     eee_bb_reg = EEE_BB_ENABLE_0r;
  43146                     offset = mmu_port;
  43147                 } else if ((mmu_port >=32) && (mmu_port < 64)) {
  43148                     eee_bb_reg = EEE_BB_ENABLE_1r;
  43149                     offset = mmu_port - 32;
  43150                 } else { /* mmu_port >= 64 */
  43151                     eee_bb_reg = EEE_BB_ENABLE_2r;
  43152                     offset = mmu_port - 64;
  43153                 }
  43154                 temp = (1 << offset);
  43155                 BCM_IF_ERROR_RETURN(
  43156                     soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval));
  43157                 fval = soc_reg_field_get(unit, eee_bb_reg, rval,
  43158                                          EEE_BB_ENABLEf);
  43159                 if (value == bcmPortEEEBurstAndBatchMode) {
  43160                     fval |= temp;
  43161                 } else if (value == bcmPortEEENativeMode) {
  43162                     fval &= ~temp;
  43163                 } else {
  43164                     return BCM_E_PARAM;
  43165                 }
  43166                 rv = soc_reg_field32_modify(unit, eee_bb_reg, REG_PORT_ANY,
  43167                                             EEE_BB_ENABLEf,
  43168                                             fval);
  43169             } else {
  43170                 temp = (1 << port);
  43171                 temp >>= 2;
  43172                 READ_EEE_BB_ENABLEr(unit, &rval);
  43173                 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval,
  43174                                          EEE_BB_ENABLEf);
  43175                 if (value == bcmPortEEEBurstAndBatchMode) {
  43176                     fval |= temp;
  43177                 } else if (value == bcmPortEEENativeMode) {
  43178                     fval &= ~temp;
  43179                 } else {
  43180                     return BCM_E_PARAM;
  43181                 }
  43182                 rv = soc_reg_field32_modify(unit, EEE_BB_ENABLEr, REG_PORT_ANY,
  43183                                             EEE_BB_ENABLEf,
  43184                                             fval);
  43185             }
  43186         }
  43187         break;
  43188 #ifdef BCM_GREYHOUND_SUPPORT
  43189     case bcmPortControlWredDropCountUpdateEnableQueueMask:
  43190         if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  43191 #if defined(BCM_GREYHOUND2_SUPPORT)
  43192             if (SOC_IS_GREYHOUND2(unit)) {
  43193                 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type,
  43194                                                          value);
  43195             } else
  43196 #endif /* BCM_GREYHOUND2_SUPPORT */
  43197             {
  43198                 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr,
  43199                                             port, QUEUE_MASKf, value);
  43200             }
  43201         }
  43202         break;
  43203     case bcmPortControlWredDropCountUpdateEnableColorMask:
  43204         if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  43205             /* parameter checking */
  43206             if (value & ~((0x1 << bcmColorGreen) |
  43207                 (0x1 << bcmColorYellow) |
  43208                 (0x1 << bcmColorRed))) {
  43209                 return BCM_E_PARAM;
  43210             }
  43211 #if defined(BCM_GREYHOUND2_SUPPORT)
  43212             if (SOC_IS_GREYHOUND2(unit)) {
  43213                 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type,
  43214                                                          value);
  43215             } else
  43216 #endif /* BCM_GREYHOUND2_SUPPORT */
  43217             {
  43218                 cur_val = 0;
  43219                 if (value & (0x1 << bcmColorGreen)) {
  43220                     cur_val |= 0x4;
  43221                 }
  43222                 if (value & (0x1 << bcmColorYellow)) {
  43223                     cur_val |= 0x2;
  43224                 }
  43225                 if (value & (0x1 << bcmColorRed)) {
  43226                     cur_val |= 0x1;
  43227                 }
  43228                 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr,
  43229                                             port, COLOR_MASKf, cur_val);
  43230             }
  43231         }
  43232         break;
  43233 #endif /* BCM_GREYHOUND_SUPPORT */
  43234 #ifdef BCM_TRIDENT2_SUPPORT
  43235     case bcmPortControlProbeSerdesReset:
  43236         if (SOC_IS_TD2_TT2(unit)) {
  43237             PORT_LOCK(unit);
  43238             if (value) {
  43239                 PORT(unit, port).flags |= _PORT_INFO_PROBE_RESET_SERDES;
  43240             } else {
  43241                 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES;
  43242             }
  43243             PORT_UNLOCK(unit);
  43244             rv = BCM_E_NONE;
  43245         }
  43246         break;
  43247 #endif /* BCM_TRIDENT2_SUPPORT */
  43248     case bcmPortControlMmuDrain:
  43249         rv = bcm_esw_port_drain_cells(unit, port, value);
  43250         break;
  43251     case bcmPortControlMmuTrafficEnable:
  43252         rv = bcm_esw_port_enqueue_set(unit, port, value);
  43253         break;
  43254     case bcmPortControlRxFastLOS:
  43255         rv = _bcm_esw_link_fast_set(unit, port, value);
  43256         break;
  43257     case bcmPortControlStatCollectionEnable:
  43258         if (!SOC_PORT_VALID(unit, port)) {
  43259             return BCM_E_PORT;
  43260         }
  43261         rv = soc_counter_port_collect_enable_set(unit, port, value);
  43262         break;
  43263     case bcmPortControlLLFCReceive:
  43264     case bcmPortControlLLFCTransmit:
  43265 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  43266     case bcmPortControlSAFCReceive:
  43267     case bcmPortControlSAFCTransmit:
  43268 #endif
  43269         rv = _bcm_esw_port_llfc_set(unit, port, type, value);
  43270         break;
  43271     case bcmPortControlTrunkLoadBalancingRandomizer:
  43272 #ifdef BCM_TOMAHAWK_SUPPORT
  43273         if (soc_feature(unit, soc_feature_randomized_load_balance)) {
  43274             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  43275                                        OFFSET_TRUNK_RANDOM_LBf, value);
  43276         }
  43277 #endif /* BCM_TOMAHAWK_SUPPORT */
  43278         break;
  43279     case bcmPortControlECMPLevel1LoadBalancingRandomizer:
  43280 #ifdef BCM_TOMAHAWK_SUPPORT
  43281         if (soc_feature(unit, soc_feature_ecmp_random)) {
  43282             if ((value < 0) || (value > 15)) {
  43283                 return BCM_E_PARAM;
  43284             }
  43285             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  43286                                        OFFSET_ECMP_RANDOM_LBf, value);
  43287         }
  43288 #endif /* BCM_TOMAHAWK_SUPPORT */
  43289         break;
  43290     case bcmPortControlECMPLevel2LoadBalancingRandomizer:
  43291 #ifdef BCM_TOMAHAWK_SUPPORT
  43292         if (soc_feature(unit, soc_feature_ecmp_random)) {
  43293             if ((value < 0) || (value > 15)) {
  43294                 return BCM_E_PARAM;
  43295             }
  43296             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  43297                                        OFFSET_ECMP_LEVEL2_RANDOM_LBf,
  43298                                        value);
  43299         }
  43300 #endif /* BCM_TOMAHAWK_SUPPORT */
  43301         break;
  43302     case bcmPortControlMcastGroupRemap:
  43303           if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
  43304               rv = soc_mem_field32_modify(unit, SOURCE_VPm, port,
  43305                       NETWORK_PORTf, value ? 1 : 0);
  43306           }
  43307           break;
  43308     case bcmPortControlOOBFCTxReportIngEnable:
  43309         if (soc_feature(unit, soc_feature_oob_fc)) {
  43310 #ifdef BCM_TOMAHAWK_SUPPORT
  43311             if (SOC_IS_TOMAHAWKX(unit)) {
  43312                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 0);
  43313             }
  43314 #endif
  43315 #ifdef BCM_KATANA2_SUPPORT
  43316             if (SOC_IS_KATANA2(unit)) {
  43317                 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 0);
  43318             }
  43319 #endif
  43320 #ifdef BCM_TRIDENT3_SUPPORT
  43321             if (SOC_IS_TRIDENT3X(unit)) {
  43322                 rv = _bcm_td3_oob_fc_tx_port_control_set(unit, port, value, 0);
  43323             }
  43324 #endif
  43325 #ifdef BCM_APACHE_SUPPORT
  43326             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  43327                 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 0);
  43328             }
  43329 #endif
  43330         }
  43331         break;
  43332     case bcmPortControlOOBFCTxReportEgrEnable:
  43333         if (soc_feature(unit, soc_feature_oob_fc)) {
  43334 #ifdef BCM_TOMAHAWK_SUPPORT
  43335             if (SOC_IS_TOMAHAWKX(unit)) {
  43336                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1);
  43337             }
  43338 #endif
  43339 #ifdef BCM_APACHE_SUPPORT
  43340             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  43341                 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 1);
  43342             }
  43343 #endif
  43344 #ifdef BCM_KATANA2_SUPPORT
  43345             if (SOC_IS_KATANA2(unit)) {
  43346                 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 1);
  43347             }
  43348 #endif
  43349 #ifdef BCM_TRIDENT3_SUPPORT
  43350             if (SOC_IS_TRIDENT3X(unit)) {
  43351                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1);
  43352             }
  43353 #endif
  43354         }
  43355         break;
  43356 
  43357 	case bcmPortControlSubportTagSize:
  43358 #ifdef BCM_HGPROXY_COE_SUPPORT
  43359           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  43360                                   DESTINATION_SUBPORT_TAG_TYPEf)) {
  43361 
  43362               int local_port = 0;
  43363               if (BCM_GPORT_IS_SET(port)) {
  43364                   BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  43365               } else {
  43366                   if(!SOC_PORT_VALID(unit, port)) {
  43367                       return BCM_E_PORT;
  43368                   } else {
  43369                       local_port = port;
  43370                   }
  43371               }
  43372 
  43373               /* Setting of tag_type to 8Byte is not supported currently,
  43374                  hence return error if 'value' is non-zero */
  43375               if(value) {
  43376                   return BCM_E_UNAVAIL;
  43377               }
  43378 
  43379               rv = soc_mem_field32_modify(unit, EGR_PORTm, local_port,
  43380                       DESTINATION_SUBPORT_TAG_TYPEf, value ? 1 : 0);
  43381           }
  43382           if (SOC_IS_TRIDENT3X(unit)) {
  43383               if (value) {
  43384                   return BCM_E_UNAVAIL;
  43385               }
  43386               else {
  43387                   return BCM_E_NONE;
  43388               }
  43389           }
  43390 #endif
  43391 		  break;
  43392 
  43393 	case bcmPortControlSystemPortOverride:
  43394 #ifdef BCM_HGPROXY_COE_SUPPORT
  43395         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_SYS_PORT_OVERRIDEf)) {
  43396             rv = bcmi_xgs5_subport_subtag_port_override_set(unit, port, value);
  43397         }
  43398 #endif
  43399         break;
  43400 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  43401     case bcmPortControlSampleIngressDest:
  43402         if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  43403             sflow_ing_data_source_entry_t sflow_entry;
  43404             uint32 field_values[2] = {0, 0};
  43405             if ((value < 0) || (value > 3)) {
  43406                 return BCM_E_PARAM;
  43407             }
  43408 
  43409             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) ==
  43410                  BCM_PORT_CONTROL_SAMPLE_DEST_CPU) {
  43411                 field_values[0] = 1;
  43412             }
  43413             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) ==
  43414                  BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) {
  43415                 field_values[1] = 1;
  43416             }
  43417 
  43418             BCM_IF_ERROR_RETURN
  43419                 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43420                                              &sflow_entry));
  43421             soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43422                                                  CPUf, &field_values[0]);
  43423             soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43424                                                  MIRRORf, &field_values[1]);
  43425             BCM_IF_ERROR_RETURN
  43426                 (WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43427                                               &sflow_entry));
  43428             rv = BCM_E_NONE;
  43429         }
  43430         break;
  43431     case bcmPortControlSampleFlexDest:
  43432         if(soc_feature(unit, soc_feature_sflow_flex)) {
  43433             sflow_ing_flex_data_source_entry_t sflow_entry;
  43434             uint32 field_values[2] = {0, 0};
  43435             if ((value < 0) || (value > 3)) {
  43436                 return BCM_E_PARAM;
  43437             }
  43438 
  43439             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) ==
  43440                  BCM_PORT_CONTROL_SAMPLE_DEST_CPU) {
  43441                 field_values[0] = 1;
  43442             }
  43443             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) ==
  43444                  BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) {
  43445                 field_values[1] = 1;
  43446             }
  43447 
  43448             BCM_IF_ERROR_RETURN
  43449                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43450                                                   &sflow_entry));
  43451             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43452                                                       CPUf, &field_values[0]);
  43453             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43454                                                       MIRRORf, &field_values[1]);
  43455             BCM_IF_ERROR_RETURN
  43456                 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43457                                                    &sflow_entry));
  43458             rv = BCM_E_NONE;
  43459         }
  43460         break;
  43461     case bcmPortControlSampleFlexRate:
  43462         if(soc_feature(unit, soc_feature_sflow_flex)) {
  43463             uint32 values[2] = {0, 0};
  43464             sflow_ing_flex_data_source_entry_t sflow_entry;
  43465             soc_counter_non_dma_t *non_dma = NULL;
  43466             soc_control_t *soc;
  43467             uint32 count = 0, subset_ct = 0;
  43468 
  43469             if (value < 0) {
  43470                 return BCM_E_PARAM;
  43471             }
  43472             /* Set sampling threshold */
  43473             if (value > 0) {
  43474                 /* Enable sFlow */
  43475                 values[0] = 1;
  43476 
  43477                 /* Set sampling threshold */
  43478                 if (value == 1) {
  43479                     /* Needs special handling to avoid register overflow */
  43480                     values[1] = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  43481                 } else {
  43482                     /* Calculate threshold based on sampling rate */
  43483                     values[1] = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  43484                 }
  43485             }
  43486 
  43487             /* Update Flex rate limiting data table. */
  43488             BCM_IF_ERROR_RETURN
  43489                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43490                                                   &sflow_entry));
  43491             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43492                                                       ENABLEf, &values[0]);
  43493             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  43494                                                       THRESHOLDf, &values[1]);
  43495             BCM_IF_ERROR_RETURN
  43496                 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43497                                                    &sflow_entry));
  43498 
  43499             /* Enable counter thread for Flex sFlow samplers */
  43500             if (values[0] == 1) {
  43501                 soc = SOC_CONTROL(unit);
  43502                 non_dma = &soc->counter_non_dma[
  43503                             SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT -
  43504                             SOC_COUNTER_NON_DMA_START];
  43505                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  43506                     /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  43507                     subset_ct = non_dma->extra_ctr_ct << 1;
  43508                     non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  43509                     non_dma = non_dma->extra_ctrs;
  43510 
  43511                     do {
  43512                         non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  43513                         /* BYTE_CTRf not currently supported */
  43514                         count += 2;
  43515                         non_dma += 2;
  43516                     } while ((count < subset_ct));
  43517                 }
  43518             }
  43519             rv = BCM_E_NONE;
  43520         }
  43521         break;
  43522 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  43523 #ifdef BCM_XGS3_SWITCH_SUPPORT
  43524     case bcmPortControlSampleIngressEnable:
  43525         if (SOC_IS_XGS3_SWITCH(unit)) {
  43526             uint32 regval       = 0;
  43527             uint32 field_enable = 0;
  43528 #ifdef BCM_TOMAHAWK_SUPPORT
  43529             sflow_ing_data_source_entry_t sflow_entry;
  43530             soc_counter_non_dma_t *non_dma = NULL;
  43531             soc_control_t *soc;
  43532             uint32 count = 0, subset_ct = 0;
  43533 #endif /* BCM_TOMAHAWK_SUPPORT */
  43534 
  43535             field_enable = value ? 1 : 0;
  43536 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  43537             /* Update Ingress rate limiting data table. */
  43538             if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  43539                 BCM_IF_ERROR_RETURN(
  43540                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43541                                                 &sflow_entry));
  43542                 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, ENABLEf,
  43543                                                      &field_enable);
  43544 
  43545                 BCM_IF_ERROR_RETURN(
  43546                     WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43547                                                  &sflow_entry));
  43548 
  43549                 /* Enable counter thread for Ingress sFlow samplers */
  43550                 if (field_enable) {
  43551                     soc = SOC_CONTROL(unit);
  43552                     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_ING_PKT -
  43553                                                     SOC_COUNTER_NON_DMA_START];
  43554                     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  43555                         /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  43556                         subset_ct = non_dma->extra_ctr_ct << 1;
  43557                         non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  43558                         non_dma = non_dma->extra_ctrs;
  43559 
  43560                         do {
  43561                             non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  43562                             /* BYTE_CTRf not currently supported */
  43563                             count += 2;
  43564                             non_dma += 2;
  43565                         } while ((count < subset_ct));
  43566                     }
  43567                 }
  43568                 rv =  BCM_E_NONE;
  43569             } else
  43570 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  43571             {
  43572                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  43573                     return BCM_E_UNAVAIL;
  43574                 }
  43575                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  43576                 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, &regval,
  43577                                   ENABLEf, field_enable);
  43578 
  43579                 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval));
  43580                 rv = BCM_E_NONE;
  43581             }
  43582         } else {
  43583             rv = BCM_E_UNAVAIL;
  43584         }
  43585         break;
  43586     case bcmPortControlSampleEgressEnable:
  43587         if (SOC_IS_XGS3_SWITCH(unit)) {
  43588             uint32 regval       = 0;
  43589             uint32 field_enable = 0;
  43590 
  43591             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  43592                 return BCM_E_UNAVAIL;
  43593             }
  43594             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  43595 
  43596             field_enable = value ? 1 : 0;
  43597             soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, &regval,
  43598                               ENABLEf, field_enable);
  43599 
  43600             BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval));
  43601             rv = BCM_E_NONE;
  43602         } else {
  43603             rv = BCM_E_UNAVAIL;
  43604         }
  43605         break;
  43606     case bcmPortControlSampleIngressRate:
  43607         if (SOC_IS_XGS3_SWITCH(unit)) {
  43608             uint32 field_value = 0;
  43609             uint32 regval = 0;
  43610 #ifdef BCM_TOMAHAWK_SUPPORT
  43611             sflow_ing_data_source_entry_t sflow_entry;
  43612 #endif /* BCM_TOMAHAWK_SUPPORT */
  43613 
  43614 
  43615                 /*           rate         - (IN)Every 1/rate a packet will be sampled
  43616                  *            1 indicating sample all.
  43617                  *            0 indicating sample none.*/
  43618             if (value > 0) {
  43619                 /* Set sampling threshold */
  43620                 if (value == 1) {
  43621                     /* Needs special handling to avoid register overflow */
  43622                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  43623                 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) {
  43624                     /* Calculate threshold based on sampling rate */
  43625                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  43626                 } else {
  43627                     return BCM_E_PARAM;
  43628                 }
  43629 
  43630                 /*
  43631                  * For early sFlow implementations the 16-bit threshold value
  43632                  * is compared to bits [23:8] of the sFlow random number.
  43633                  */
  43634                 if (soc_feature(unit, soc_feature_sample_offset8)) {
  43635                     field_value >>= 8;
  43636                 }
  43637 
  43638                 /* Cut the value in case 16 bit threshold can not accomodate it. */
  43639                 if (soc_feature(unit, soc_feature_sample_thresh16)) {
  43640                     if (field_value >= (1 << 16)) {
  43641                         field_value = (1 << 16) - 1;
  43642                     }
  43643                 }
  43644             }
  43645 
  43646 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  43647             /* Update Ingress rate limiting data table. */
  43648             if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  43649                 BCM_IF_ERROR_RETURN(
  43650                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43651                                                 &sflow_entry));
  43652                 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, THRESHOLDf,
  43653                                                      &field_value);
  43654 
  43655                 BCM_IF_ERROR_RETURN(
  43656                     WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  43657                                                  &sflow_entry));
  43658 
  43659                 rv =  BCM_E_NONE;
  43660             } else
  43661 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  43662             {
  43663                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  43664                     return BCM_E_UNAVAIL;
  43665                 }
  43666                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  43667                 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, &regval,
  43668                                   THRESHOLDf, field_value);
  43669 
  43670                 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval));
  43671                 rv = BCM_E_NONE;
  43672             }
  43673         } else {
  43674             rv = BCM_E_UNAVAIL;
  43675         }
  43676         break;
  43677     case bcmPortControlSampleEgressRate:
  43678         if (SOC_IS_XGS3_SWITCH(unit)) {
  43679             uint32 field_value = 0, regval = 0;
  43680 
  43681                 /*           rate         - (IN)Every 1/rate a packet will be sampled
  43682                  *            1 indicating sample all.
  43683                  *            0 indicating sample none.*/
  43684             if (value > 0) {
  43685                 /* Set sampling threshold */
  43686                 if (value == 1) {
  43687                     /* Needs special handling to avoid register overflow */
  43688                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  43689                 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) {
  43690                     /* Calculate threshold based on sampling rate */
  43691                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  43692                 } else {
  43693                     return BCM_E_PARAM;
  43694                 }
  43695 
  43696                 /*
  43697                  * For early sFlow implementations the 16-bit threshold value
  43698                  * is compared to bits [23:8] of the sFlow random number.
  43699                  */
  43700                 if (soc_feature(unit, soc_feature_sample_offset8)) {
  43701                     field_value >>= 8;
  43702                 }
  43703 
  43704                 /* Cut the value in case 16 bit threshold can not accomodate it. */
  43705                 if (soc_feature(unit, soc_feature_sample_thresh16)) {
  43706                     if (field_value >= (1 << 16)) {
  43707                         field_value = (1 << 16) - 1;
  43708                     }
  43709                 }
  43710             }
  43711 
  43712             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  43713                 return BCM_E_UNAVAIL;
  43714             }
  43715 
  43716             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  43717             soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, &regval,
  43718                               THRESHOLDf, field_value);
  43719 
  43720             BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval));
  43721             rv = BCM_E_NONE;
  43722         } else {
  43723             rv = BCM_E_UNAVAIL;
  43724         }
  43725         break;
  43726 #endif
  43727     case bcmPortControlExternalBufferEnable:
  43728 #if defined(BCM_KATANA2_SUPPORT)
  43729           if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) {
  43730               rv = _bcm_kt2_cosq_port_ext_buf_set(unit, port, value);
  43731           }
  43732 #endif
  43733           break;
  43734 #ifdef BCM_HURRICANE3_SUPPORT
  43735     case bcmPortControlTrustMimlPri:
  43736         if (soc_feature(unit, soc_feature_miml)) {
  43737             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  43738                                        USE_MIML_PCP_FOR_PRIf, value ? 1 : 0);
  43739             if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  43740                 if (BCM_FAILURE(rv)) {
  43741                     return rv;
  43742                 }
  43743                 /*
  43744                  * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  43745                  * MiML internal priority mapping.
  43746                  */
  43747                 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  43748                          (unit, (value) ? 1 : -1);
  43749             }
  43750         }
  43751         break;
  43752     case bcmPortControlTrustCustomHeaderPri:
  43753         if (soc_feature(unit, soc_feature_custom_header)) {
  43754             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  43755                                        USE_CUSTOM_HEADER_FOR_PRIf,
  43756                                        value ? 1 : 0);
  43757         }
  43758         break;
  43759     case bcmPortControlCustomHeaderEncapEnable:
  43760         if (soc_feature(unit, soc_feature_custom_header)) {
  43761             uint64 val64;
  43762 
  43763             rv = READ_EGR_PORT_64r(unit, port, &val64);
  43764             if (BCM_SUCCESS(rv)) {
  43765                 soc_reg64_field32_set(unit, EGR_PORT_64r,
  43766                     &val64,
  43767                     CUSTOM_HEADER_ENABLEf, value ? 1 : 0);
  43768             }
  43769 
  43770             rv = WRITE_EGR_PORT_64r(unit, port, val64);
  43771         }
  43772         break;
  43773 #endif /* BCM_HURRICANE3_SUPPORT */
  43774 #if defined(BCM_SABER2_SUPPORT)
  43775     case bcmPortControlSatEnable:
  43776         PORT_LOCK(unit);
  43777         if (SOC_IS_SABER2(unit)) {
  43778             COUNTER_LOCK(unit);
  43779             SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  43780             rv = _bcm_sb2_port_oamp_enable(unit, port, value);
  43781             COUNTER_UNLOCK(unit);
  43782             SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  43783         } else {
  43784             rv = BCM_E_UNAVAIL;
  43785         }
  43786         PORT_UNLOCK(unit);
  43787         break;
  43788 #endif
  43789     case bcmPortControl1588P2PDelay:
  43790         {
  43791             int p_speed=0;
  43792             rv = bcm_esw_port_speed_get(unit, port, &p_speed);
  43793             if (BCM_FAILURE(rv)) {
  43794                 rv = BCM_E_FAIL;
  43795             }
  43796             PORT(unit, port).link_delay_offset = value;
  43797             rv = _bcm_esw_port_link_delay_update(unit, port, p_speed);
  43798         }
  43799         break;
  43800     case bcmPortControlPacketTimeStampInsertRx:
  43801 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43802     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43803         if (soc_feature(unit, soc_feature_timestamp)) {
  43804             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43805             BCM_IF_ERROR_RETURN(
  43806                 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  43807                                       INSERT_RX_TIMESTAMPf, value ? 1 : 0));
  43808             rv = BCM_E_NONE;
  43809         }
  43810         break;
  43811 #endif
  43812     case bcmPortControlPacketTimeStampInsertTx:
  43813 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43814     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43815         if (soc_feature(unit, soc_feature_timestamp)) {
  43816             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43817             SOC_IF_ERROR_RETURN(
  43818                 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  43819                                        INSERT_TX_TIMESTAMPf, value ? 1 : 0));
  43820             rv = BCM_E_NONE;
  43821         }
  43822         break;
  43823 #endif
  43824     case bcmPortControlPacketTimeStampSrcPortInsertCancel:
  43825 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43826     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43827         if (soc_feature(unit, soc_feature_timestamp)) {
  43828             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43829             BCM_IF_ERROR_RETURN(
  43830                 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  43831                                       DISABLE_TIMESTAMPINGf, value ? 1 : 0));
  43832             rv = BCM_E_NONE;
  43833         }
  43834         break;
  43835 #endif
  43836     case bcmPortControlPacketTimeStampDestPortInsertCancel:
  43837 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43838     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43839         if (soc_feature(unit, soc_feature_timestamp)) {
  43840             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43841             SOC_IF_ERROR_RETURN(
  43842                 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  43843                                        DISABLE_TIMESTAMPINGf, value ? 1 : 0));
  43844             rv = BCM_E_NONE;
  43845         }
  43846         break;
  43847 #endif
  43848     case bcmPortControlPacketTimeStampRxId:
  43849 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43850     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43851         if (soc_feature(unit, soc_feature_timestamp)) {
  43852             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43853             if ((value < 0) || (value >= 0x7FFFFF)) {
  43854                 return BCM_E_PARAM;
  43855             }
  43856             if (SOC_REG_IS_VALID(unit,EGR_TS_ING_PORT_MAPr)) {
  43857                 SOC_IF_ERROR_RETURN(
  43858                      soc_reg_field32_modify(unit, EGR_TS_ING_PORT_MAPr,
  43859                                        port, TS_RX_ORIGIN_IDf, value));
  43860             } else {
  43861                 SOC_IF_ERROR_RETURN(
  43862                 soc_mem_field32_modify(unit, EGR_TS_ING_PORT_MAPm,
  43863                                        port, TS_RX_ORIGIN_IDf, value));
  43864             }
  43865             rv = BCM_E_NONE;
  43866         }
  43867 #endif
  43868         break;
  43869     case bcmPortControlPacketTimeStampTxId:
  43870 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43871     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43872         if (soc_feature(unit, soc_feature_timestamp)) {
  43873             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43874             if ((value < 0) || (value >= 0x7FFFFF)) {
  43875                 return BCM_E_PARAM;
  43876             }
  43877             if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf))
  43878             {
  43879                 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROL_2r,
  43880                                             port, TS_TX_ORIGIN_IDf, value);
  43881             } else {
  43882                 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr,
  43883                                             port, TS_TX_ORIGIN_IDf, value);
  43884             }
  43885         }
  43886 #endif
  43887         break;
  43888     case bcmPortControlPacketTimeStampByteMeterAdjust:
  43889 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  43890     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  43891         if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit))
  43892         {
  43893             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43894             rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  43895                                         TS_ADJUST_METERSf, (value) ? 1 : 0);
  43896         }
  43897 #endif
  43898         break;
  43899     case bcmPortControlE2EFCTransmitEnable:
  43900         if (soc_feature(unit, soc_feature_e2efc)) {
  43901             uint64 val;
  43902 #if defined(BCM_KATANA2_SUPPORT)
  43903             uint32 val32;
  43904 #endif
  43905             if (!IS_HG_PORT(unit, port)) {
  43906                 LOG_ERROR(
  43907                     BSL_LS_BCM_PORT,
  43908                     (BSL_META_U(unit,
  43909                                 "Error: unit %d port %d is not a Higig port. "
  43910                                 "E2EFC messages can only be transmitted to "
  43911                                 "or received from Higig ports.\n"),
  43912                      unit, port));
  43913                 return BCM_E_PARAM;
  43914             }
  43915 #if defined(BCM_KATANA2_SUPPORT)
  43916             if (SOC_IS_KATANA2(unit)) {
  43917                 val32 = value ? 1: 0;
  43918                 rv = WRITE_E2EFC_IBP_ENr(unit, val32);
  43919             } else
  43920 #endif
  43921             if (IS_XL_PORT(unit, port)) {
  43922                 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val));
  43923                 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr,
  43924                                       &val, E2E_ENABLEf, value ? 1 : 0);
  43925                 rv = WRITE_XLMAC_E2E_CTRLr(unit, port, val);
  43926             } else if (IS_CL_PORT(unit, port)) {
  43927                 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val));
  43928                 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr,
  43929                                       &val, E2E_ENABLEf, value ? 1 : 0);
  43930                 rv = WRITE_CLMAC_E2E_CTRLr(unit, port, val);
  43931             } else {
  43932                 return BCM_E_PARAM;
  43933             }
  43934         }
  43935         break;
  43936     case bcmPortControlE2EFCReceiveEnable:
  43937         if (soc_feature(unit, soc_feature_e2efc)) {
  43938             uint32 val;
  43939 
  43940             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  43941             soc_reg_field_set(unit, IE2E_CONTROLr,
  43942                               &val, IBP_ENABLEf, value ? 1 : 0);
  43943             rv = WRITE_IE2E_CONTROLr(unit, port, val);
  43944         }
  43945         break;
  43946     case bcmPortControlE2EFCCopyToCpuEnable:
  43947         if (soc_feature(unit, soc_feature_e2efc)) {
  43948             uint32 val;
  43949 
  43950             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  43951             soc_reg_field_set(unit, IE2E_CONTROLr,
  43952                               &val, IBP_TOCPUf, value ? 1 : 0);
  43953             rv = WRITE_IE2E_CONTROLr(unit, port, val);
  43954         }
  43955         break;
  43956     /* Higher 3 bytes of Destination MAC address */
  43957     case bcmPortControlE2EFCDestMacOui:
  43958         if (soc_feature(unit, soc_feature_e2efc)) {
  43959             uint32 val_lo, val_hi;
  43960             uint64 val_64, data_0;
  43961 #if defined(BCM_KATANA2_SUPPORT)
  43962             uint32 val;
  43963 #endif
  43964             soc_reg_t reg;
  43965 
  43966             if (!IS_HG_PORT(unit, port)) {
  43967                 LOG_ERROR(
  43968                     BSL_LS_BCM_PORT,
  43969                     (BSL_META_U(unit,
  43970                                 "Error: unit %d port %d is not a Higig port. "
  43971                                 "E2EFC messages can only be transmitted to "
  43972                                 "or received from Higig ports.\n"),
  43973                      unit, port));
  43974                 return BCM_E_PARAM;
  43975             }
  43976 #if defined(BCM_KATANA2_SUPPORT)
  43977             if (SOC_IS_KATANA2(unit)) {
  43978 #if defined(BCM_SABER2_SUPPORT)
  43979                 if (SOC_IS_SABER2(unit)) {
  43980                     /* Do nothing */
  43981                 } else
  43982 #endif /* BCM_SABER2_SUPPORT */
  43983                {
  43984                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  43985                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  43986                     val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8);
  43987                     soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi);
  43988                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val));
  43989                     rv = BCM_E_NONE;
  43990                     break;
  43991                }
  43992            }
  43993 #endif /* BCM_KATANA2_SUPPORT */
  43994             if (IS_XL_PORT(unit, port)) {
  43995                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  43996             } else if (IS_CL_PORT(unit, port)) {
  43997                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  43998             } else {
  43999                 return BCM_E_PARAM;
  44000             }
  44001             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  44002                                             0, &val_64));
  44003             data_0 = soc_reg64_field_get(unit, reg,
  44004                                          val_64, E2EFC_DATA_HDR_0f);
  44005             COMPILER_64_TO_32_LO(val_lo, data_0);
  44006             COMPILER_64_TO_32_HI(val_hi, data_0);
  44007             val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8);
  44008             COMPILER_64_SET(data_0, val_hi, val_lo);
  44009             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f,
  44010                                 data_0);
  44011             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  44012         }
  44013         break;
  44014     /* Lower 3 bytes of Destination MAC address */
  44015     case bcmPortControlE2EFCDestMacNonOui:
  44016         if (soc_feature(unit, soc_feature_e2efc)) {
  44017             uint32 val_lo, val_hi;
  44018             uint64 val_64, data_0;
  44019             soc_reg_t reg;
  44020 #if defined(BCM_KATANA2_SUPPORT)
  44021             uint32 val;
  44022 #endif
  44023 
  44024             if (!IS_HG_PORT(unit, port)) {
  44025                 LOG_ERROR(
  44026                     BSL_LS_BCM_PORT,
  44027                     (BSL_META_U(unit,
  44028                                 "Error: unit %d port %d is not a Higig port. "
  44029                                 "E2EFC messages can only be transmitted to "
  44030                                 "or received from Higig ports.\n"),
  44031                      unit, port));
  44032                 return BCM_E_PARAM;
  44033             }
  44034 #if defined(BCM_KATANA2_SUPPORT)
  44035             if (SOC_IS_KATANA2(unit)) {
  44036 #if defined(BCM_SABER2_SUPPORT)
  44037                 if (SOC_IS_SABER2(unit)) {
  44038                     /* Do nothing */
  44039                 } else
  44040 #endif /* BCM_SABER2_SUPPORT */
  44041                {
  44042                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  44043                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  44044                     val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  44045                     soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo);
  44046                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val));
  44047 
  44048                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  44049                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  44050                     val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff);
  44051                     soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi);
  44052                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val));
  44053                     rv = BCM_E_NONE;
  44054                     break;
  44055                }
  44056            }
  44057 #endif /* BCM_KATANA2_SUPPORT */
  44058             if (IS_XL_PORT(unit, port)) {
  44059                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  44060             } else if (IS_CL_PORT(unit, port)) {
  44061                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  44062             } else {
  44063                 return BCM_E_PARAM;
  44064             }
  44065             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  44066                                             0, &val_64));
  44067             data_0 = soc_reg64_field_get(unit, reg,
  44068                                          val_64, E2EFC_DATA_HDR_0f);
  44069             COMPILER_64_TO_32_LO(val_lo, data_0);
  44070             COMPILER_64_TO_32_HI(val_hi, data_0);
  44071             val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff);
  44072             val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  44073             COMPILER_64_SET(data_0, val_hi, val_lo);
  44074             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f,
  44075                                 data_0);
  44076             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  44077         }
  44078         break;
  44079     /* Higher 3 bytes of Source MAC address */
  44080     case bcmPortControlE2EFCSrcMacOui:
  44081         if (soc_feature(unit, soc_feature_e2efc)) {
  44082             uint32 val_lo, val_hi;
  44083             uint64 val_64, data_1, data_0;
  44084             soc_reg_t reg_1, reg_0;
  44085 #if defined(BCM_KATANA2_SUPPORT)
  44086             uint32 val;
  44087 #endif
  44088             if (!IS_HG_PORT(unit, port)) {
  44089                 LOG_ERROR(
  44090                     BSL_LS_BCM_PORT,
  44091                     (BSL_META_U(unit,
  44092                                 "Error: unit %d port %d is not a Higig port. "
  44093                                 "E2EFC messages can only be transmitted to "
  44094                                 "or received from Higig ports.\n"),
  44095                      unit, port));
  44096                 return BCM_E_PARAM;
  44097             }
  44098 #if defined(BCM_KATANA2_SUPPORT)
  44099             if (SOC_IS_KATANA2(unit)) {
  44100 #if defined(BCM_SABER2_SUPPORT)
  44101                 if (SOC_IS_SABER2(unit)) {
  44102                     /* Do nothing */
  44103                 } else
  44104 #endif /* BCM_SABER2_SUPPORT */
  44105                {
  44106                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  44107                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  44108                     val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff);
  44109                     soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo);
  44110                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val));
  44111 
  44112                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  44113                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  44114                     val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24);
  44115                     soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi);
  44116                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val));
  44117                     rv = BCM_E_NONE;
  44118                     break;
  44119                }
  44120            }
  44121 #endif /* BCM_KATANA2_SUPPORT */
  44122             if (IS_XL_PORT(unit, port)) {
  44123                 reg_1 = XLMAC_E2EFC_DATA_HDR_1r;
  44124                 reg_0 = XLMAC_E2EFC_DATA_HDR_0r;
  44125             } else if (IS_CL_PORT(unit, port)) {
  44126                 reg_1 = CLMAC_E2EFC_DATA_HDR_1r;
  44127                 reg_0 = CLMAC_E2EFC_DATA_HDR_0r;
  44128             } else {
  44129                 return BCM_E_PARAM;
  44130             }
  44131 
  44132             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, port,
  44133                                             0, &val_64));
  44134             data_1 = soc_reg64_field_get(unit, reg_1,
  44135                                          val_64, E2EFC_DATA_HDR_1f);
  44136             COMPILER_64_TO_32_LO(val_lo, data_1);
  44137             COMPILER_64_TO_32_HI(val_hi, data_1);
  44138             val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24);
  44139             COMPILER_64_SET(data_1, val_hi, val_lo);
  44140             soc_reg64_field_set(unit, reg_1, &val_64, E2EFC_DATA_HDR_1f,
  44141                                 data_1);
  44142             BCM_IF_ERROR_RETURN(soc_reg64_set(unit, reg_1,  port, 0, val_64));
  44143             /* SA MAC setting across 2 registers */
  44144             COMPILER_64_ZERO(val_64);
  44145             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, port,
  44146                                             0, &val_64));
  44147             data_0 = soc_reg64_field_get(unit, reg_0,
  44148                                          val_64, E2EFC_DATA_HDR_0f);
  44149             COMPILER_64_TO_32_LO(val_lo, data_0);
  44150             COMPILER_64_TO_32_HI(val_hi, data_0);
  44151             val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff);
  44152             COMPILER_64_SET(data_0, val_hi, val_lo);
  44153             soc_reg64_field_set(unit, reg_0, &val_64, E2EFC_DATA_HDR_0f,
  44154                                 data_0);
  44155             rv = soc_reg64_set(unit, reg_0, port, 0, val_64);
  44156         }
  44157         break;
  44158     /* Lower 3 bytes of Source MAC address */
  44159     case bcmPortControlE2EFCSrcMacNonOui:
  44160         if (soc_feature(unit, soc_feature_e2efc)) {
  44161             uint32 val_lo, val_hi;
  44162             uint64 val_64, data_1;
  44163             soc_reg_t reg;
  44164 #if defined(BCM_KATANA2_SUPPORT)
  44165             uint32 val;
  44166 #endif
  44167             if (!IS_HG_PORT(unit, port)) {
  44168                 LOG_ERROR(
  44169                     BSL_LS_BCM_PORT,
  44170                     (BSL_META_U(unit,
  44171                                 "Error: unit %d port %d is not a Higig port. "
  44172                                 "E2EFC messages can only be transmitted to "
  44173                                 "or received from Higig ports.\n"),
  44174                      unit, port));
  44175                 return BCM_E_PARAM;
  44176             }
  44177 #if defined(BCM_KATANA2_SUPPORT)
  44178             if (SOC_IS_KATANA2(unit)) {
  44179 #if defined(BCM_SABER2_SUPPORT)
  44180                 if (SOC_IS_SABER2(unit)) {
  44181                     /* Do nothing */
  44182                 } else
  44183 #endif /* BCM_SABER2_SUPPORT */
  44184                {
  44185                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  44186                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  44187                     val_hi = (val_hi & 0xff000000) | (value & 0xffffff);
  44188                     soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi);
  44189                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val));
  44190                     rv = BCM_E_NONE;
  44191                     break;
  44192                }
  44193             }
  44194 #endif /* BCM_KATANA2_SUPPORT */
  44195             if (IS_XL_PORT(unit, port)) {
  44196                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  44197             } else if (IS_CL_PORT(unit, port)) {
  44198                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  44199             } else {
  44200                 return BCM_E_PARAM;
  44201             }
  44202             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  44203                                             0, &val_64));
  44204             data_1 = soc_reg64_field_get(unit, reg,
  44205                                          val_64, E2EFC_DATA_HDR_1f);
  44206             COMPILER_64_TO_32_LO(val_lo, data_1);
  44207             COMPILER_64_TO_32_HI(val_hi, data_1);
  44208             val_hi = (val_hi & 0xff000000) | (value & 0xffffff);
  44209             COMPILER_64_SET(data_1, val_hi, val_lo);
  44210             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  44211                                 data_1);
  44212 
  44213             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  44214         }
  44215         break;
  44216     case bcmPortControlE2EFCEtherType:
  44217         if (soc_feature(unit, soc_feature_e2efc)) {
  44218             uint32 val_lo, val_hi;
  44219             uint64 val_64, data_1;
  44220             soc_reg_t reg;
  44221 #if defined(BCM_KATANA2_SUPPORT)
  44222             uint32 val;
  44223 #endif
  44224             if (!IS_HG_PORT(unit, port)) {
  44225                 LOG_ERROR(
  44226                     BSL_LS_BCM_PORT,
  44227                     (BSL_META_U(unit,
  44228                                 "Error: unit %d port %d is not a Higig port. "
  44229                                 "E2EFC messages can only be transmitted to "
  44230                                 "or received from Higig ports.\n"),
  44231                      unit, port));
  44232                 return BCM_E_PARAM;
  44233             }
  44234 #if defined(BCM_KATANA2_SUPPORT)
  44235             if (SOC_IS_KATANA2(unit)) {
  44236 #if defined(BCM_SABER2_SUPPORT)
  44237                 if (SOC_IS_SABER2(unit)) {
  44238                     /* Do nothing */
  44239                 } else
  44240 #endif /* BCM_SABER2_SUPPORT */
  44241                {
  44242                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  44243                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  44244                     val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  44245                     soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo);
  44246                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val));
  44247                     rv = BCM_E_NONE;
  44248                     break;
  44249                }
  44250             }
  44251 #endif /* BCM_KATANA2_SUPPORT */
  44252             if (IS_XL_PORT(unit, port)) {
  44253                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  44254             } else if (IS_CL_PORT(unit, port)) {
  44255                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  44256             } else {
  44257                 return BCM_E_PARAM;
  44258             }
  44259 
  44260             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  44261                                             0, &val_64));
  44262             data_1 = soc_reg64_field_get(unit, reg,
  44263                                          val_64, E2EFC_DATA_HDR_1f);
  44264             COMPILER_64_TO_32_LO(val_lo, data_1);
  44265             COMPILER_64_TO_32_HI(val_hi, data_1);
  44266             val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  44267             COMPILER_64_SET(data_1, val_hi, val_lo);
  44268             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  44269                                 data_1);
  44270             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  44271         }
  44272         break;
  44273     case bcmPortControlE2EFCOpcode:
  44274         if (soc_feature(unit, soc_feature_e2efc)) {
  44275             uint32 val_lo, val_hi;
  44276             uint64 val_64, data_1;
  44277             soc_reg_t reg;
  44278 #if defined(BCM_KATANA2_SUPPORT)
  44279             uint32 val;
  44280 #endif
  44281 
  44282             if (!IS_HG_PORT(unit, port)) {
  44283                 LOG_ERROR(
  44284                     BSL_LS_BCM_PORT,
  44285                     (BSL_META_U(unit,
  44286                                 "Error: unit %d port %d is not a Higig port. "
  44287                                 "E2EFC messages can only be transmitted to "
  44288                                 "or received from Higig ports.\n"),
  44289                      unit, port));
  44290                 return BCM_E_PARAM;
  44291             }
  44292 #if defined(BCM_KATANA2_SUPPORT)
  44293             if (SOC_IS_KATANA2(unit)) {
  44294 #if defined(BCM_SABER2_SUPPORT)
  44295                 if (SOC_IS_SABER2(unit)) {
  44296                     /* Do nothing */
  44297                 } else
  44298 #endif /* BCM_SABER2_SUPPORT */
  44299                {
  44300                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  44301                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  44302                     val_lo = (val_lo & 0xffff0000) | (value & 0xffff);
  44303                     soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo);
  44304                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val));
  44305                     rv = BCM_E_NONE;
  44306                     break;
  44307                }
  44308             }
  44309 #endif /* BCM_KATANA2_SUPPORT */
  44310             if (IS_XL_PORT(unit, port)) {
  44311                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  44312             } else if (IS_CL_PORT(unit, port)) {
  44313                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  44314             } else {
  44315                 return BCM_E_PARAM;
  44316             }
  44317             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  44318                                             0, &val_64));
  44319             data_1 = soc_reg64_field_get(unit, reg,
  44320                                          val_64, E2EFC_DATA_HDR_1f);
  44321             COMPILER_64_TO_32_LO(val_lo, data_1);
  44322             COMPILER_64_TO_32_HI(val_hi, data_1);
  44323             val_lo = (val_lo & 0xffff0000) | (value & 0xffff);
  44324             COMPILER_64_SET(data_1, val_hi, val_lo);
  44325             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  44326                                 data_1);
  44327             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  44328         }
  44329         break;
  44330     case bcmPortControlResetSerdes:
  44331 
  44332 
  44333 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT)
  44334         if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWKPLUS(unit)) {
  44335             rv = soc_th_reset_serdes(unit, port, value);
  44336 
  44337         } else
  44338 #endif
  44339 
  44340 #if defined(BCM_HURRICANE3_SUPPORT)
  44341         if (SOC_IS_HURRICANE3(unit)) {
  44342             rv = soc_hurricane3_tsc_core_reset(unit, port, value);
  44343         } else
  44344 #endif
  44345         {
  44346             rv = BCM_E_UNAVAIL;
  44347         }
  44348         break;
  44349     case bcmPortControlIntEnable:
  44350 #if defined(BCM_TOMAHAWK3_SUPPORT)
  44351         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  44352             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, INT_ENABLEf, value);
  44353         }
  44354 #endif
  44355         break;
  44356     case bcmPortControlIntTurnaround:
  44357 #if defined(BCM_TOMAHAWK3_SUPPORT)
  44358         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  44359             SOC_IF_ERROR_RETURN
  44360                 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  44361                                      &int_turnaround_en_bmap_entry));
  44362             soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm,
  44363                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  44364             if (value)
  44365                 SOC_PBMP_PORT_ADD(pbmp, port);
  44366             else
  44367                 SOC_PBMP_PORT_REMOVE(pbmp, port);
  44368 
  44369             soc_mem_pbmp_field_set(unit, INT_TURNAROUND_EN_BMAPm,
  44370                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  44371             SOC_IF_ERROR_RETURN
  44372                 (WRITE_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  44373                                       &int_turnaround_en_bmap_entry));
  44374             rv = BCM_E_NONE;
  44375         }
  44376 #endif
  44377         break;
  44378     case bcmPortControlObmClassifierPriority:
  44379     case bcmPortControlObmClassifierEnableDscp:
  44380     case bcmPortControlObmClassifierEnableMpls:
  44381     case bcmPortControlObmClassifierEnableEtag:
  44382     case bcmPortControlObmClassifierEtagEthertype:
  44383     case bcmPortControlObmClassifierVntagEthertype:
  44384 
  44385 #if defined(BCM_MONTEREY_SUPPORT)
  44386         if (SOC_IS_MONTEREY(unit)) {
  44387             rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value);
  44388         } else
  44389 #endif
  44390 #if defined(BCM_APACHE_SUPPORT)
  44391         if (SOC_IS_APACHE(unit)) {
  44392             rv = bcm_apache_obm_classifier_port_control_set(unit, port, type, value);
  44393         } else
  44394 #endif
  44395 #if defined(BCM_HELIX5_SUPPORT)
  44396         if (SOC_IS_HELIX5(unit)) {
  44397             rv = bcm_hx5_obm_classifier_port_control_set(unit, port, type, value);
  44398         } else
  44399 #endif
  44400 #if defined(BCM_TRIDENT3_SUPPORT)
  44401         if (soc_feature(unit, soc_feature_td3_style_obm_classifier_map)) {
  44402             rv = bcm_td3_obm_classifier_port_control_set(unit, port, type, value);
  44403         } else
  44404 #endif
  44405         {
  44406             rv = BCM_E_UNAVAIL;
  44407         }
  44408         break;
  44409     case bcmPortControlObmClassifierInternal:
  44410 #if defined(BCM_MONTEREY_SUPPORT)
  44411         if (SOC_IS_MONTEREY(unit)) {
  44412             rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value);
  44413         } else
  44414 #endif
  44415         {
  44416             rv = BCM_E_UNAVAIL;
  44417         }
  44418         break;
  44419 
  44420    case bcmPortControlWirelessCosMapSelect:
  44421 #if defined(BCM_HELIX5_SUPPORT)
  44422         if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit)) {
  44423             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  44424                                        WIRED_WIRELESSf, (value) ? 1 : 0);
  44425         } else
  44426 #endif
  44427         {
  44428            rv = BCM_E_UNAVAIL;
  44429         }
  44430     break;
  44431 
  44432    case bcmPortControlHiGigCosSelect:
  44433 #if defined(BCM_HURRICANE4_SUPPORT)
  44434         if (SOC_IS_HURRICANE4(unit)) {
  44435             rv = bcm_hr4_hgcos_select_port_control_set(unit, port, type, value);
  44436         } else
  44437 #endif
  44438 #if defined(BCM_HELIX5_SUPPORT)
  44439         if (SOC_IS_HELIX5(unit)) {
  44440             rv = bcm_hx5_hgcos_select_port_control_set(unit, port, type, value);
  44441         } else
  44442 #endif
  44443         {
  44444            rv = BCM_E_UNAVAIL;
  44445         }
  44446     break;
  44447     case bcmPortControlInternalLoopback:
  44448 #ifdef BCM_TRIDENT3_SUPPORT
  44449         if (SOC_IS_TRIDENT3X(unit)) {
  44450             rv = bcmi_td3_port_internal_loopback_set(unit,port,value);
  44451 
  44452         } else
  44453 #endif
  44454         {
  44455             rv = BCM_E_UNAVAIL;
  44456         }
  44457         break;
  44458 #ifdef BCM_MONTEREY_SUPPORT
  44459     case bcmPortControlObmInterruptTypeDropPreempt :
  44460     case bcmPortControlObmInterruptTypeOverflowPreempt :
  44461     case bcmPortControlObmInterruptTypeDropExpress :
  44462     case  bcmPortControlObmInterruptTypeOverflowExpress :
  44463         if (SOC_IS_MONTEREY(unit)) {
  44464             rv = bcm_mn_obm_interrupt_port_control_set(unit, port, type, value);
  44465 
  44466         } else
  44467 #endif
  44468         {
  44469             rv = BCM_E_UNAVAIL;
  44470         }
  44471         break;
  44472     case bcmPortControlRuntThreshold:
  44473         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  44474                              SOC_MAC_CONTROL_RX_RUNT_THRESHOLD, value);
  44475         break;
  44476     case bcmPortControlPacketProcssingPort:
  44477 #ifdef BCM_TRIDENT3_SUPPORT
  44478         if (soc_feature(unit, soc_feature_pp_port_control)) {
  44479             rv = bcmi_td3_port_pp_num_set(unit, port, value);
  44480         } else
  44481 #endif /* BCM_TRIDENT3_SUPPORT */
  44482         {
  44483             rv = BCM_E_UNAVAIL;
  44484         }
  44485         break;
  44486     default:
  44487         break;
  44488     }
  44489     return rv;
  44490 }
  44491 
  44492 
  44493 /*
  44494  * Function:
  44495  *      bcm_esw_port_control_get
  44496  * Description:
  44497  *      Get the status of specified port feature.
  44498  * Parameters:
  44499  *      unit - Device number
  44500  *      port - Port number
  44501  *      type - Enum  value of the feature
  44502  *      value - (OUT) Current value of the port feature
  44503  * Return Value:
  44504  *      BCM_E_NONE
  44505  *      BCM_E_UNAVAIL - Functionality not available
  44506  */
  44507 int
  44508 bcm_esw_port_control_get(int unit, bcm_port_t port,
  44509                          bcm_port_control_t type, int *value)
  44510 {
  44511     int rv = BCM_E_UNAVAIL;
  44512     int valid = 0;
  44513 #if defined(BCM_SHADOW_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  44514     uint32 val = 0;
  44515 #endif /* BCM_SHADOW_SUPPORT || BCM_GREYHOUND_SUPPORT */
  44516 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44517     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  44518                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  44519 #endif
  44520 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  44521     int udp;
  44522     int tcp;
  44523     int enable;
  44524 #endif
  44525     source_vp_entry_t svp_entry;
  44526 #if defined(BCM_TOMAHAWK3_SUPPORT)
  44527 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry;
  44528 bcm_pbmp_t  pbmp;
  44529 #endif
  44530     if (value == NULL) {
  44531         return BCM_E_PARAM;
  44532     }
  44533 
  44534     /* Make sure port module is initialized. */
  44535     PORT_INIT(unit);
  44536 
  44537     if(bcm_common_oamp_port_enable_get(unit, port) &&
  44538             (type != bcmPortControlSatEnable)) {
  44539         LOG_ERROR(BSL_LS_BCM_PORT,
  44540                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  44541                    port));
  44542         return BCM_E_PARAM;
  44543     }
  44544 
  44545     /* Call Port Control module */
  44546     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  44547         /*
  44548          * Check that port control feature is valid in Port Control.
  44549          * If valid, call Port Control routine to handle feature; otherwise
  44550          * continue with rest of logic.
  44551          */
  44552         BCM_IF_ERROR_RETURN
  44553             (bcmi_esw_portctrl_control_validate(unit, type, &valid));
  44554         if (valid) {
  44555             return bcmi_esw_portctrl_control_get(unit, port, type, value);
  44556         }
  44557     }
  44558 
  44559 #if defined(BCM_SHADOW_SUPPORT)
  44560     if (SOC_IS_SHADOW(unit)) {
  44561         /*  If unsupported port control type, return unavail */
  44562         if (!_bcm_port_type_shadow_support (unit, port, type)) {
  44563             return BCM_E_UNAVAIL;
  44564         }
  44565     }
  44566 #endif /* BCM_SHADOW_SUPPORT */
  44567 
  44568     if (type == bcmPortControlEsmEligibility) {
  44569 #ifdef BCM_TRIUMPH3_SUPPORT
  44570         /* For bcmPortControlEsmEligibility, a non-local port
  44571          * is accepted. For other port controls, a non-local
  44572          * port is not accepted. Hence, bcmPortControlEsmEligibility
  44573          * is implemented here, before the _bcm_esw_port_gport_validate
  44574          * procedure below.
  44575          */
  44576         return bcm_tr3_port_esm_eligible_get(unit, port, value);
  44577 #endif /* BCM_TRIUMPH3_SUPPORT */
  44578     }
  44579 
  44580 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  44581     if (
  44582 #ifdef BCM_HGPROXY_COE_SUPPORT
  44583         ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  44584             soc_feature(unit, soc_feature_channelized_switching)) &&
  44585          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  44586          ((type == bcmPortControlVlanVpGroupIngress) ||
  44587           (type == bcmPortControlVlanVpGroupEgress))) ||
  44588 #endif
  44589         BCM_GPORT_IS_TRUNK(port) ||
  44590         BCM_GPORT_IS_VLAN_PORT(port) ||
  44591         BCM_GPORT_IS_NIV_PORT(port) ||
  44592         BCM_GPORT_IS_VXLAN_PORT(port) ||
  44593         BCM_GPORT_IS_MIM_PORT(port) ||
  44594         BCM_GPORT_IS_MPLS_PORT(port) ||
  44595         BCM_GPORT_IS_L2GRE_PORT(port) ||
  44596         BCM_GPORT_IS_FLOW_PORT(port) ||
  44597         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  44598         return bcm_td_vp_control_get(unit, port, type, value);
  44599     } else
  44600 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  44601 #if defined(BCM_KATANA2_SUPPORT)
  44602     if (((BCM_GPORT_IS_MIM_PORT(port)) ||
  44603          (BCM_GPORT_IS_MPLS_PORT(port))) && SOC_IS_KATANA2(unit)) {
  44604         rv = BCM_E_NONE;
  44605     } else
  44606 #endif /* BCM_KATANA2_SUPPORT */
  44607     if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) ||
  44608         (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) {
  44609         rv = BCM_E_NONE;
  44610     } else
  44611 #ifdef BCM_HGPROXY_COE_SUPPORT
  44612     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  44613         soc_feature(unit, soc_feature_channelized_switching)) &&
  44614         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  44615         rv = BCM_E_NONE;
  44616     } else
  44617 #endif
  44618 #ifdef BCM_TRIDENT3_SUPPORT
  44619     if (soc_feature(unit, soc_feature_pp_port_control) &&
  44620         (type == bcmPortControlPacketProcssingPort) ) {
  44621         rv = BCM_E_NONE;
  44622     } else
  44623 #endif
  44624     {
  44625         rv = bcm_esw_port_control_validate(unit, port, type, &port);
  44626     }
  44627     BCM_IF_ERROR_RETURN(rv);
  44628     rv = BCM_E_UNAVAIL;
  44629 
  44630     /*
  44631      * At this point, 'port' can be:
  44632      *    GPORT WLAN
  44633      *    GPORT PROXY
  44634      *    BCM valid local port
  44635      *
  44636      * Some switch cases only handles 'port' in BCM port format
  44637      * (non-gport).  Corresponding checks must be added in those
  44638      * cases to ensure that 'port' is not a gport.
  44639      */
  44640     switch (type) {
  44641     case bcmPortControlBridge:
  44642         if (SOC_IS_XGS3_SWITCH(unit)) {
  44643             rv = _bcm_esw_port_tab_get(unit, port, PORT_BRIDGEf, value);
  44644         }
  44645         break;
  44646     case bcmPortControlTrunkHashSet:
  44647 #if defined(BCM_TRIUMPH3_SUPPORT)
  44648         if (SOC_IS_TRIUMPH3(unit)) {
  44649             return BCM_E_UNAVAIL;
  44650         } else
  44651 #endif /* BCM_TRIUMPH3_SUPPORT */
  44652         {
  44653 #if defined(BCM_BRADLEY_SUPPORT)
  44654             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  44655                 rv = _bcm_esw_port_tab_get(unit, port,
  44656                                            RTAG7_HASH_CFG_SEL_TRUNKf, value);
  44657             }
  44658 #endif /* BCM_BRADLEY_SUPPORT */
  44659         }
  44660         break;
  44661     case bcmPortControlFabricTrunkHashSet:
  44662 #if defined(BCM_TRIUMPH3_SUPPORT)
  44663         if (SOC_IS_TRIUMPH3(unit)) {
  44664             return BCM_E_UNAVAIL;
  44665         } else
  44666 #endif /* BCM_TRIUMPH3_SUPPORT */
  44667         {
  44668 #if defined(BCM_BRADLEY_SUPPORT)
  44669             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  44670                 rv = _bcm_esw_port_tab_get(unit, port,
  44671                                            RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf,
  44672                                            value);
  44673             }
  44674 #endif /* BCM_BRADLEY_SUPPORT */
  44675         }
  44676         break;
  44677     case bcmPortControlECMPHashSet:
  44678 #if defined(BCM_TRIUMPH3_SUPPORT)
  44679         if (SOC_IS_TRIUMPH3(unit)) {
  44680             return BCM_E_UNAVAIL;
  44681         } else
  44682 #endif /* BCM_TRIUMPH3_SUPPORT */
  44683         {
  44684 #if defined(BCM_BRADLEY_SUPPORT)
  44685             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  44686                 rv = _bcm_esw_port_tab_get(unit, port,
  44687                                            RTAG7_HASH_CFG_SEL_ECMPf, value);
  44688             }
  44689 #endif /* BCM_BRADLEY_SUPPORT */
  44690         }
  44691         break;
  44692     case bcmPortControlLoadBalanceHashSet:
  44693 #if defined(BCM_TRIUMPH3_SUPPORT)
  44694         if (SOC_IS_TRIUMPH3(unit)) {
  44695             return BCM_E_UNAVAIL;
  44696         } else
  44697 #endif /* BCM_TRIUMPH3_SUPPORT */
  44698         {
  44699 #if defined(BCM_BRADLEY_SUPPORT)
  44700             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  44701                 rv = _bcm_esw_port_tab_get(unit, port,
  44702                                            RTAG7_HASH_CFG_SEL_LBIDf, value);
  44703             }
  44704 #endif /* BCM_BRADLEY_SUPPORT */
  44705         }
  44706         break;
  44707     case bcmPortControlLoadBalancingNumber:
  44708 #if defined(BCM_BRADLEY_SUPPORT)
  44709         if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  44710             rv = _bcm_esw_port_tab_get(unit, port,
  44711                                        RTAG7_PORT_LBNf, value);
  44712         }
  44713 #endif /* BCM_BRADLEY_SUPPORT */
  44714         break;
  44715     case bcmPortControlErrorSymbolDetect:
  44716 #if defined(BCM_GREYHOUND_SUPPORT)
  44717         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  44718             SOC_IS_GREYHOUND2(unit)) {
  44719             rv = BCM_E_UNAVAIL;
  44720         } else
  44721 #endif /* BCM_GREYHOUND_SUPPORT */
  44722         {
  44723 #ifdef BCM_XGS3_SWITCH_SUPPORT
  44724             if (SOC_IS_XGS3_SWITCH(unit)) {
  44725                  rv = _bcm_esw_port_err_sym_detect_get(unit, port, value);
  44726             }
  44727 #endif
  44728         }
  44729         break;
  44730     case bcmPortControlErrorSymbolCount:
  44731 #if defined(BCM_GREYHOUND_SUPPORT)
  44732         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  44733             SOC_IS_GREYHOUND2(unit)) {
  44734             rv = BCM_E_UNAVAIL;
  44735         } else
  44736 #endif /* BCM_GREYHOUND_SUPPORT */
  44737         {
  44738 #ifdef BCM_XGS3_SWITCH_SUPPORT
  44739             if (SOC_IS_XGS3_SWITCH(unit)) {
  44740                 rv = _bcm_esw_port_err_sym_count_get(unit, port, value);
  44741             }
  44742 #endif
  44743         }
  44744         break;
  44745     case bcmPortControlIP4:
  44746         if (SOC_IS_XGS3_SWITCH(unit)) {
  44747 #if defined(BCM_TRX_SUPPORT)
  44748             if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  44749                 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), V4L3_ENABLEf, value);
  44750             } else
  44751 #endif
  44752             {
  44753                 rv = _bcm_esw_port_tab_get(unit, port, V4L3_ENABLEf, value);
  44754             }
  44755         }
  44756         break;
  44757     case bcmPortControlIP6:
  44758         if (SOC_IS_XGS3_SWITCH(unit)) {
  44759             rv = _bcm_esw_port_tab_get(unit, port, V6L3_ENABLEf, value);
  44760         }
  44761         break;
  44762     case bcmPortControlIP4Mcast:
  44763         if (SOC_IS_XGS3_SWITCH(unit)) {
  44764             rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value);
  44765         }
  44766         break;
  44767     case bcmPortControlIP6Mcast:
  44768         if (SOC_IS_XGS3_SWITCH(unit)) {
  44769             rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value);
  44770         }
  44771         break;
  44772     case bcmPortControlIPMC4Ucast:
  44773         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  44774             rv = _bcm_esw_port_tab_get(unit, port,
  44775                     IPMCV4_UNICAST_MACDA_ENABLEf, value);
  44776         }
  44777         break;
  44778     case bcmPortControlIPMC6Ucast:
  44779         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  44780             rv = _bcm_esw_port_tab_get(unit, port,
  44781                     IPMCV6_UNICAST_MACDA_ENABLEf, value);
  44782         }
  44783         break;
  44784     case bcmPortControlIP4McastL2:
  44785 #if defined(BCM_TRX_SUPPORT)
  44786         if (SOC_IS_XGS3_SWITCH(unit)) {
  44787             if (SOC_IS_TD2_TT2(unit) &&
  44788                     soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  44789                                                          IPMCV4_L2_ENABLEf)) {
  44790                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  44791                                      IPMCV4_L2_ENABLEf, (uint32 *)value);
  44792             } else {
  44793                 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_L2_ENABLEf, value);
  44794             }
  44795         }
  44796 #endif /* BCM_TRX_SUPPORT */
  44797         break;
  44798     case bcmPortControlIP6McastL2:
  44799 #ifdef BCM_TRX_SUPPORT
  44800         if (SOC_IS_XGS3_SWITCH(unit)) {
  44801             if (SOC_IS_TD2_TT2(unit) &&
  44802                     soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  44803                                                          IPMCV6_L2_ENABLEf)) {
  44804                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  44805                                     IPMCV6_L2_ENABLEf, (uint32 *)value);
  44806             } else {
  44807                 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_L2_ENABLEf, value);
  44808             }
  44809         }
  44810 #endif
  44811         break;
  44812 
  44813     case bcmPortControlMpls:
  44814 #if defined(BCM_TRIUMPH_SUPPORT)
  44815         if (SOC_IS_XGS3_SWITCH(unit)) {
  44816             rv = _bcm_esw_port_tab_get(unit, port, MPLS_ENABLEf, value);
  44817         }
  44818 #endif
  44819         break;
  44820 
  44821     case bcmPortControlMacInMac:
  44822 #if defined(BCM_TRIUMPH2_SUPPORT)
  44823         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  44824             rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value);
  44825         }
  44826 #endif
  44827         break;
  44828 
  44829     case bcmPortControlMimUcastTermEnable:
  44830 #if defined(BCM_TRIUMPH2_SUPPORT)
  44831         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  44832             rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value);
  44833         }
  44834 #endif
  44835         break;
  44836 
  44837     case bcmPortControlMimMcastTermEnable:
  44838 #if defined(BCM_TRIUMPH2_SUPPORT)
  44839         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  44840             rv = _bcm_esw_port_tab_get(unit, port, MIM_MC_TERM_ENABLEf, value);
  44841         }
  44842 #endif
  44843         break;
  44844 
  44845     case bcmPortControlSrcBmacMissToCpu:
  44846 #ifdef BCM_TRIUMPH2_SUPPORT
  44847      if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  44848          SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  44849          SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit)) {
  44850          /* 0x2: ToCPU 0x1: Drop(default) */
  44851          rv = _bcm_esw_port_tab_get(unit, port, CML_BMAC_NEWf, value);
  44852          *value = (*value == 0x2) ? TRUE : FALSE;
  44853      }
  44854 #endif /* BCM_TRIUMPH2_SUPPORT */
  44855          break;
  44856 
  44857     case bcmPortControlQosRemarkResolution:
  44858 #ifdef BCM_TRIDENT3_SUPPORT
  44859         if (SOC_IS_TRIDENT3X(unit)) {
  44860             rv = _bcm_esw_egr_port_tab_get(unit, port, QOS_CTRL_IDf, value);
  44861             /* TD3 only supports 2 of the 4 valid hardware configurations for now.
  44862              * 1: Serial resolution.
  44863              * 3: Layered resolution.
  44864              * Other value: Invalid.
  44865              */
  44866             if (rv == BCM_E_NONE) {
  44867                 if (*value == 1) {
  44868                     *value = BCM_PORT_QOS_SERIAL_RESOLUTION;
  44869                 } else if (*value == 3) {
  44870                     *value = BCM_PORT_QOS_LAYERED_RESOLUTION;
  44871                 } else {
  44872                     return BCM_E_PARAM;
  44873                 }
  44874             }
  44875         }
  44876 #endif /* BCM_TRIDENT3_SUPPORT */
  44877          break;
  44878 
  44879     case bcmPortControlFabricQueue:
  44880 #if defined(BCM_TRIUMPH2_SUPPORT)
  44881         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44882         if (IS_ST_PORT(unit, port)) {
  44883             if  (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) {
  44884                 uint64 egr_val64;
  44885                 rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  44886                 if (BCM_SUCCESS(rv)) {
  44887                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  44888                                               egr_val64, EH_EXT_HDR_ENABLEf);
  44889                 }
  44890             }
  44891             else if(SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){
  44892                 egr_port_entry_t entry;
  44893                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port,
  44894                             &entry);
  44895                  if (BCM_SUCCESS(rv)) {
  44896                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  44897                                             EH_EXT_HDR_ENABLEf);
  44898                 }
  44899             }
  44900         } else {
  44901 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  44902             /* Allow CPU port on TD2+ to add extended header */
  44903             if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) {
  44904                 egr_port_entry_t entry;
  44905                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port,
  44906                             &entry);
  44907                  if (BCM_SUCCESS(rv)) {
  44908                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  44909                                             EH_EXT_HDR_ENABLEf);
  44910                 }
  44911             }
  44912 #endif
  44913 #if defined(BCM_TOMAHAWK_SUPPORT)
  44914             if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) {
  44915                 egr_port_entry_t entry;
  44916                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, &entry);
  44917                 if (BCM_SUCCESS(rv)) {
  44918                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  44919                                             EH_EXT_HDR_ENABLEf);
  44920                 }
  44921             }
  44922 #endif
  44923         }
  44924 #if defined(BCM_TRIDENT3_SUPPORT)
  44925         if (SOC_IS_TRIDENT3X(unit) &&
  44926             soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  44927             uint32 enable = 0;
  44928             rv = bcm_esw_port_egr_lport_field_get(
  44929                   unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf,
  44930                   &enable);
  44931             BCM_IF_ERROR_RETURN(rv);
  44932             *value = (enable) ? 1: 0;
  44933         }
  44934 #endif
  44935 #endif
  44936         break;
  44937     case bcmPortControlPassControlFrames:
  44938         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44939 #ifdef BCM_XGS_SWITCH_SUPPORT
  44940         if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) ||
  44941             (IS_GE_PORT(unit, port)
  44942              && soc_feature(unit, soc_feature_unified_port)) ||
  44943             (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) {
  44944             if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) {
  44945                 uint32 rval32 = 0;
  44946                 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32);
  44947                 if (BCM_SUCCESS(rv)) {
  44948                     /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved
  44949                      * the bit value needs to be reversed
  44950                      */
  44951                     *value = ((rval32 & 0x800) >> 11) ? 0 : 1 ;
  44952                 }
  44953             } else {
  44954                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44955                                      SOC_MAC_PASS_CONTROL_FRAME, value);
  44956             }
  44957         }
  44958 #endif
  44959         break;
  44960 #ifdef BCM_XGS3_SWITCH_SUPPORT
  44961     case bcmPortControlFilterLookup:
  44962 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  44963         rv = _bcm_esw_port_tab_get(unit, port, VFP_ENABLEf, value);
  44964 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  44965         break;
  44966     case bcmPortControlFilterIngress:
  44967 #if defined(BCM_TRX_SUPPORT)
  44968         if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  44969             rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value);
  44970         } else
  44971 #endif
  44972         if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  44973             rv = _bcm_esw_port_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value);
  44974         } else {
  44975             rv = _bcm_esw_port_tab_get(unit, port, FILTER_ENABLEf, value);
  44976         }
  44977         break;
  44978     case bcmPortControlFilterEgress:
  44979 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  44980         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44981         if (SOC_REG_FIELD_VALID(unit, EGR_PORTr, EFP_FILTER_ENABLEf)) {
  44982             uint32 egr_val;
  44983 
  44984             rv = READ_EGR_PORTr(unit, port, &egr_val);
  44985             if (BCM_SUCCESS(rv)) {
  44986                 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val,
  44987                                            EFP_FILTER_ENABLEf);
  44988             }
  44989         } else if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r,
  44990                                        EFP_FILTER_ENABLEf)) {
  44991             uint64 egr_val64;
  44992 
  44993             rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  44994             if (BCM_SUCCESS(rv)) {
  44995                 *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  44996                                                egr_val64,
  44997                                                EFP_FILTER_ENABLEf);
  44998             }
  44999         } else {
  45000             rv = _bcm_esw_egr_port_tab_get(unit, port, EFP_FILTER_ENABLEf, value);
  45001 
  45002         }
  45003 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  45004         break;
  45005     case bcmPortControlFrameSpacingStretch:
  45006         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45007         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45008                              SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, value);
  45009         break;
  45010     case bcmPortControlPreservePacketPriority:
  45011 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  45012         if (SOC_IS_TRIUMPH3(unit)) {
  45013             /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */
  45014             rv = _bcm_esw_port_tab_get(unit, port,
  45015                                        DOT1P_REMAP_POINTERf, value);
  45016             if (BCM_SUCCESS(rv)) {
  45017                /* True if pointed to default dot1p profile */
  45018                *value = (*value) ? 0 : 1;
  45019             }
  45020         } else {
  45021             rv = _bcm_esw_port_tab_get(unit, port, USE_INCOMING_DOT1Pf, value);
  45022         }
  45023 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  45024         break;
  45025     case bcmPortControlLearnClassEnable:
  45026 #if defined(BCM_TRX_SUPPORT)
  45027         if (soc_feature(unit, soc_feature_class_based_learning)) {
  45028             rv = _bcm_esw_port_tab_get(unit, port, CLASS_BASED_SM_ENABLEf,
  45029                                        value);
  45030         }
  45031 #endif /* BCM_TRX_SUPPORT */
  45032         break;
  45033     case bcmPortControlTrustIncomingVlan:
  45034 #if defined(BCM_TRIDENT3_SUPPORT)
  45035         if (SOC_IS_TRIDENT3X(unit)) {
  45036             uint32 tpid_enable;
  45037             rv = _bcm_fb2_port_tpid_enable_get(unit, port, &tpid_enable);
  45038             *value = tpid_enable ? 1 : 0;
  45039         } else
  45040 #endif
  45041 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  45042         {
  45043             rv = _bcm_esw_port_tab_get(unit, port, TRUST_INCOMING_VIDf, value);
  45044         }
  45045 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  45046         break;
  45047     case bcmPortControlDoNotCheckVlan:
  45048 #if defined(BCM_TRX_SUPPORT)
  45049         if (!SOC_IS_SHADOW(unit)) {
  45050 #if defined(BCM_TRIDENT3_SUPPORT)
  45051             if (SOC_IS_TRIDENT3X(unit)) {
  45052                 rv = _bcm_esw_port_tab_get(unit, port,
  45053                                            DISABLE_VLAN_CHECKSf, value);
  45054             } else
  45055 #endif
  45056             if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  45057                 if (CMIC_PORT(unit) == port) {
  45058                     rv = _bcm_esw_iport_tab_get(unit, port,
  45059                                                 DISABLE_VLAN_CHECKSf, value);
  45060                 } else {
  45061                     rv = _bcm_esw_port_tab_get(unit, port,
  45062                                                DISABLE_VLAN_CHECKSf, value);
  45063                 }
  45064             } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  45065                         DISABLE_VLAN_CHECKSf)) {
  45066 #if defined(BCM_KATANA2_SUPPORT)
  45067                 if (SOC_IS_KATANA2(unit)) {
  45068                     rv = _bcm_kt2_source_trunk_map_get(unit, port,
  45069                             DISABLE_VLAN_CHECKSf, (uint32 *)value);
  45070                 } else
  45071 #endif
  45072                 {
  45073                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  45074                             DISABLE_VLAN_CHECKSf, (uint32 *)value);
  45075                 }
  45076             }
  45077         }
  45078 #endif /* BCM_TRX_SUPPORT */
  45079           break;
  45080     case bcmPortControlDoNotCheckVlanFromCpu:
  45081 #if defined(BCM_TRX_SUPPORT)
  45082         if (!SOC_IS_SHADOW(unit)) {
  45083             if (CMIC_PORT(unit) == port) {
  45084                 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf) ||
  45085                     SOC_IS_TRIDENT3X(unit)) {
  45086                     rv = _bcm_esw_port_tab_get(unit, port,
  45087                                            DISABLE_VLAN_CHECKSf, value);
  45088                 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  45089                         DISABLE_VLAN_CHECKSf)) {
  45090                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  45091                         DISABLE_VLAN_CHECKSf, (uint32 *)value);
  45092                 }
  45093             } else {
  45094                 rv = BCM_E_PORT;
  45095             }
  45096         }
  45097 #endif /* BCM_TRX_SUPPORT */
  45098          break;
  45099     case bcmPortControlIEEE8021ASEnableIngress:
  45100 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_ENDURO_SUPPORT)
  45101         if (soc_feature(unit, soc_feature_rx_timestamp)) {
  45102             rv = _bcm_esw_port_tab_get(unit, port,
  45103                                        IEEE_802_1AS_ENABLEf, value);
  45104         }
  45105 #endif /* BCM_HAWKEYE_SUPPORT */
  45106         break;
  45107     case bcmPortControlIEEE8021ASEnableEgress:
  45108 #if defined(BCM_HAWKEYE_SUPPORT)
  45109         if (SOC_IS_HAWKEYE(unit)) {
  45110             uint32 egr_val;
  45111 
  45112             rv = READ_EGR_PORTr(unit, port, &egr_val);
  45113             if (BCM_SUCCESS(rv)) {
  45114                 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val,
  45115                                            IEEE_802_1AS_ENABLEf);
  45116             }
  45117         }
  45118 #endif /* BCM_HAWKEYE_SUPPORT */
  45119         break;
  45120     case bcmPortControlEgressVlanPriUsesPktPri:
  45121 #if defined(BCM_TRX_SUPPORT)
  45122 #if defined (BCM_HGPROXY_COE_SUPPORT)
  45123         if (!((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  45124             (soc_feature(unit, soc_feature_channelized_switching))) &&
  45125             BCM_GPORT_IS_SUBPORT_PORT(port)))
  45126 #endif
  45127         {
  45128             BCM_IF_ERROR_RETURN(
  45129                 _bcm_esw_port_gport_validate(unit, port, &port));
  45130         }
  45131         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  45132             uint32 val;
  45133 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  45134             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  45135                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  45136                     rv = bcm_esw_port_egr_lport_field_get(unit,
  45137                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf,
  45138                         (uint32 *)value);
  45139                     *value = *value ? 0 : 1;
  45140                 } else {
  45141 #if defined (BCM_HGPROXY_COE_SUPPORT)
  45142                     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  45143                         (soc_feature(unit, soc_feature_channelized_switching))) &&
  45144                         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  45145                         rv = bcm_esw_port_egr_lport_field_get(
  45146                                 unit, port, EGR_VLAN_CONTROL_1m,
  45147                                 REMARK_OUTER_DOT1Pf, (uint32 *)value);
  45148                         *value = *value ? 0 : 1;
  45149                     } else
  45150 #endif
  45151                     {
  45152                         egr_vlan_control_1_entry_t entry;
  45153                         rv = READ_EGR_VLAN_CONTROL_1m(
  45154                                 unit, MEM_BLOCK_ANY, port, &entry);
  45155                         if (BCM_SUCCESS(rv)) {
  45156                             *value = soc_EGR_VLAN_CONTROL_1m_field32_get(
  45157                                         unit, &entry,
  45158                                         REMARK_OUTER_DOT1Pf) ? 0 : 1;
  45159                         }
  45160                     }
  45161                 }
  45162             } else
  45163 #endif
  45164             {
  45165                 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val);
  45166                 if (BCM_SUCCESS(rv)) {
  45167                     *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val,
  45168                                                 REMARK_OUTER_DOT1Pf)) ? 0 : 1;
  45169                 }
  45170             }
  45171         }
  45172 #endif /* BCM_TRX_SUPPORT */
  45173         break;
  45174     case bcmPortControlEgressModifyDscp:
  45175 #if defined(BCM_TRX_SUPPORT)
  45176         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45177         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  45178             uint32 val;
  45179 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  45180             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  45181                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  45182                     rv = bcm_esw_port_egr_lport_field_get(unit,
  45183                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf,
  45184                         (uint32 *)value);
  45185                     *value = *value ? 1 : 0;
  45186                 } else {
  45187                     egr_vlan_control_1_entry_t entry;
  45188                     rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry);
  45189                     if (BCM_SUCCESS(rv)) {
  45190                         *value = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry,
  45191                                                 REMARK_OUTER_DSCPf) ? 1 : 0;
  45192                     }
  45193                 }
  45194             } else
  45195 #endif
  45196             {
  45197                 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val);
  45198                 if (BCM_SUCCESS(rv)) {
  45199                     *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val,
  45200                                                 REMARK_OUTER_DSCPf)) ? 1 : 0;
  45201                 }
  45202             }
  45203         }
  45204 #endif /* BCM_TRX_SUPPORT */
  45205         break;
  45206     case bcmPortControlIpfixRate:
  45207 #ifdef BCM_TRIUMPH2_SUPPORT
  45208         if (soc_feature(unit, soc_feature_ipfix_rate)) {
  45209             rv = _bcm_esw_port_tab_get(unit, port, IPFIX_FLOW_METER_IDf,
  45210                                        value);
  45211         }
  45212 #endif /* BCM_TRIUMPH2_SUPPORT */
  45213         break;
  45214     case bcmPortControlCustomerQueuing:
  45215         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45216 #ifdef BCM_ENDURO_SUPPORT
  45217         if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) {
  45218             return BCM_E_UNAVAIL;
  45219         }
  45220 #endif
  45221 #ifdef BCM_KATANA_SUPPORT
  45222         if (SOC_IS_KATANAX(unit)) {
  45223             uint32 rval, ing_cos_mode, rqe_cos_mode;
  45224             BCM_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  45225             ing_cos_mode = soc_reg_field_get(unit, ING_COS_MODEr, rval, COS_MODEf);
  45226             if (SOC_IS_KATANA(unit)) {
  45227                 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval));
  45228                 rqe_cos_mode = soc_reg_field_get(unit, RQE_PORT_CONFIGr, rval, COS_MODEf);
  45229             } else {
  45230                 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  45231                 rqe_cos_mode = soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval, COS_MODEf);
  45232             }
  45233             if ((ing_cos_mode != rqe_cos_mode) && (ing_cos_mode != 1)) {
  45234                 *value = 4;
  45235             } else {
  45236                 *value = ing_cos_mode;
  45237             }
  45238             rv = BCM_E_NONE;
  45239             break;
  45240         }
  45241 #endif /* BCM_KATANA_SUPPORT */
  45242 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  45243         if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKX(unit))) {
  45244             uint64 rval1;
  45245             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  45246                 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval1);
  45247                 BCM_IF_ERROR_RETURN(rv);
  45248                 *value = soc_reg64_field32_get(unit, ING_COS_MODEr, rval1,
  45249                                                COS_MODEf);
  45250             }
  45251 
  45252             if (SOC_MEM_IS_VALID(unit, ING_COS_MODEm)) {
  45253                ing_cos_mode_entry_t entry;
  45254                rv = soc_mem_read(unit, ING_COS_MODEm, MEM_BLOCK_ANY, port, &entry);
  45255                BCM_IF_ERROR_RETURN(rv);
  45256                *value = soc_mem_field32_get(unit, ING_COS_MODEm, &entry, COS_MODEf);
  45257             }
  45258 
  45259             break;
  45260         }
  45261 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK_SUPPORT */
  45262 #ifdef BCM_TRIDENT2_SUPPORT
  45263         if (SOC_IS_TD2_TT2(unit)) {
  45264             uint64 rval;
  45265             rv = READ_ING_COS_MODE_64r(unit, port, &rval);
  45266             BCM_IF_ERROR_RETURN(rv);
  45267 
  45268             if (SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) {
  45269                 *value = soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval,
  45270                                                QUEUE_MODEf);
  45271                 break;
  45272             }
  45273         }
  45274 #endif /* BCM_TRIDENT2_SUPPORT */
  45275 #ifdef BCM_TRIUMPH2_SUPPORT
  45276         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  45277             uint32 rval;
  45278             soc_field_t field;
  45279             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  45280                 rv = READ_ING_COS_MODEr(unit, port, &rval);
  45281                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) {
  45282                     field = SELECTf;
  45283                 } else if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr,
  45284                                                QUEUE_MODEf)) {
  45285                     field = QUEUE_MODEf;
  45286                 } else {
  45287                     rv = BCM_E_UNAVAIL;
  45288                     break;
  45289                 }
  45290                 if (SOC_IS_TRIUMPH3(unit)) {
  45291                     *value = soc_reg_field_get(unit, ING_COS_MODEr, rval, field);
  45292                 } else {
  45293                     if (soc_reg_field_get(unit, ING_COS_MODEr, rval, field)
  45294                         == 3) {
  45295                         *value = 1;
  45296                     } else {
  45297                         *value = 0;
  45298                     }
  45299                 }
  45300             }
  45301         }
  45302 #endif /* BCM_TRIUMPH2_SUPPORT */
  45303         break;
  45304 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  45305 
  45306 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT)
  45307     case bcmPortControlOAMEnable:
  45308         rv = _bcm_esw_port_tab_get(unit, port, OAM_ENABLEf, value);
  45309         break;
  45310 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */
  45311 
  45312 #if defined (BCM_OLP_SUPPORT)
  45313     case bcmPortControlOlpEnable:
  45314         if (soc_feature(unit, soc_feature_olp)) {
  45315             bcm_module_t module_id = 0;
  45316             bcm_module_t my_modid;
  45317             bcm_port_t port_id;
  45318             bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  45319             int         local_id;
  45320 
  45321             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  45322 
  45323             if (BCM_GPORT_IS_SET(port)) {
  45324                 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id,
  45325                             &port_id, &trunk_id, &local_id));
  45326 
  45327 #if defined(BCM_KATANA2_SUPPORT)
  45328                 if (SOC_IS_KATANA2(unit) &&
  45329                         (BCM_GPORT_IS_SUBPORT_PORT(port)) &&
  45330                         ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
  45331                          (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) {
  45332 
  45333                     LOG_ERROR(BSL_LS_BCM_L2,
  45334                             (BSL_META_U(unit,
  45335                                         "OLP is not allowed on SUBPORT. \
  45336                                         \n")));
  45337                     return BCM_E_PARAM;
  45338                 }
  45339 #endif
  45340             } else {
  45341                 port_id = port;
  45342             }
  45343             if ((module_id == 0) || (module_id == my_modid)) {
  45344 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  45345                 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  45346                     iarb_ing_port_table_entry_t entry;
  45347 
  45348                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm,
  45349                                         MEM_BLOCK_ANY, port_id, &entry));
  45350                     *value = soc_IARB_ING_PORT_TABLEm_field32_get(unit,
  45351                                                             &entry, OLP_ENABLEf);
  45352 
  45353                 } else
  45354 #endif
  45355                 {
  45356                     iarb_ing_physical_port_entry_t entry;
  45357                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm,
  45358                                          MEM_BLOCK_ANY, port_id, &entry));
  45359                     *value = soc_IARB_ING_PHYSICAL_PORTm_field32_get(unit,
  45360                                                         &entry, OLP_ENABLEf);
  45361                 }
  45362             }
  45363             rv = BCM_E_NONE;
  45364         }
  45365         break;
  45366 #endif /* BCM_OLP_SUPPORT*/
  45367 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
  45368 
  45369     case bcmPortControlPortMacOui:
  45370     case bcmPortControlPortMacNonOui:
  45371 
  45372         /*
  45373          * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed
  45374          * by either of bcm_l2_station_xxx API or  bcm_switch_olp_l2_addr_xxx
  45375          *
  45376          * Use either of two set of APIs
  45377          */
  45378 
  45379         if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) {
  45380             LOG_VERBOSE(BSL_LS_BCM_L2,
  45381                         (BSL_META_U(unit,
  45382                                     "use bcm_l2_station_xxx API\n")));
  45383             return BCM_E_UNAVAIL;
  45384         }
  45385         _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API);
  45386 
  45387 #if defined(BCM_KATANA2_SUPPORT)
  45388         if (SOC_IS_KATANA2(unit) &&
  45389                  (soc_feature(unit, soc_feature_oam)  ||
  45390                   soc_feature(unit, soc_feature_sat))) {
  45391 
  45392             uint32 val_lo, val_hi;
  45393             uint64 mac_field;
  45394 
  45395             PORT_LOCK(unit);
  45396 
  45397             rv = _bcm_kt2_port_mac_get(unit, port, &mac_field);
  45398             if (BCM_FAILURE(rv)) {
  45399                 PORT_UNLOCK(unit);
  45400                 return (rv);
  45401             }
  45402             COMPILER_64_TO_32_LO(val_lo, mac_field);
  45403             COMPILER_64_TO_32_HI(val_hi, mac_field);
  45404 
  45405             switch (type) {
  45406                 case bcmPortControlPortMacOui:
  45407                     *value = 0xffffff & ((val_hi << 8) | ((val_lo >> 24) & 0xff));
  45408                     break;
  45409 
  45410                 case bcmPortControlPortMacNonOui:
  45411                     *value = (val_lo & 0xffffff);
  45412                     break;
  45413                 default:
  45414                      break;
  45415             }
  45416             PORT_UNLOCK(unit);
  45417 
  45418             rv = BCM_E_NONE;
  45419         }
  45420 #endif /* BCM_KATANA2_SUPPORT */
  45421 
  45422 #if defined(BCM_MONTEREY_SUPPORT)
  45423         if (SOC_IS_MONTEREY(unit)) {
  45424             uint32 mac;
  45425 
  45426             PORT_LOCK(unit);
  45427             rv = _bcm_monterey_port_mac_get(unit,
  45428                                           port,
  45429                                           type == bcmPortControlPortMacOui,
  45430                                           &mac);
  45431             PORT_UNLOCK(unit);
  45432 
  45433             *value = mac;
  45434         }
  45435 #endif
  45436 #if defined(BCM_APACHE_SUPPORT)
  45437         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  45438             uint32 mac;
  45439 
  45440             PORT_LOCK(unit);
  45441             rv = _bcm_apache_port_mac_get(unit,
  45442                                           port,
  45443                                           type == bcmPortControlPortMacOui,
  45444                                           &mac);
  45445             PORT_UNLOCK(unit);
  45446 
  45447             *value = mac;
  45448         }
  45449 #endif /* BCM_APACHE_SUPPORT */
  45450         break;
  45451 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT*/
  45452 
  45453 #ifdef BCM_TRX_SUPPORT
  45454      case bcmPortControlOamLoopback:
  45455         if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit)
  45456             && !SOC_IS_SHADOW(unit))
  45457         {
  45458             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45459             if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr,
  45460                                     OAM_DO_NOT_MODIFYf)) {
  45461                 uint32 reg_value;
  45462 
  45463                 rv = READ_ING_MISC_PORT_CONFIGr(unit, port, &reg_value);
  45464 
  45465                 if (SOC_SUCCESS(rv)) {
  45466                     *value = soc_reg_field_get(unit, ING_MISC_PORT_CONFIGr,
  45467                                                reg_value, OAM_DO_NOT_MODIFYf);
  45468                 }
  45469             } else {
  45470                 return BCM_E_UNAVAIL;
  45471             }
  45472         }
  45473 
  45474         break;
  45475 #endif /* BCM_TRX_SUPPORT */
  45476 
  45477     case bcmPortControlLanes:
  45478         if (soc_feature(unit, soc_feature_flexport_no_legacy)) {
  45479             return BCM_E_UNAVAIL;
  45480         }
  45481         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45482 #if defined(BCM_TRIUMPH2_SUPPORT)
  45483         if (soc_feature(unit, soc_feature_flex_port)) {
  45484 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  45485             if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) {
  45486                 rv = bcmi_xgs5_port_lanes_get(unit, port, value);
  45487             } else
  45488 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  45489 #if defined(BCM_ENDURO_SUPPORT)
  45490             if (SOC_IS_ENDURO(unit)) {
  45491                 rv = _bcm_en_port_lanes_get(unit, port, value);
  45492             } else
  45493 #endif
  45494 #if defined(BCM_HURRICANE1_SUPPORT)
  45495             if (SOC_IS_HURRICANE(unit)) {
  45496                 rv = _bcm_hu_port_lanes_get(unit, port, value);
  45497             } else
  45498 #endif
  45499 #if defined(BCM_HURRICANE2_SUPPORT)
  45500             if (SOC_IS_HURRICANE2(unit)) {
  45501                 rv = soc_hurricane2_port_lanes_get(unit, port, value);
  45502             } else
  45503 #endif
  45504 #if defined(BCM_MONTEREY_SUPPORT)
  45505             if (SOC_IS_MONTEREY(unit)) {
  45506                 rv = bcmi_monterey_port_lanes_get(unit, port, value);
  45507             } else
  45508 #endif
  45509 #if defined(BCM_APACHE_SUPPORT)
  45510             if (SOC_IS_APACHE(unit)) {
  45511                 rv = bcmi_apache_port_lanes_get(unit, port, value);
  45512             } else
  45513 #endif
  45514 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  45515             if (SOC_IS_TD2P_TT2P(unit)) {
  45516                 rv = bcmi_td2p_port_lanes_get(unit, port, value);
  45517             } else
  45518 #endif
  45519 #if defined(BCM_TRIDENT2_SUPPORT)
  45520             if (SOC_IS_TD2_TT2(unit)) {
  45521                 rv = soc_trident2_port_lanes_get(unit, port, value);
  45522             } else
  45523 #endif /* BCM_TRIDENT2_SUPPORT */
  45524 #ifdef BCM_TRIDENT_SUPPORT
  45525             if (SOC_IS_TD_TT(unit)) {
  45526                 if (!SOC_PORT_VALID(unit, port)) {
  45527                     return BCM_E_PORT;
  45528                 }
  45529                 /* coverity[overrun-local : FALSE] */
  45530                 *value = SOC_INFO(unit).port_num_lanes[port];
  45531                 rv = BCM_E_NONE;
  45532             } else
  45533 #endif /* BCM_TRIDENT_SUPPORT */
  45534 #ifdef BCM_SHADOW_SUPPORT
  45535             if (SOC_IS_SHADOW(unit)) {
  45536                 if (!SOC_PORT_VALID(unit, port)) {
  45537                     return BCM_E_PORT;
  45538                 }
  45539                 /* coverity[overrun-local : FALSE] */
  45540                 *value = SOC_INFO(unit).port_num_lanes[port];
  45541                 rv = BCM_E_NONE;
  45542             } else
  45543 #endif /* BCM_SHADOW_SUPPORT */
  45544 #ifdef BCM_TRIUMPH3_SUPPORT
  45545             if (SOC_IS_TRIUMPH3(unit)) {
  45546                 rv = _bcm_tr3_port_lanes_get(unit, port, value);
  45547             } else
  45548 #endif /* BCM_TRIUMPH3_SUPPORT */
  45549 #ifdef BCM_METROLITE_SUPPORT
  45550             if (SOC_IS_METROLITE(unit)) {
  45551                 rv = _bcm_ml_port_lanes_get(unit, port, value);
  45552             } else
  45553 #endif /* BCM_METROLITE_SUPPORT */
  45554 #ifdef BCM_SABER2_SUPPORT
  45555             if (SOC_IS_SABER2(unit)) {
  45556                 rv = _bcm_sb2_port_lanes_get(unit, port, value);
  45557             } else
  45558 #endif /* BCM_SABER2_SUPPORT */
  45559 #ifdef BCM_KATANA2_SUPPORT
  45560             if (SOC_IS_KATANA2(unit)) {
  45561                 rv = _bcm_kt2_port_lanes_get(unit, port, value);
  45562             } else
  45563 #endif /* BCM_KATANA2_SUPPORT */
  45564             {
  45565                 rv = _bcm_tr2_port_lanes_get(unit, port, value);
  45566             }
  45567         }
  45568 #endif
  45569         break;
  45570     case bcmPortControlPFCEthertype:
  45571 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45572         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45573             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45574             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45575                 /* IS_GX_PORT == IS_XL_PORT */
  45576                 return BCM_E_PORT;
  45577             }
  45578             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45579                                  SOC_MAC_CONTROL_PFC_TYPE, value);
  45580         }
  45581 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45582           break;
  45583     case bcmPortControlPFCOpcode:
  45584 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45585         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45586             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45587             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45588                 /* IS_GX_PORT == IS_XL_PORT */
  45589                 return BCM_E_PORT;
  45590             }
  45591             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45592                                  SOC_MAC_CONTROL_PFC_OPCODE, value);
  45593         }
  45594 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45595           break;
  45596     case bcmPortControlPFCReceive:
  45597 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45598         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45599             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45600             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45601                 /* IS_GX_PORT == IS_XL_PORT */
  45602                 return BCM_E_PORT;
  45603             }
  45604             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45605                                  SOC_MAC_CONTROL_PFC_RX_ENABLE, value);
  45606         }
  45607 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45608           break;
  45609     case bcmPortControlPFCTransmit:
  45610 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45611         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45612             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45613             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45614                 /* IS_GX_PORT == IS_XL_PORT */
  45615                 return BCM_E_PORT;
  45616             }
  45617             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45618                                  SOC_MAC_CONTROL_PFC_TX_ENABLE, value);
  45619         }
  45620 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45621           break;
  45622     case bcmPortControlPFCClasses:
  45623 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45624         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45625             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45626             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45627                 /* IS_GX_PORT == IS_XL_PORT */
  45628                 return BCM_E_PORT;
  45629             }
  45630             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45631                                  SOC_MAC_CONTROL_PFC_CLASSES, value);
  45632         }
  45633 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45634         break;
  45635     case bcmPortControlPFCPassFrames:
  45636 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45637         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45638             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45639             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45640                 /* IS_GX_PORT == IS_XL_PORT */
  45641                 return BCM_E_PORT;
  45642             }
  45643 
  45644             if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) {
  45645                 uint32 rval32 = 0;
  45646                 soc_reg_t reg = INVALIDr;
  45647                 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  45648                     reg = PGW_MAC_RSV_MASKr;
  45649                 } else if(IS_CL_PORT(unit, port) &&
  45650                           SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  45651                     reg = CLPORT_MAC_RSV_MASKr;
  45652                 } else if(IS_XL_PORT(unit, port) &&
  45653                           SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  45654                     reg = XLPORT_MAC_RSV_MASKr;
  45655                 } else {
  45656                     reg = INVALIDr;
  45657                 }
  45658 
  45659                 if (reg != INVALIDr) {
  45660                     rv = soc_reg32_get(unit, reg, port, 0, &rval32);
  45661                     if (BCM_SUCCESS(rv)) {
  45662                         /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected
  45663                          * the bit value needs to be reversed
  45664                          */
  45665                         *value = ((rval32 & 0x40000) >> 18) ? 0 : 1 ;
  45666                     }
  45667                 } else {
  45668                     rv = BCM_E_UNAVAIL;
  45669                 }
  45670             } else {
  45671                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45672                                      SOC_MAC_CONTROL_PFC_RX_PASS, value);
  45673             }
  45674         }
  45675 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45676         break;
  45677 
  45678     case bcmPortControlPFCDestMacOui:
  45679 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45680         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45681             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45682             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45683                 /* IS_GX_PORT == IS_XL_PORT */
  45684                 return BCM_E_PORT;
  45685             }
  45686             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45687                                  SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value);
  45688         }
  45689 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45690         break;
  45691 
  45692     case bcmPortControlPFCDestMacNonOui:
  45693 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  45694         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45695             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45696             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  45697                 /* IS_GX_PORT == IS_XL_PORT */
  45698                 return BCM_E_PORT;
  45699             }
  45700             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45701                                  SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value);
  45702         }
  45703 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  45704         break;
  45705 
  45706     case bcmPortControlPFCRefreshTime:
  45707 #if defined(BCM_TRIDENT_SUPPORT)|defined(BCM_GREYHOUND_SUPPORT)
  45708         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45709             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45710             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45711                                  SOC_MAC_CONTROL_PFC_REFRESH_TIME, value);
  45712         }
  45713 #endif /* BCM_TRIDENT_SUPPORT */
  45714         break;
  45715 
  45716     case bcmPortControlPFCXOffTime:
  45717 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  45718         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  45719             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  45720             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45721                                  SOC_MAC_CONTROL_PFC_XOFF_TIME, value);
  45722         }
  45723 #endif /* BCM_TRIDENT_SUPPORT */
  45724         break;
  45725 
  45726     case bcmPortControlVrf:
  45727         rv = _bcm_esw_port_vrf_get(unit, port, value);
  45728         break;
  45729 
  45730     case bcmPortControlL3Ingress:
  45731 #if defined(BCM_TRIUMPH_SUPPORT)
  45732         {
  45733             if (!soc_feature(unit, soc_feature_l3_ingress_interface)) {
  45734                 return BCM_E_UNAVAIL;
  45735             }
  45736 
  45737             *value = 0;
  45738             if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  45739                 SOC_IS_TRIDENT3X(unit)) {
  45740                 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value);
  45741                 BCM_IF_ERROR_RETURN(rv);
  45742                 if ((*value == 0x2) &&
  45743                     (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  45744                                          L3_IIFf)) ) {
  45745 #if defined(BCM_KATANA2_SUPPORT)
  45746                     if (SOC_IS_KATANA2(unit)) {
  45747                         rv = _bcm_kt2_source_trunk_map_get(unit, port, L3_IIFf,
  45748                                                        (uint32 *)value);
  45749                     } else
  45750 #endif
  45751                     {
  45752                         rv = _bcm_trx_source_trunk_map_get(unit, port, L3_IIFf,
  45753                                                        (uint32 *)value);
  45754                     }
  45755                 }
  45756             }
  45757         }
  45758 #endif  /* BCM_TRIUMPH_SUPPORT */
  45759         break;
  45760 
  45761     case bcmPortControlL2Learn:
  45762 #if defined(BCM_TRX_SUPPORT)
  45763         if (SOC_IS_TRX(unit)) {
  45764             bcm_port_cfg_t port_cfg;
  45765 
  45766             rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg);
  45767             if (BCM_SUCCESS(rv)) {
  45768                 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml,
  45769                                                 (uint32 *)value);
  45770             }
  45771         }
  45772 #endif /* BCM_TRX_SUPPORT */
  45773         break;
  45774 
  45775     case bcmPortControlL2Move:
  45776 #if defined(BCM_TRX_SUPPORT)
  45777         if (SOC_IS_TRX(unit)) {
  45778             bcm_port_cfg_t port_cfg;
  45779 
  45780             rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg);
  45781             if (BCM_SUCCESS(rv)) {
  45782                 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml_move,
  45783                                                 (uint32 *)value);
  45784             }
  45785         }
  45786 #endif /* BCM_TRX_SUPPORT */
  45787           break;
  45788 
  45789     case bcmPortControlForwardStaticL2MovePkt:
  45790 #if defined(BCM_TRX_SUPPORT)
  45791          rv = _bcm_esw_port_tab_get(unit, port, DISABLE_STATIC_MOVE_DROPf,
  45792                                     value);
  45793 #endif /* BCM_TRX_SUPPORT */
  45794          break;
  45795 
  45796     case bcmPortControlPrbsRxStatus:
  45797         PORT_LOCK(unit);
  45798         rv = soc_phyctrl_control_get(unit, port,
  45799                                      SOC_PHY_CONTROL_PRBS_RX_STATUS,
  45800                                      (uint32 *)value);
  45801         PORT_UNLOCK(unit);
  45802         break;
  45803     case bcmPortControlLinkFaultLocalEnable:
  45804         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45805                              SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value);
  45806         break;
  45807     case bcmPortControlLinkFaultRemoteEnable:
  45808         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45809                              SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value);
  45810         break;
  45811     case bcmPortControlLinkFaultLocal:
  45812         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45813                              SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, value);
  45814         break;
  45815     case bcmPortControlLinkFaultRemote:
  45816         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45817                              SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, value);
  45818         break;
  45819     case bcmPortControlTimestampTransmit:
  45820 #if defined(BCM_TIMESYNC_SUPPORT)
  45821         if (soc_feature(unit, soc_feature_timesync_support)) {
  45822             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45823                                  SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT, value);
  45824         } else
  45825 #endif  /* BCM_TIMESYNC_SUPPORT */
  45826         {
  45827             return BCM_E_UNAVAIL;
  45828         }
  45829         break;
  45830     case bcmPortControlTimestampEnable:
  45831 #if defined(BCM_HAWKEYE_SUPPORT)
  45832         if (SOC_IS_HAWKEYE(unit)) {
  45833             uint32 rval;
  45834             if (!SOC_PORT_VALID(unit, port)) {
  45835                 return BCM_E_PORT;
  45836             }
  45837             SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval));
  45838             if ( port < 32 ) {
  45839                 *value = (rval & (1 << port)) ? TRUE:FALSE;
  45840             } else {
  45841                 *value = FALSE;
  45842             }
  45843             rv = BCM_E_NONE;
  45844         } else
  45845 #endif /* BCM_HAWKEYE_SUPPORT */
  45846         if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  45847             if (IS_XL_PORT(unit, port)) {
  45848                 int tmp;
  45849                 uint32 rval;
  45850                 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit,
  45851                                                              port, &rval));
  45852                 tmp = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr,
  45853                                         rval, XLMAC_TS_DISABLEf);
  45854                 if (tmp) {
  45855                     *value = FALSE;
  45856                 } else {
  45857                     *value = TRUE;
  45858                 }
  45859                 rv = BCM_E_NONE;
  45860             }
  45861         }
  45862         break;
  45863     case bcmPortControlSerdesDriverEqualizationTuneStatusFarEnd:
  45864         PORT_LOCK(unit);
  45865         rv = soc_phyctrl_control_get(unit, port,
  45866              SOC_PHY_CONTROL_SERDES_DRIVER_EQUALIZATION_TUNE_STATUS_FAR_END,
  45867                                      (uint32 *)value);
  45868         PORT_UNLOCK(unit);
  45869         break;
  45870     case bcmPortControlLinkdownTransmit:
  45871         PORT_LOCK(unit);
  45872         rv = soc_phyctrl_control_get(unit, port,
  45873                                      SOC_PHY_CONTROL_LINKDOWN_TRANSMIT,
  45874                                      (uint32 *)value);
  45875         PORT_UNLOCK(unit);
  45876         /* Most of PHYs have nothing to configure and simply return UNAVAIL*/
  45877         if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) {
  45878             rv = _bcm_esw_link_down_tx_get(unit, port, value);
  45879         }
  45880         break;
  45881     case bcmPortControlSerdesTuneMarginMode:
  45882         PORT_LOCK(unit);
  45883         rv = soc_phyctrl_control_get(unit, port,
  45884                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE,
  45885                                      (uint32 *)value);
  45886         PORT_UNLOCK(unit);
  45887         break;
  45888     case bcmPortControlSerdesTuneMarginValue:
  45889         PORT_LOCK(unit);
  45890         rv = soc_phyctrl_control_get(unit, port,
  45891                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE,
  45892                                      (uint32 *)value);
  45893         PORT_UNLOCK(unit);
  45894         break;
  45895     case bcmPortControlSerdesTuneMarginMax:
  45896         PORT_LOCK(unit);
  45897         rv = soc_phyctrl_control_get(unit, port,
  45898                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MAX,
  45899                                      (uint32 *)value);
  45900         PORT_UNLOCK(unit);
  45901         break;
  45902     case bcmPortControlStatOversize:
  45903         rv = _bcm_esw_stat_ovr_threshold_get(unit, port, value);
  45904         break;
  45905 
  45906     case bcmPortControlStatOversizeIsError:
  45907         rv = _bcm_esw_stat_ovr_error_control_get(unit, port, value);
  45908         break;
  45909 
  45910     case bcmPortControlEEEEnable:
  45911         if (!SOC_PORT_VALID(unit, port)) {
  45912             return BCM_E_PORT;
  45913         }
  45914 
  45915         PORT_LOCK(unit);
  45916 
  45917 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  45918         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  45919         || defined(BCM_HURRICANE2_SUPPORT)
  45920 
  45921         if (soc_feature(unit, soc_feature_eee)) {
  45922             *value = eee_cfg[unit][port];
  45923             rv = BCM_E_NONE;
  45924         } else
  45925 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPORT ||
  45926           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  45927 
  45928         {
  45929             uint32 eeenative, eeeauto;
  45930             int rv1 = BCM_E_UNAVAIL, rv2 = BCM_E_UNAVAIL;
  45931 
  45932             rv = BCM_E_NONE;
  45933 
  45934             if ((rv1 = soc_phyctrl_control_get(unit, port,
  45935                             BCM_PORT_PHY_CONTROL_EEE, &eeenative)) !=
  45936                 SOC_E_UNAVAIL) {
  45937                 *value = eeenative;
  45938             }
  45939 
  45940             if ((rv2 = soc_phyctrl_control_get(unit, port,
  45941                             BCM_PORT_PHY_CONTROL_EEE_AUTO, &eeeauto)) !=
  45942                 SOC_E_UNAVAIL) {
  45943                 *value = eeeauto;
  45944             }
  45945 
  45946             /* If neither Native EEE nor AutoGrEEEn mode is supported */
  45947             if ((rv1 == SOC_E_UNAVAIL) && (rv2 == SOC_E_UNAVAIL)) {
  45948                 rv = BCM_E_UNAVAIL;
  45949             }
  45950 
  45951             /* If both Native EEE and AutoGrEEEn mode are supported */
  45952             if ((rv1 != SOC_E_UNAVAIL) && (rv2 != SOC_E_UNAVAIL)) {
  45953                 *value = eeenative ? (eeeauto ? 0 : 1) : (eeeauto ? 1 : 0);
  45954             }
  45955         }
  45956 
  45957         PORT_UNLOCK (unit);
  45958 
  45959         break;
  45960 
  45961  /**********************      EEE Mode Overview    ************************
  45962  *                      |DET|                              |  WT |
  45963  *   Signalling   |idles|   |------------------------------|     | idles   |
  45964  *   from Tx MAC  | or  |   |   Low Power Idle (LPI)       |idles|  or     |
  45965  *   to local PHY |data |   |------------------------------|     | data    |
  45966  *                          *                              *
  45967  *                          *                              *
  45968  *                          *  -------LPI state------------*
  45969  *   Local PHY    |         |  |      |  |       |  |      |   |           |
  45970  *   signaling    |   Active|Ts|  Tq  |Tr|  Tq   |Tr|  Tq  |Tw |Active     |
  45971  *   on MDI       |         |  |      |  |       |  |      |   |           |
  45972  *                          *------------------------------*
  45973  *                          *                              *
  45974  *                          *                               *
  45975  *   Signaling    |   idles |-------------------------------|id| PHY is    |
  45976  *   from LP PHY  |     or  |  Low Power Idle (LPI)         |le| ready     |
  45977  *   to Rx MAC    |   data  |-------------------------------|s | for data  |
  45978  *
  45979  *   where DET = Delay Entry Timer    WT = MAC Wake Timer
  45980  */
  45981     case bcmPortControlEEETransmitIdleTime:
  45982         /* DET = Time (in microsecs) for which condition to move to LPI state
  45983          * is satisfied, at the end of which MAC TX transitions to LPI state */
  45984         if (!SOC_PORT_VALID(unit, port)) {
  45985             return BCM_E_PORT;
  45986         }
  45987 
  45988         PORT_LOCK(unit);
  45989 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  45990         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  45991         || defined(BCM_HURRICANE2_SUPPORT)
  45992         if (soc_feature (unit, soc_feature_eee)) {
  45993             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45994                     SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value);
  45995         } else
  45996 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  45997           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  45998         {
  45999             rv = BCM_E_UNAVAIL;
  46000         }
  46001         PORT_UNLOCK(unit);
  46002         break;
  46003 
  46004     case bcmPortControlEEETransmitEventCount:
  46005         /* Number of time MAC TX enters LPI state for
  46006          * a given measurement interval*/
  46007         if (!SOC_PORT_VALID(unit, port)) {
  46008             return BCM_E_PORT;
  46009         }
  46010 
  46011         PORT_LOCK(unit);
  46012 
  46013 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  46014         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  46015         || defined(BCM_HURRICANE2_SUPPORT)
  46016         if (soc_feature(unit, soc_feature_eee)) {
  46017             int mac_val;
  46018             uint32 phy_val;
  46019             uint64 rval64, rval64_2nd;
  46020             soc_reg_t reg, reg_2nd = INVALIDr;
  46021 
  46022             COMPILER_64_ZERO(rval64);
  46023             COMPILER_64_ZERO(rval64_2nd);
  46024 
  46025             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46026                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  46027                 (soc_phyctrl_control_get(unit, port,
  46028                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  46029                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  46030                  * and PHY also supports Native mode
  46031                  */
  46032 
  46033                 /* On Katana TX/RX register are swapped */
  46034                 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_EVENT_COUNTERr :
  46035                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  46036                       GTX_EEE_LPI_EVENT_COUNTERr :
  46037                       TX_EEE_LPI_EVENT_COUNTERr);
  46038                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  46039                     if (IS_XL_PORT(unit, port)){
  46040                         reg = TX_EEE_LPI_EVENT_COUNTERr;
  46041                     } else {
  46042                         reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46043                     }
  46044                 } else if (SOC_IS_GREYHOUND2(unit)) {
  46045                     if (IS_CL_PORT(unit, port)){
  46046                         reg = CLMIB_TX_EEE_LPI_EVENT_COUNTERr;
  46047                     } else if (IS_XL_PORT(unit, port)) {
  46048                         reg = XLMIB_TX_EEE_LPI_EVENT_COUNTERr;
  46049                         reg_2nd = XLPMIB_TX_EEE_LPI_EVENT_COUNTERr;
  46050                     } else {
  46051 #if defined(BCM_FIRELIGHT_SUPPORT)
  46052                         if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) {
  46053                             if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46054                                 reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46055                             } else {
  46056                                 reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46057                             }
  46058                         } else
  46059 #endif
  46060                         {
  46061                             reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46062                         }
  46063                     }
  46064                 }
  46065 
  46066 #ifdef BCM_HURRICANE4_SUPPORT
  46067                 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  46068                     if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46069                         reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46070                     } else {
  46071                         reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46072                     }
  46073                 }
  46074 #endif /* BCM_HURRICANE4_SUPPORT */
  46075 
  46076                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  46077 
  46078                 if (BCM_SUCCESS(rv)) {
  46079                     *value = COMPILER_64_LO(rval64);
  46080                 }
  46081 
  46082                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  46083                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  46084 
  46085                     if (BCM_SUCCESS(rv)) {
  46086                         *value += COMPILER_64_LO(rval64_2nd);
  46087                     }
  46088                 }
  46089             } else {
  46090                 /* Get counter value from PHY. If PHY does not support
  46091                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46092                  */
  46093                 rv = soc_phyctrl_control_get(unit, port,
  46094                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val);
  46095                 if (SOC_SUCCESS(rv)) {
  46096                     *value = phy_val;
  46097                 }
  46098             }
  46099         } else
  46100 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  46101           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  46102 
  46103         {
  46104             /* On legacy devices that don't support native EEE,
  46105              * get counter value from PHY. If PHY does not support
  46106              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46107              */
  46108             uint32 phy_val;
  46109             rv = soc_phyctrl_control_get(unit, port,
  46110                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val);
  46111             if (SOC_SUCCESS(rv)) {
  46112                 *value = phy_val;
  46113             }
  46114         }
  46115 
  46116         PORT_UNLOCK (unit);
  46117 
  46118         break;
  46119 
  46120     case bcmPortControlEEETransmitDuration:
  46121         /* Time in (microsecs) for which MAC TX enters LPI state
  46122          * during a measurement interval*/
  46123         if (!SOC_PORT_VALID(unit, port)) {
  46124             return BCM_E_PORT;
  46125         }
  46126 
  46127         PORT_LOCK(unit);
  46128 
  46129 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  46130         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  46131         || defined(BCM_HURRICANE2_SUPPORT)
  46132         if (soc_feature(unit, soc_feature_eee)) {
  46133             int mac_val;
  46134             uint32 phy_val;
  46135             uint64 rval64, rval64_2nd;
  46136             soc_reg_t reg, reg_2nd = INVALIDr;
  46137 
  46138             COMPILER_64_ZERO(rval64);
  46139             COMPILER_64_ZERO(rval64_2nd);
  46140 
  46141             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46142                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  46143                 (soc_phyctrl_control_get(unit, port,
  46144                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  46145                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  46146                  * and PHY also supports Native mode
  46147                  */
  46148                 /* On Katana TX/RX register are swapped */
  46149                 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_DURATION_COUNTERr :
  46150                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  46151                       GTX_EEE_LPI_DURATION_COUNTERr :
  46152                       TX_EEE_LPI_DURATION_COUNTERr);
  46153                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  46154                     if (IS_XL_PORT(unit, port)) {
  46155                         reg = TX_EEE_LPI_DURATION_COUNTERr;
  46156                     } else {
  46157                         reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46158                     }
  46159                 } else if (SOC_IS_GREYHOUND2(unit)) {
  46160                     if (IS_CL_PORT(unit, port)){
  46161                         reg = CLMIB_TX_EEE_LPI_DURATION_COUNTERr;
  46162                     } else if (IS_XL_PORT(unit, port)) {
  46163                         reg = XLMIB_TX_EEE_LPI_DURATION_COUNTERr;
  46164                         reg_2nd = XLPMIB_TX_EEE_LPI_DURATION_COUNTERr;
  46165                     } else {
  46166 #if defined(BCM_FIRELIGHT_SUPPORT)
  46167                         if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) {
  46168                             if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46169                                 reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46170                             } else {
  46171                                 reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46172                             }
  46173                         } else
  46174 #endif
  46175                         {
  46176                             reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46177                         }
  46178                     }
  46179                 }
  46180 
  46181 #ifdef BCM_HURRICANE4_SUPPORT
  46182                 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  46183                     if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46184                         reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46185                     } else {
  46186                         reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46187                     }
  46188                 }
  46189 #endif /* BCM_HURRICANE4_SUPPORT */
  46190 
  46191                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  46192 
  46193                 if (BCM_SUCCESS(rv)) {
  46194                     *value = COMPILER_64_LO(rval64);
  46195                 }
  46196 
  46197                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  46198                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  46199                     if (BCM_SUCCESS(rv)) {
  46200                         /* add the 2nd register */
  46201                         *value += COMPILER_64_LO(rval64_2nd);
  46202                     }
  46203                 }
  46204             } else {
  46205                 /* Get counter value from PHY. If PHY does not support
  46206                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46207                  */
  46208                 rv = soc_phyctrl_control_get(unit, port,
  46209                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val);
  46210                 if (SOC_SUCCESS(rv)) {
  46211                     *value = phy_val;
  46212                 }
  46213             }
  46214         } else
  46215 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  46216           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  46217         {
  46218             /* On legacy devices that don't support native EEE,
  46219              * get counter value from PHY. If PHY does not support
  46220              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46221              */
  46222             uint32 phy_val;
  46223             rv = soc_phyctrl_control_get(unit, port,
  46224                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val);
  46225             if (SOC_SUCCESS(rv)) {
  46226                 *value = phy_val;
  46227             }
  46228         }
  46229 
  46230         PORT_UNLOCK (unit);
  46231         break;
  46232 
  46233     case bcmPortControlEEEReceiveEventCount:
  46234         /* Number of time MAC RX enters LPI state for
  46235          * a given measurement interval */
  46236         if (!SOC_PORT_VALID(unit, port)) {
  46237             return BCM_E_PORT;
  46238         }
  46239 
  46240         PORT_LOCK(unit);
  46241 
  46242 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  46243         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  46244         || defined(BCM_HURRICANE2_SUPPORT)
  46245         if (soc_feature(unit, soc_feature_eee)) {
  46246             int mac_val;
  46247             uint32 phy_val;
  46248             uint64 rval64, rval64_2nd;
  46249             soc_reg_t reg, reg_2nd = INVALIDr;
  46250 
  46251             COMPILER_64_ZERO(rval64);
  46252             COMPILER_64_ZERO(rval64_2nd);
  46253 
  46254             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46255                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  46256                 (soc_phyctrl_control_get(unit, port,
  46257                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  46258                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  46259                  * and PHY also supports Native mode
  46260                  */
  46261                 /* On Katana TX/RX register are swapped */
  46262                 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_EVENT_COUNTERr :
  46263                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  46264                       GRX_EEE_LPI_EVENT_COUNTERr :
  46265                       RX_EEE_LPI_EVENT_COUNTERr);
  46266                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  46267                     if (IS_XL_PORT(unit, port)) {
  46268                         reg = RX_EEE_LPI_EVENT_COUNTERr;
  46269                     } else {
  46270                         reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46271                     }
  46272                 } else if (SOC_IS_GREYHOUND2(unit)) {
  46273                     if (IS_CL_PORT(unit, port)){
  46274                         reg = CLMIB_RX_EEE_LPI_EVENT_COUNTERr;
  46275                     } else if (IS_XL_PORT(unit, port)) {
  46276                         reg = XLMIB_RX_EEE_LPI_EVENT_COUNTERr;
  46277                         reg_2nd = XLPMIB_RX_EEE_LPI_EVENT_COUNTERr;
  46278                     } else {
  46279 #if defined(BCM_FIRELIGHT_SUPPORT)
  46280                         if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) {
  46281                             if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46282                                 reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46283                             } else {
  46284                                 reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46285                             }
  46286                         } else
  46287 #endif
  46288                         {
  46289                             reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46290                         }
  46291                     }
  46292                 }
  46293 
  46294 #ifdef BCM_HURRICANE4_SUPPORT
  46295                 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  46296                     if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46297                         reg = GTX_EEE_LPI_EVENT_COUNTERr;
  46298                     } else {
  46299                         reg = GRX_EEE_LPI_EVENT_COUNTERr;
  46300                     }
  46301                 }
  46302 #endif /* BCM_HURRICANE4_SUPPORT */
  46303 
  46304                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  46305 
  46306                 if (BCM_SUCCESS(rv)) {
  46307                     *value = COMPILER_64_LO(rval64);
  46308                 }
  46309 
  46310                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  46311                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  46312                     if (BCM_SUCCESS(rv)) {
  46313                         /* add the 2nd register */
  46314                         *value += COMPILER_64_LO(rval64_2nd);
  46315                     }
  46316                 }
  46317             } else {
  46318                 /* Get counter value from PHY. If PHY does not support
  46319                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46320                  */
  46321                 rv = soc_phyctrl_control_get(unit, port,
  46322                         BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val);
  46323                 if (SOC_SUCCESS(rv)) {
  46324                     *value = phy_val;
  46325                 }
  46326             }
  46327         } else
  46328 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  46329           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  46330         {
  46331             /* On legacy devices that don't support native EEE,
  46332              * get counter value from PHY. If PHY does not support
  46333              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46334              */
  46335             uint32 phy_val;
  46336             rv = soc_phyctrl_control_get(unit, port,
  46337                     BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val);
  46338             if (SOC_SUCCESS(rv)) {
  46339                 *value = phy_val;
  46340             }
  46341         }
  46342 
  46343         PORT_UNLOCK (unit);
  46344         break;
  46345 
  46346     case bcmPortControlEEEReceiveDuration:
  46347         /* Time in (microsecs) for which MAC RX enters LPI state
  46348          * during a measurement interval*/
  46349         if (!SOC_PORT_VALID(unit, port)) {
  46350             return BCM_E_PORT;
  46351         }
  46352         if (!IS_E_PORT(unit, port)) {
  46353             return BCM_E_UNAVAIL;
  46354         }
  46355 
  46356         PORT_LOCK(unit);
  46357 
  46358 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  46359         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  46360         if (soc_feature(unit, soc_feature_eee)) {
  46361             int mac_val;
  46362             uint32 phy_val;
  46363             uint64 rval64, rval64_2nd;
  46364             soc_reg_t reg, reg_2nd = INVALIDr;
  46365 
  46366             COMPILER_64_ZERO(rval64);
  46367             COMPILER_64_ZERO(rval64_2nd);
  46368 
  46369             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46370                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  46371                 (soc_phyctrl_control_get(unit, port,
  46372                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  46373                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  46374                  * and PHY also supports Native mode
  46375                  */
  46376                 /* On Katana TX/RX register are swapped */
  46377                 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_DURATION_COUNTERr :
  46378                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  46379                       GRX_EEE_LPI_DURATION_COUNTERr :
  46380                       RX_EEE_LPI_DURATION_COUNTERr);
  46381                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  46382                     if (IS_XL_PORT(unit, port)) {
  46383                         reg = RX_EEE_LPI_DURATION_COUNTERr;
  46384                     } else {
  46385                         reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46386                     }
  46387                 } else if (SOC_IS_GREYHOUND2(unit)) {
  46388                     if (IS_CL_PORT(unit, port)){
  46389                         reg = CLMIB_RX_EEE_LPI_DURATION_COUNTERr;
  46390                     } else if (IS_XL_PORT(unit, port)) {
  46391                         reg = XLMIB_RX_EEE_LPI_DURATION_COUNTERr;
  46392                         reg_2nd = XLPMIB_RX_EEE_LPI_DURATION_COUNTERr;
  46393                     } else {
  46394 #if defined(BCM_FIRELIGHT_SUPPORT)
  46395                         if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) {
  46396                             if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46397                                 reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46398                             } else {
  46399                                 reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46400                             }
  46401                         } else
  46402 #endif
  46403                         {
  46404                             reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46405                         }
  46406                     }
  46407                 }
  46408 
  46409 #ifdef BCM_HURRICANE4_SUPPORT
  46410                 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  46411                     if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) {
  46412                         reg = GTX_EEE_LPI_DURATION_COUNTERr;
  46413                     } else {
  46414                         reg = GRX_EEE_LPI_DURATION_COUNTERr;
  46415                     }
  46416                 }
  46417 #endif /* BCM_HURRICANE4_SUPPORT */
  46418 
  46419                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  46420 
  46421                 if (BCM_SUCCESS(rv)) {
  46422                     *value = COMPILER_64_LO(rval64);
  46423                 }
  46424 
  46425                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  46426                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  46427                     if (BCM_SUCCESS(rv)) {
  46428                         /* add the 2nd register */
  46429                         *value += COMPILER_64_LO(rval64_2nd);
  46430                     }
  46431                 }
  46432             } else {
  46433                 /* Get counter value from PHY. If PHY does not support
  46434                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46435                  */
  46436                 rv = soc_phyctrl_control_get(unit, port,
  46437                         BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val);
  46438                 if (SOC_SUCCESS(rv)) {
  46439                     *value = phy_val;
  46440                 }
  46441             }
  46442         } else
  46443 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  46444           BCM_TRIDENT_SUPPORT */
  46445         {
  46446             /* On legacy devices that don't support native EEE,
  46447              * get counter value from PHY. If PHY does not support
  46448              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  46449              */
  46450             uint32 phy_val;
  46451             rv = soc_phyctrl_control_get(unit, port,
  46452                     BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val);
  46453             if (SOC_SUCCESS(rv)) {
  46454                 *value = phy_val;
  46455             }
  46456         }
  46457 
  46458         PORT_UNLOCK (unit);
  46459         break;
  46460 
  46461     case bcmPortControlEEETransmitRefreshTime:
  46462         if (!SOC_PORT_VALID(unit, port)) {
  46463             return BCM_E_PORT;
  46464         }
  46465         if (!IS_E_PORT(unit, port)) {
  46466             return BCM_E_UNAVAIL;
  46467         }
  46468         PORT_LOCK(unit);
  46469         rv = soc_phyctrl_control_get(unit, port,
  46470                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME,
  46471                                      (uint32 *)value);
  46472         PORT_UNLOCK (unit);
  46473         break;
  46474 
  46475     case bcmPortControlEEETransmitSleepTime:
  46476         if (!SOC_PORT_VALID(unit, port)) {
  46477             return BCM_E_PORT;
  46478         }
  46479         if (!IS_E_PORT(unit, port)) {
  46480             return BCM_E_UNAVAIL;
  46481         }
  46482         PORT_LOCK(unit);
  46483         rv = soc_phyctrl_control_get(unit, port,
  46484                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, (uint32 *)value);
  46485         PORT_UNLOCK (unit);
  46486         break;
  46487 
  46488     case bcmPortControlEEETransmitQuietTime:
  46489         if (!SOC_PORT_VALID(unit, port)) {
  46490             return BCM_E_PORT;
  46491         }
  46492         if (!IS_E_PORT(unit, port)) {
  46493             return BCM_E_UNAVAIL;
  46494         }
  46495         PORT_LOCK(unit);
  46496         rv = soc_phyctrl_control_get(unit, port,
  46497                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, (uint32 *)value);
  46498         PORT_UNLOCK (unit);
  46499         break;
  46500 
  46501     case bcmPortControlEEETransmitWakeTime:
  46502         /* Time(in microsecs) to wait before transmitter can leave LPI State*/
  46503         if (!SOC_PORT_VALID(unit, port)) {
  46504             return BCM_E_PORT;
  46505         }
  46506         if (!IS_E_PORT(unit, port)) {
  46507             return BCM_E_UNAVAIL;
  46508         }
  46509 
  46510         PORT_LOCK(unit);
  46511 
  46512 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  46513         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  46514         if (soc_feature(unit, soc_feature_eee)) {
  46515             int mac_val;
  46516             uint32 phy_val;
  46517 
  46518             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46519                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  46520                 (soc_phyctrl_control_get(unit, port,
  46521                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  46522                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  46523                  * and PHY also supports Native mode
  46524                  */
  46525                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  46526                         SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value);
  46527 
  46528             } else {
  46529                 /* Get timer value from PHY. If PHY does not support
  46530                  * EEE timers, rv will be assigned SOC_E_UNAVAIL.
  46531                  */
  46532                 rv = soc_phyctrl_control_get(unit, port,
  46533                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val);
  46534                 if (SOC_SUCCESS(rv)) {
  46535                     *value = phy_val;
  46536                 }
  46537             }
  46538         } else
  46539 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  46540           BCM_TRIDENT_SUPPORT */
  46541         {
  46542             /* On legacy devices that don't support native EEE,
  46543              * get timer value from PHY. If PHY does not support
  46544              * EEE timers, rv will be assigned SOC_E_UNAVAIL.
  46545              */
  46546             uint32 phy_val;
  46547             rv = soc_phyctrl_control_get(unit, port,
  46548                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val);
  46549             if (SOC_SUCCESS(rv)) {
  46550                 *value = phy_val;
  46551             }
  46552         }
  46553 
  46554         PORT_UNLOCK (unit);
  46555         break;
  46556 
  46557     case bcmPortControlEEEReceiveSleepTime:
  46558         if (!SOC_PORT_VALID(unit, port)) {
  46559             return BCM_E_PORT;
  46560         }
  46561         if (!IS_E_PORT(unit, port)) {
  46562             return BCM_E_UNAVAIL;
  46563         }
  46564         PORT_LOCK(unit);
  46565         rv = soc_phyctrl_control_get(unit, port,
  46566                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, (uint32 *)value);
  46567         PORT_UNLOCK (unit);
  46568         break;
  46569 
  46570     case bcmPortControlEEEReceiveQuietTime:
  46571         if (!SOC_PORT_VALID(unit, port)) {
  46572             return BCM_E_PORT;
  46573         }
  46574         if (!IS_E_PORT(unit, port)) {
  46575             return BCM_E_UNAVAIL;
  46576         }
  46577         PORT_LOCK(unit);
  46578         rv = soc_phyctrl_control_get(unit, port,
  46579                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, (uint32 *)value);
  46580         PORT_UNLOCK (unit);
  46581         break;
  46582 
  46583     case bcmPortControlEEEReceiveWakeTime:
  46584         if (!SOC_PORT_VALID(unit, port)) {
  46585             return BCM_E_PORT;
  46586         }
  46587         if (!IS_E_PORT(unit, port)) {
  46588             return BCM_E_UNAVAIL;
  46589         }
  46590         PORT_LOCK(unit);
  46591         rv = soc_phyctrl_control_get(unit, port,
  46592                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, (uint32 *)value);
  46593         PORT_UNLOCK (unit);
  46594         break;
  46595 
  46596     case bcmPortControlEEEEventCountSymmetric:
  46597         if (!SOC_PORT_VALID(unit, port)) {
  46598             return BCM_E_PORT;
  46599         }
  46600         if (!IS_E_PORT(unit, port)) {
  46601             return BCM_E_UNAVAIL;
  46602         }
  46603 #if defined(BCM_HURRICANE2_SUPPORT)
  46604         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  46605             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  46606             uint32      reg_value;
  46607             soc_reg_t   reg;
  46608             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  46609                 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr :
  46610                                                CLPORT_EEE_COUNTER_MODEr;
  46611 
  46612                 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) {
  46613                     rv = soc_reg32_get(unit, reg, port, 0, &reg_value);
  46614                     if (SOC_SUCCESS(rv)) {
  46615                         *value = soc_reg_field_get(unit, reg,
  46616                                                    reg_value, MODE_BITf);
  46617                     }
  46618                 } else {
  46619                     return BCM_E_INTERNAL;
  46620                 }
  46621             } else {
  46622                 return BCM_E_PORT;
  46623             }
  46624         } else
  46625 #endif
  46626         {
  46627 #if defined(BCM_TRIUMPH3_SUPPORT)
  46628             if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) {
  46629                   uint32 reg_value;
  46630 
  46631                   rv = READ_PORT_EEE_COUNTER_MODEr(unit, port, &reg_value);
  46632 
  46633                   if (SOC_SUCCESS(rv)) {
  46634                       *value = soc_reg_field_get(unit, PORT_EEE_COUNTER_MODEr,
  46635                           reg_value, MODE_BITf);
  46636                   }
  46637             }
  46638 #endif
  46639        }
  46640         break;
  46641 
  46642     case bcmPortControlEEELinkActiveDuration:
  46643         if (!SOC_PORT_VALID(unit, port)) {
  46644             return BCM_E_PORT;
  46645         }
  46646         if (!IS_E_PORT(unit, port)) {
  46647             return BCM_E_UNAVAIL;
  46648         }
  46649 #if defined(BCM_HURRICANE2_SUPPORT)
  46650         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  46651             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  46652             soc_reg_t   reg;
  46653 
  46654             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  46655 
  46656                 reg = IS_XL_PORT(unit, port) ?
  46657                                 XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  46658                                 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  46659                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  46660                     uint64 reg_value;
  46661 
  46662                     rv = soc_reg_get(unit, reg, port, 0, &reg_value);
  46663                     if (SOC_SUCCESS(rv)) {
  46664                         *value = soc_reg64_field32_get(unit,
  46665                                                        reg, reg_value,
  46666                                                        ONE_SECOND_TIMERf);
  46667                     }
  46668                 }
  46669             } else {
  46670                 return BCM_E_PORT;
  46671             }
  46672         } else
  46673 #endif
  46674         {
  46675 #if defined(BCM_TRIUMPH3_SUPPORT)
  46676             {
  46677                 soc_reg_t reg;
  46678 
  46679                 reg = IS_C_PORT(unit, port) ?
  46680                     CMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  46681                     XMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  46682                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  46683                     uint64 reg_value;
  46684 
  46685                     rv = soc_reg_get(unit, reg, port, 0, &reg_value);
  46686                     if (SOC_SUCCESS(rv)) {
  46687                         *value = soc_reg64_field32_get(unit, reg, reg_value,
  46688                                                      ONE_SECOND_TIMERf);
  46689                     }
  46690                 }
  46691             }
  46692 #endif
  46693         }
  46694         break;
  46695 
  46696     case bcmPortControlRemoteCpuTcMapping:
  46697         if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) {
  46698             rv = _bcm_esw_port_tab_get(unit, port, REMOTE_CPU_ENf, value);
  46699         } else {
  46700             rv = BCM_E_UNAVAIL;
  46701         }
  46702         break;
  46703 
  46704     case bcmPortControlTrill:
  46705 #if defined(BCM_TRIDENT_SUPPORT)
  46706         if (soc_feature(unit, soc_feature_trill)) {
  46707             rv = _bcm_esw_port_tab_get(unit, port, TRILL_ENABLEf, value);
  46708         }
  46709 #endif /* BCM_TRIDENT_SUPPORT */
  46710         break;
  46711 
  46712     case bcmPortControlTrillAllow:
  46713 #if defined(BCM_TRIDENT_SUPPORT)
  46714         if (soc_feature(unit, soc_feature_trill)) {
  46715             rv = _bcm_esw_port_tab_get(unit, port,
  46716                                        ALLOW_TRILL_FRAMESf, value);
  46717         }
  46718 #endif /* BCM_TRIDENT_SUPPORT */
  46719         break;
  46720 
  46721     case bcmPortControlNonTrillAllow:
  46722 #if defined(BCM_TRIDENT_SUPPORT)
  46723         if (soc_feature(unit, soc_feature_trill)) {
  46724             rv = _bcm_esw_port_tab_get(unit, port,
  46725                                        ALLOW_NON_TRILL_FRAMESf, value);
  46726         }
  46727 #endif /* BCM_TRIDENT_SUPPORT */
  46728         break;
  46729 
  46730     case bcmPortControlTrillCoreISISToCPU:
  46731 #if defined(BCM_TRIDENT_SUPPORT)
  46732         if (soc_feature(unit, soc_feature_trill)) {
  46733             rv = _bcm_esw_port_tab_get(unit, port,
  46734                                        COPY_CORE_IS_IS_TO_CPUf, value);
  46735         }
  46736 #endif /* BCM_TRIDENT_SUPPORT */
  46737         break;
  46738 
  46739     case bcmPortControlTrillHashSelect:
  46740 #if defined(BCM_TRIDENT_SUPPORT)
  46741         if (soc_feature(unit, soc_feature_trill)) {
  46742             rv = _bcm_esw_port_tab_get(unit, port,
  46743                                        RTAG7_HASH_CFG_SEL_TRILL_ECMPf, value);
  46744         }
  46745 #endif /* BCM_TRIDENT_SUPPORT */
  46746         break;
  46747 
  46748     case bcmPortControlNivAccessVirtualInterfaceId:
  46749     case bcmPortControlExtendedPortVid:
  46750 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46751          if (soc_feature(unit, soc_feature_niv) ||
  46752                  soc_feature(unit, soc_feature_port_extension)) {
  46753             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  46754                 SOC_IS_GREYHOUND2(unit)) {
  46755                 uint64 val64;
  46756                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  46757                 if (BCM_SUCCESS(rv)) {
  46758                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  46759                                             val64, NIV_VIF_IDf);
  46760                 }
  46761             } else {
  46762                 rv = _bcm_esw_port_tab_get(unit, port, NIV_VIF_IDf, value);
  46763             }
  46764          }
  46765 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46766          break;
  46767 
  46768     case bcmPortControlNivNonVntagDrop:
  46769     case bcmPortControlNonEtagDrop:
  46770 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46771          if (soc_feature(unit, soc_feature_niv) ||
  46772                  soc_feature(unit, soc_feature_port_extension)) {
  46773              rv = _bcm_esw_port_tab_get(unit, port,
  46774                      DISCARD_IF_VNTAG_NOT_PRESENTf, value);
  46775          }
  46776 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46777          break;
  46778 
  46779     case bcmPortControlNivVntagDrop:
  46780     case bcmPortControlEtagDrop:
  46781 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46782         if (soc_feature(unit, soc_feature_niv) ||
  46783             soc_feature(unit, soc_feature_port_extension)) {
  46784             rv = _bcm_esw_port_tab_get(unit, port,
  46785                                        DISCARD_IF_VNTAG_PRESENTf, value);
  46786         }
  46787 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46788         break;
  46789 
  46790     case bcmPortControlSubportPktTagDrop:
  46791 #if defined(BCM_KATANA2_SUPPORT)
  46792          if (soc_feature(unit, soc_feature_lltag)) {
  46793              rv = _bcm_esw_port_tab_get(unit, port,
  46794                      DISCARD_IF_LLTAG_PRESENTf, value);
  46795          }
  46796 #endif /* BCM_KATANA2_SUPPORT */
  46797          break;
  46798 
  46799     case bcmPortControlNoSubportPktTagDrop:
  46800 #if defined(BCM_KATANA2_SUPPORT)
  46801          if (soc_feature(unit, soc_feature_lltag)) {
  46802              rv = _bcm_esw_port_tab_get(unit, port,
  46803                      DISCARD_IF_LLTAG_NOT_PRESENTf, value);
  46804          }
  46805 #endif /* BCM_KATANA2_SUPPORT */
  46806          break;
  46807 
  46808     case bcmPortControlNivNonVntagAdd:
  46809 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46810         if (soc_feature(unit, soc_feature_niv)) {
  46811             int vntag_action;
  46812             rv = _bcm_esw_port_tab_get(unit, port,
  46813                                        VNTAG_ACTIONS_IF_NOT_PRESENTf,
  46814                                        &vntag_action);
  46815             if (BCM_SUCCESS(rv)) {
  46816                 *value = (vntag_action == VNTAG_ADD) ? TRUE : FALSE;
  46817             }
  46818         }
  46819 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46820         break;
  46821 
  46822     case bcmPortControlNonEtagAdd:
  46823 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46824         if (soc_feature(unit, soc_feature_port_extension)) {
  46825             int etag_action;
  46826             rv = _bcm_esw_port_tab_get(unit, port,
  46827                                        VNTAG_ACTIONS_IF_NOT_PRESENTf,
  46828                                        &etag_action);
  46829             if (BCM_SUCCESS(rv)) {
  46830                 *value = (etag_action == 2) ? TRUE : FALSE;
  46831             }
  46832         }
  46833 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46834         break;
  46835 
  46836     case bcmPortControlNivVntagIngressReplace:
  46837     case bcmPortControlEtagIngressReplace:
  46838 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46839         if (soc_feature(unit, soc_feature_niv) ||
  46840             soc_feature(unit, soc_feature_port_extension)) {
  46841             int vntag_action;
  46842             rv = _bcm_esw_port_tab_get(unit, port,
  46843                                        VNTAG_ACTIONS_IF_PRESENTf,
  46844                                        &vntag_action);
  46845             if (BCM_SUCCESS(rv)) {
  46846                 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  46847             }
  46848         }
  46849 #endif /* BCM_TRIDENT_SUPPORT ||BCM_GREYHOUND_SUPPORT */
  46850         break;
  46851 
  46852     case bcmPortControlNivVntagEgressReplace:
  46853     case bcmPortControlEtagEgressReplace:
  46854 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46855          if (soc_feature(unit, soc_feature_niv) ||
  46856                  soc_feature(unit, soc_feature_port_extension)) {
  46857             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  46858                 SOC_IS_GREYHOUND2(unit)) {
  46859                 uint64 val64;
  46860                 int vntag_action;
  46861 
  46862                 if (type == bcmPortControlEtagEgressReplace) {
  46863                     return BCM_E_UNAVAIL;
  46864                 }
  46865 
  46866                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  46867                 if (BCM_SUCCESS(rv)) {
  46868                     vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r,
  46869                                             val64, VNTAG_ACTIONS_IF_PRESENTf);
  46870                     *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  46871                 }
  46872             } else {
  46873                 int vntag_action;
  46874                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  46875                                                VNTAG_ACTIONS_IF_PRESENTf,
  46876                                                &vntag_action);
  46877                 if (BCM_SUCCESS(rv)) {
  46878                     *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  46879                 }
  46880             }
  46881          }
  46882 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46883          break;
  46884 
  46885     case bcmPortControlNivVntagIngressDelete:
  46886     case bcmPortControlEtagIngressDelete:
  46887 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46888         if (soc_feature(unit, soc_feature_niv) ||
  46889             soc_feature(unit, soc_feature_port_extension)) {
  46890             int vntag_action;
  46891             rv = _bcm_esw_port_tab_get(unit, port,
  46892                                        VNTAG_ACTIONS_IF_PRESENTf,
  46893                                        &vntag_action);
  46894             if (BCM_SUCCESS(rv)) {
  46895                 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  46896             }
  46897         }
  46898 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46899         break;
  46900 
  46901     case bcmPortControlNivVntagEgressDelete:
  46902     case bcmPortControlEtagEgressDelete:
  46903 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46904         if (soc_feature(unit, soc_feature_niv) ||
  46905             soc_feature(unit, soc_feature_port_extension)) {
  46906             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  46907                 SOC_IS_GREYHOUND2(unit)) {
  46908                 uint64 val64;
  46909                 int vntag_action;
  46910                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  46911                 if (BCM_SUCCESS(rv)) {
  46912                     vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r,
  46913                                             val64, VNTAG_ACTIONS_IF_PRESENTf);
  46914                     *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  46915                 }
  46916             } else {
  46917                 int vntag_action;
  46918                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  46919                                                VNTAG_ACTIONS_IF_PRESENTf,
  46920                                                &vntag_action);
  46921                 if (BCM_SUCCESS(rv)) {
  46922                     *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  46923                 }
  46924             }
  46925         }
  46926 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46927         break;
  46928 
  46929     case bcmPortControlNivRpfCheck:
  46930     case bcmPortControlExtenderRpfCheck:
  46931 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46932         if (soc_feature(unit, soc_feature_niv) ||
  46933             soc_feature(unit, soc_feature_port_extension)) {
  46934             rv = _bcm_esw_port_tab_get(unit, port,
  46935                                        NIV_RPF_CHECK_ENABLEf, value);
  46936         }
  46937 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46938         break;
  46939 
  46940     case bcmPortControlNivSourceKnockout:
  46941     case bcmPortControlExtenderSourceKnockout:
  46942 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46943         if (soc_feature(unit, soc_feature_niv) ||
  46944             soc_feature(unit, soc_feature_port_extension)) {
  46945             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  46946                 SOC_IS_GREYHOUND2(unit)) {
  46947                 uint64 val64;
  46948                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  46949                 if (BCM_SUCCESS(rv)) {
  46950                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  46951                                             val64, NIV_PRUNE_ENABLEf);
  46952                 }
  46953             } else {
  46954                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  46955                                                NIV_PRUNE_ENABLEf, value);
  46956             }
  46957         }
  46958 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  46959          break;
  46960 
  46961     case bcmPortControlNivForwardPort:
  46962     case bcmPortControlExtenderForwardPort:
  46963 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  46964         if (soc_feature(unit, soc_feature_niv) ||
  46965             soc_feature(unit, soc_feature_port_extension)) {
  46966             int is_niv_uplink;
  46967             int tx_dest_port;
  46968             _bcm_gport_dest_t dest;
  46969 
  46970             BCM_IF_ERROR_RETURN
  46971                 (_bcm_esw_port_tab_get(unit, port,
  46972                                        NIV_UPLINK_PORTf, &is_niv_uplink));
  46973             if (is_niv_uplink) {
  46974                 *value = -1;
  46975             } else {
  46976                 if (soc_feature(unit, soc_feature_generic_dest)) {
  46977                     uint32 dt, dval;
  46978                     BCM_IF_ERROR_RETURN
  46979                         (_bcm_esw_port_tab_get(unit, port, DESTINATIONf,
  46980                                                &tx_dest_port));
  46981                     _soc_mem_dest_value_resolve(unit, tx_dest_port, &dt, &dval);
  46982                     if (dt == SOC_MEM_FIF_DEST_LAG) {
  46983                         dest.tgid = dval;
  46984                         dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
  46985                     } else {
  46986                         dest.port = dval & SOC_MEM_FIF_DGPP_PORT_MASK;
  46987                         dest.modid = (dval & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >>
  46988                                         SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS;
  46989                         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  46990                     }
  46991                 } else {
  46992                     BCM_IF_ERROR_RETURN
  46993                         (_bcm_esw_port_tab_get(unit, port,
  46994                                                TX_DEST_PORTf, &tx_dest_port));
  46995                     if ((tx_dest_port >> SOC_TRUNK_BIT_POS(unit)) & 0x1) {
  46996                         dest.tgid = tx_dest_port - (1 << SOC_TRUNK_BIT_POS(unit));
  46997                         dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
  46998                     } else {
  46999 #if defined(BCM_METROLITE_SUPPORT)
  47000                   /* Metrolite DGLP still uses 7 bits for port like saber 2 */
  47001                       if (SOC_IS_METROLITE(unit)) {
  47002                           dest.port = tx_dest_port & 0x7f;
  47003                           dest.modid =( tx_dest_port & 0xff10) >> 7;
  47004                       } else
  47005 #endif
  47006                       {
  47007                           dest.port = tx_dest_port & SOC_PORT_ADDR_MAX(unit);
  47008                           dest.modid = (tx_dest_port - dest.port) /
  47009                                    (SOC_PORT_ADDR_MAX(unit) + 1);
  47010                       }
  47011                         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  47012                     }
  47013                 }
  47014                 BCM_IF_ERROR_RETURN
  47015                     (_bcm_esw_gport_construct(unit, &dest, value));
  47016             }
  47017             rv = BCM_E_NONE;
  47018         }
  47019 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47020         break;
  47021 
  47022     case bcmPortControlNivType:
  47023         if (soc_feature(unit, soc_feature_niv)) {
  47024             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  47025                 SOC_IS_GREYHOUND2(unit)) {
  47026 #if defined(BCM_GREYHOUND_SUPPORT)
  47027                 rv = bcm_gh_port_niv_type_get(unit, port, value);
  47028 #endif /* BCM_GREYHOUND_SUPPORT */
  47029             } else {
  47030 #if defined(BCM_TRIDENT_SUPPORT)
  47031                 rv = bcm_td_port_niv_type_get(unit, port, value);
  47032 #endif /* BCM_TRIDENT_SUPPORT */
  47033             }
  47034         }
  47035         break;
  47036 
  47037     case bcmPortControlExtenderType:
  47038         if (soc_feature(unit, soc_feature_port_extension)) {
  47039             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  47040                 SOC_IS_GREYHOUND2(unit)) {
  47041 #if defined(BCM_GREYHOUND_SUPPORT)
  47042                 rv = bcm_gh_port_extender_type_get(unit, port, value);
  47043 #endif /* BCM_GREYHOUND_SUPPORT */
  47044             } else {
  47045 #if defined(BCM_TRIUMPH3_SUPPORT)
  47046                 rv = bcm_tr3_port_extender_type_get(unit, port, value);
  47047 #endif /* BCM_TRIUMPH3_SUPPORT */
  47048             }
  47049         }
  47050         break;
  47051 
  47052     case bcmPortControlNivNameSpace:
  47053     case bcmPortControlExtenderNameSpace:
  47054 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  47055         if (soc_feature(unit, soc_feature_niv) ||
  47056             soc_feature(unit, soc_feature_port_extension)) {
  47057             rv = _bcm_esw_port_tab_get(unit, port, NIV_NAMESPACEf, value);
  47058         }
  47059 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47060         break;
  47061 
  47062     case bcmPortControlEtagPcpDeSelect:
  47063 #if defined(INCLUDE_L3)
  47064         if (soc_feature(unit, soc_feature_port_extension)) {
  47065             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  47066                 SOC_IS_GREYHOUND2(unit)) {
  47067 #if defined(BCM_GREYHOUND_SUPPORT)
  47068                 rv = bcm_gh_port_etag_pcp_de_source_get(unit, port, value);
  47069 #endif /* BCM_GREYHOUND_SUPPORT */
  47070             } else {
  47071 #if defined(BCM_TRIUMPH3_SUPPORT)
  47072                 rv = bcm_tr3_port_etag_pcp_de_source_get(unit, port, value);
  47073 #endif /* BCM_TRIUMPH3_SUPPORT */
  47074             }
  47075         }
  47076 #endif /* INCLUDE_L3 */
  47077         break;
  47078 
  47079     case bcmPortControlEtagPcp:
  47080 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  47081         if (soc_feature(unit, soc_feature_port_extension)) {
  47082             rv = _bcm_esw_port_tab_get(unit, port, ETAG_PCPf, value);
  47083         }
  47084 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47085         break;
  47086 
  47087     case bcmPortControlEtagDe:
  47088 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  47089         if (soc_feature(unit, soc_feature_port_extension)) {
  47090             rv = _bcm_esw_port_tab_get(unit, port, ETAG_DEf, value);
  47091         }
  47092 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47093         break;
  47094 
  47095     case bcmPortControlUseEtagPri:
  47096 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  47097         if (soc_feature(unit, soc_feature_port_extension)) {
  47098             rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_ETAGf, value);
  47099         }
  47100 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47101         break;
  47102 
  47103     case bcmPortControlUseSubportPktTagPri:
  47104 #if defined(BCM_KATANA2_SUPPORT)
  47105          if (soc_feature(unit, soc_feature_lltag)) {
  47106              rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_LLTAGf, value);
  47107          }
  47108 #endif /* BCM_KATANA2_SUPPORT */
  47109          break;
  47110 
  47111     case bcmPortControlProhibitedDot1p:
  47112 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  47113         rv = _bcm_esw_port_tab_get(unit, port, PROHIBITED_DOT1Pf, value);
  47114 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  47115         break;
  47116 
  47117     case bcmPortControlFabricSourceKnockout:
  47118         rv = _bcm_esw_port_tab_get(unit, port, REMOVE_HG_HDR_SRC_PORTf,
  47119                                    value);
  47120         break;
  47121 
  47122     case bcmPortControlPrbsPolynomial:
  47123         rv = soc_phyctrl_control_get(unit, port,
  47124                                      SOC_PHY_CONTROL_PRBS_POLYNOMIAL,
  47125                                      (uint32 *)value);
  47126         break;
  47127     case bcmPortControlPrbsTxEnable:
  47128         rv = soc_phyctrl_control_get(unit, port,
  47129                                      SOC_PHY_CONTROL_PRBS_TX_ENABLE,
  47130                                      (uint32 *)value);
  47131         break;
  47132 
  47133     case bcmPortControlPrbsRxEnable:
  47134         rv = soc_phyctrl_control_get(unit, port,
  47135                                      SOC_PHY_CONTROL_PRBS_RX_ENABLE,
  47136                                      (uint32 *)value);
  47137         break;
  47138 
  47139     case bcmPortControlPrbsTxInvertData:
  47140         rv = soc_phyctrl_control_get(unit, port,
  47141                                      SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA,
  47142                                      (uint32 *)value);
  47143         break;
  47144 
  47145     case bcmPortControlRxEnable:
  47146         rv = _bcm_esw_mac_rx_control(unit, port, 1, value);
  47147         break;
  47148     case bcmPortControlTxEnable:
  47149         if (SOC_REG_IS_VALID(unit, COSMASKr) ||
  47150 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  47151             /* Trident2plus/Trident2 uses soc_td2_port_traffic_egr_enable_set */
  47152             SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit) ||
  47153 #endif
  47154 #ifdef BCM_APACHE_SUPPORT
  47155             SOC_IS_APACHE(unit) ||
  47156 #endif
  47157 #ifdef BCM_TRIDENT3_SUPPORT
  47158             SOC_IS_TRIDENT3X(unit) ||
  47159 #endif
  47160 #ifdef BCM_TOMAHAWK_SUPPORT
  47161             SOC_IS_TOMAHAWKX(unit) ||
  47162 #endif
  47163 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  47164             (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) ||
  47165 #endif
  47166             (SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr) &&
  47167              SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) {
  47168             *value = 1;
  47169             if (PORT(unit, port).flags & _PORT_INFO_STOP_TX) {
  47170                 *value = 0;
  47171             }
  47172             rv = SOC_E_NONE;
  47173         }
  47174         break;
  47175 
  47176     case bcmPortControlL2GreEnable:
  47177 #if defined(BCM_TRIUMPH3_SUPPORT)
  47178         if (soc_feature(unit, soc_feature_l2gre)
  47179 #if defined(BCM_TRIDENT3_SUPPORT)
  47180             || soc_feature(unit, soc_feature_flex_flow)
  47181 #endif
  47182             ) {
  47183             rv = _bcm_esw_port_tab_get(unit, port,
  47184                                        L2GRE_TERMINATION_ALLOWEDf, value);
  47185         }
  47186 #endif /* BCM_TRIUMPH3_SUPPORT */
  47187        break;
  47188 
  47189     case bcmPortControlL2GreTunnelbasedVpnId:
  47190 #if defined(BCM_TRIUMPH3_SUPPORT)
  47191         if (soc_feature(unit, soc_feature_l2gre)
  47192 #if defined(BCM_TRIDENT3_SUPPORT)
  47193             || soc_feature(unit, soc_feature_flex_flow)
  47194 #endif
  47195             ) {
  47196             rv = _bcm_esw_port_tab_get(unit, port,
  47197                                        L2GRE_VPNID_LOOKUP_KEY_TYPEf, value);
  47198         }
  47199 #endif /* BCM_TRIUMPH3_SUPPORT */
  47200         break;
  47201 
  47202     case bcmPortControlL2GreDefaultTunnelEnable:
  47203 #if defined(BCM_TRIUMPH3_SUPPORT)
  47204         if (soc_feature(unit, soc_feature_l2gre)
  47205 #if defined(BCM_TRIDENT3_SUPPORT)
  47206             || soc_feature(unit, soc_feature_flex_flow)
  47207 #endif
  47208             ) {
  47209             rv = _bcm_esw_port_tab_get(unit, port,
  47210                                        L2GRE_DEFAULT_SVP_ENABLEf, value);
  47211         }
  47212 #endif /* BCM_TRIUMPH3_SUPPORT */
  47213 
  47214        break;
  47215 
  47216     case bcmPortControlVxlanEnable:
  47217 #if defined(BCM_TRIDENT2_SUPPORT)
  47218         if ((soc_feature(unit, soc_feature_vxlan)) ||
  47219             (soc_feature(unit, soc_feature_flex_flow))) {
  47220             rv = _bcm_esw_port_tab_get(unit, port,
  47221                                        VXLAN_TERMINATION_ALLOWEDf, value);
  47222         }
  47223 #endif /* BCM_TRIDENT2_SUPPORT */
  47224        break;
  47225 
  47226     case bcmPortControlVxlanTunnelbasedVnId:
  47227 #if defined(BCM_TRIDENT2_SUPPORT)
  47228         if ((soc_feature(unit, soc_feature_vxlan)) ||
  47229             (soc_feature(unit, soc_feature_flex_flow))) {
  47230             rv = _bcm_esw_port_tab_get(unit, port,
  47231                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  47232         }
  47233 #endif /* BCM_TRIDENT2_SUPPORT */
  47234        break;
  47235     case bcmPortControlVxlanVpnAssignmentCriteria:
  47236 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  47237         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  47238             rv = _bcm_esw_port_tab_get(unit, port,
  47239                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  47240         }
  47241 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  47242         break;
  47243     case bcmPortControlVxlanTerminationMatchCriteria:
  47244 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  47245         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  47246             rv = _bcm_esw_port_tab_get(unit, port,
  47247                                        VXLAN_TERMINATION_LOOKUP_TYPEf, value);
  47248         }
  47249 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  47250         break;
  47251     case bcmPortControlVxlanGportAssignmentCriteria:
  47252 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  47253         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  47254             rv = _bcm_esw_port_tab_get(unit, port,
  47255                                        VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value);
  47256         }
  47257 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  47258         break;
  47259     case bcmPortControlVxlanDefaultTunnelEnable:
  47260 #if defined(BCM_TRIDENT2_SUPPORT)
  47261         if ((soc_feature(unit, soc_feature_vxlan)) ||
  47262             (soc_feature(unit, soc_feature_flex_flow))) {
  47263             rv = _bcm_esw_port_tab_get(unit, port,
  47264                                        VXLAN_DEFAULT_SVP_ENABLEf, value);
  47265         }
  47266 #endif /* BCM_TRIDENT2_SUPPORT */
  47267         break;
  47268 
  47269 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  47270     case bcmPortControlRegex:
  47271         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  47272         if (enable != 0) {
  47273             *value = 1;
  47274         } else {
  47275             *value = 0;
  47276         }
  47277         break;
  47278     case bcmPortControlRegexTcp:
  47279         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  47280         if (tcp != 0) {
  47281             *value = 1;
  47282         } else {
  47283             *value = 0;
  47284         }
  47285         break;
  47286     case bcmPortControlRegexUdp:
  47287         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  47288         if (udp != 0) {
  47289             *value = 1;
  47290         } else {
  47291             *value = 0;
  47292         }
  47293         break;
  47294 #endif
  47295 
  47296     case bcmPortControlMplsEntropyHashSet:
  47297 #if defined(BCM_KATANA2_SUPPORT)
  47298         if (SOC_IS_KATANA2(unit)) {
  47299             return BCM_E_UNAVAIL;
  47300         } else
  47301 #endif /* BCM_KATANA2_SUPPORT */
  47302         {
  47303 #if defined(BCM_KATANA_SUPPORT)
  47304             if (soc_feature(unit, soc_feature_mpls)) {
  47305                 rv = _bcm_esw_port_tab_get(unit, port,
  47306                                            RTAG7_HASH_CFG_SEL_ENTROPY_LABELf,
  47307                                            value);
  47308             }
  47309 #endif /* BCM_KATANA_SUPPORT */
  47310         }
  47311         break;
  47312 
  47313 #ifdef BCM_SHADOW_SUPPORT
  47314     case bcmPortControlManagementPacketIp6Reserved:
  47315         if (!SOC_IS_SHADOW(unit)) {
  47316             return BCM_E_UNAVAIL;
  47317         }
  47318         PORT_LOCK(unit);
  47319         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  47320         if (BCM_SUCCESS(rv)) {
  47321             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  47322                                        val, IPV6_RESVf);
  47323         }
  47324         PORT_UNLOCK(unit);
  47325         break;
  47326     case bcmPortControlManagementPacketIp4Reserved:
  47327         if (!SOC_IS_SHADOW(unit)) {
  47328             return BCM_E_UNAVAIL;
  47329         }
  47330         PORT_LOCK(unit);
  47331         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  47332         if (BCM_SUCCESS(rv)) {
  47333             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  47334                                        val, IPV4_RESVf);
  47335         }
  47336         PORT_UNLOCK(unit);
  47337         break;
  47338     case bcmPortControlManagementPacketLinkConstrained:
  47339         if (!SOC_IS_SHADOW(unit)) {
  47340             return BCM_E_UNAVAIL;
  47341         }
  47342         PORT_LOCK(unit);
  47343         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  47344         if (BCM_SUCCESS(rv)) {
  47345             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  47346                                        val, LINK_CONSTf);
  47347         }
  47348         PORT_UNLOCK(unit);
  47349         break;
  47350     case bcmPortControlManagementPacketGarp:
  47351         if (!SOC_IS_SHADOW(unit)) {
  47352             return BCM_E_UNAVAIL;
  47353         }
  47354         PORT_LOCK(unit);
  47355         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  47356         if (BCM_SUCCESS(rv)) {
  47357             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  47358                                        val, DOT1D_GARPf);
  47359         }
  47360         PORT_UNLOCK(unit);
  47361         break;
  47362     case bcmPortControlManagementPacketCos:
  47363         if (!SOC_IS_SHADOW(unit)) {
  47364             return BCM_E_UNAVAIL;
  47365         }
  47366         PORT_LOCK(unit);
  47367         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  47368         if (BCM_SUCCESS(rv)) {
  47369             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  47370                                        val, MGMT_FRAME_COSf);
  47371         }
  47372         PORT_UNLOCK(unit);
  47373         break;
  47374     case bcmPortControlManagementPacketColor:
  47375         rv = BCM_E_UNAVAIL;
  47376         break;
  47377     case bcmPortControlTaggedL3PacketPktPri:
  47378         if (!SOC_IS_SHADOW(unit)) {
  47379             return BCM_E_UNAVAIL;
  47380         }
  47381         PORT_LOCK(unit);
  47382         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  47383         if (BCM_SUCCESS(rv)) {
  47384             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  47385                                        val, SELECT5f);
  47386             switch (*value) {
  47387             case 0:
  47388                 *value = BCM_PORT_COS_REMAP_DSCP;
  47389             break;
  47390             case 1:
  47391                 *value = BCM_PORT_COS_REMAP_EXP;
  47392             break;
  47393             case 2:
  47394                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47395             break;
  47396             default:
  47397                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47398             }
  47399         }
  47400         PORT_UNLOCK(unit);
  47401         break;
  47402     case bcmPortControlTaggedMPLSPacketPktPri:
  47403         if (!SOC_IS_SHADOW(unit)) {
  47404             return BCM_E_UNAVAIL;
  47405         }
  47406         PORT_LOCK(unit);
  47407         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  47408         if (BCM_SUCCESS(rv)) {
  47409             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  47410                                        val, SELECT3f);
  47411             switch (*value) {
  47412             case 0:
  47413                 *value = BCM_PORT_COS_REMAP_DSCP;
  47414             break;
  47415             case 1:
  47416                 *value = BCM_PORT_COS_REMAP_EXP;
  47417             break;
  47418             case 2:
  47419                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47420             break;
  47421             default:
  47422                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47423             }
  47424         }
  47425         PORT_UNLOCK(unit);
  47426         break;
  47427     case bcmPortControlTaggedMPLSL3PacketPktPri:
  47428         if (!SOC_IS_SHADOW(unit)) {
  47429             return BCM_E_UNAVAIL;
  47430         }
  47431         PORT_LOCK(unit);
  47432         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  47433         if (BCM_SUCCESS(rv)) {
  47434             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  47435                                        val, SELECT7f);
  47436             switch (*value) {
  47437             case 0:
  47438                 *value = BCM_PORT_COS_REMAP_DSCP;
  47439             break;
  47440             case 1:
  47441                 *value = BCM_PORT_COS_REMAP_EXP;
  47442             break;
  47443             case 2:
  47444                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47445             break;
  47446             default:
  47447                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  47448             }
  47449         }
  47450         PORT_UNLOCK(unit);
  47451         break;
  47452 #endif
  47453 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  47454     case bcmPortControlFieldEgressClassSelect:
  47455 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  47456         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  47457             rv = _bcm_td2p_port_control_egress_class_select_get(unit, port,
  47458                                                                 (uint32 *)value);
  47459         } else
  47460 #endif
  47461         {
  47462             rv = _bcm_trx_port_control_egress_class_select_get(unit, port,
  47463                                                                (uint32 *)value);
  47464         }
  47465         break;
  47466 #endif
  47467 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  47468     case bcmPortControlFieldHiGigClassSelect:
  47469 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  47470         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  47471             rv = _bcm_td2p_port_control_higig_class_select_get(unit, port,
  47472                                                                (uint32 *)value);
  47473         } else
  47474 #endif
  47475         {
  47476             rv = _bcm_trx_port_control_higig_class_select_get(unit, port,
  47477                                                               (uint32 *)value);
  47478         }
  47479         break;
  47480 #endif
  47481     case bcmPortControlSubportTagEnable:
  47482 #if defined (BCM_HGPROXY_COE_SUPPORT)
  47483         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  47484             soc_feature(unit, soc_feature_channelized_switching)) {
  47485             rv = bcmi_xgs5_port_control_subtag_status_get(unit, port, value);
  47486         }
  47487 #endif
  47488 #if defined (BCM_KATANA2_SUPPORT)
  47489         if (soc_feature(unit, soc_feature_subtag_coe)) {
  47490             if (SOC_IS_KATANA2(unit)) {
  47491                 rv = bcm_kt2_port_control_subtag_status_get(unit, port, value);
  47492             }
  47493         }
  47494 #endif
  47495         break;
  47496 
  47497 
  47498     case bcmPortControlLinkPhyEnable:
  47499 #if defined (BCM_KATANA2_SUPPORT)
  47500         if (soc_feature(unit, soc_feature_linkphy_coe)) {
  47501             if (SOC_IS_KATANA2(unit)) {
  47502                 rv = bcm_kt2_port_control_linkphy_status_get(unit, port, value);
  47503             }
  47504         }
  47505 #endif
  47506         break;
  47507 
  47508 #if defined(BCM_TRIDENT2_SUPPORT)
  47509 
  47510     case bcmPortControlFcoeRouteEnable:
  47511         if (soc_feature(unit, soc_feature_fcoe)) {
  47512 #ifdef BCM_TRIDENT3_SUPPORT
  47513             if (SOC_IS_TRIDENT3X(unit)) {
  47514                 rv = _bcm_esw_port_tab_get(unit, port,
  47515                                        FCOE_ROUTE_ENABLEf, value);
  47516             } else
  47517 #endif
  47518             {
  47519                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) {
  47520                      rv = _bcm_esw_port_tab_get(unit, port,
  47521                                                 FCOE_ROUTE_ENABLEf, value);
  47522                 }
  47523             }
  47524         }
  47525         break;
  47526 
  47527     case bcmPortControlFcoeVftEnable:
  47528         if (soc_feature(unit, soc_feature_fcoe)) {
  47529             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) {
  47530                 rv = _bcm_esw_port_tab_get(unit, port,
  47531                                            FCOE_VFT_ENABLEf, value);
  47532             }
  47533         }
  47534         break;
  47535 
  47536     case bcmPortControlFcoeZoneCheckEnable:
  47537         if (soc_feature(unit, soc_feature_fcoe)) {
  47538             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  47539                                     FCOE_ZONE_CHECK_ENABLEf)) {
  47540                 rv = _bcm_esw_port_tab_get(unit, port,
  47541                                            FCOE_ZONE_CHECK_ENABLEf, value);
  47542             }
  47543         }
  47544         break;
  47545 
  47546     case bcmPortControlFcoeSourceBindCheckEnable:
  47547         if (soc_feature(unit, soc_feature_fcoe)) {
  47548             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  47549                                     FCOE_SRC_BIND_CHECK_ENABLEf)) {
  47550                 rv = _bcm_esw_port_tab_get(unit, port,
  47551                                            FCOE_SRC_BIND_CHECK_ENABLEf,
  47552                                            value);
  47553             }
  47554         }
  47555         break;
  47556 
  47557     case bcmPortControlFcoeFpmaPrefixCheckEnable:
  47558         if (soc_feature(unit, soc_feature_fcoe)) {
  47559             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  47560                                     FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
  47561                 rv = _bcm_esw_port_tab_get(unit, port,
  47562                                            FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf,
  47563                                            value);
  47564             }
  47565         }
  47566         break;
  47567 
  47568     case bcmPortControlFcoeDoNotLearn:
  47569         if (soc_feature(unit, soc_feature_fcoe)) {
  47570             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) {
  47571                 rv = _bcm_esw_port_tab_get(unit, port,
  47572                                            FCOE_DO_NOT_LEARNf, value);
  47573             }
  47574         }
  47575         break;
  47576 
  47577     case bcmPortControlFcoeNetworkPort:
  47578         if (soc_feature(unit, soc_feature_fcoe)) {
  47579             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) {
  47580                 rv = _bcm_esw_port_tab_get(unit, port,
  47581                                            FCOE_NETWORK_PORTf, value);
  47582             }
  47583         }
  47584         break;
  47585 
  47586     case bcmPortControlFcoeFabricSel:
  47587         if (soc_feature(unit, soc_feature_fcoe)) {
  47588             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) {
  47589                 rv = _bcm_esw_port_tab_get(unit, port,
  47590                                            FCOE_FABRIC_SELf, value);
  47591             }
  47592         }
  47593         break;
  47594 
  47595     case bcmPortControlFcoeFabricId:
  47596         if (soc_feature(unit, soc_feature_fcoe)) {
  47597 #ifdef BCM_TRIDENT3_SUPPORT
  47598             if (SOC_IS_TRIDENT3X(unit)) {
  47599                     rv = _bcm_esw_port_tab_get(unit, port,
  47600                                            FCOE_FABRIC_IDf, value);
  47601             } else
  47602 #endif
  47603             {
  47604                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) {
  47605                     rv = _bcm_esw_port_tab_get(unit, port,
  47606                                                FCOE_FABRIC_IDf, value);
  47607                 }
  47608             }
  47609         }
  47610         break;
  47611 
  47612     case bcmPortControlFcoeFabricPri:
  47613         if (soc_feature(unit, soc_feature_fcoe)) {
  47614 #ifdef BCM_TRIDENT3_SUPPORT
  47615             if (SOC_IS_TRIDENT3X(unit)) {
  47616                 rv = _bcm_esw_port_tab_get(unit, port,
  47617                                            FCOE_FABRIC_PRIf, value);
  47618             } else
  47619 #endif
  47620             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) {
  47621                 rv = _bcm_esw_port_tab_get(unit, port,
  47622                                            FCOE_FABRIC_PRIf, value);
  47623             }
  47624         }
  47625         break;
  47626 
  47627     case bcmPortControlFcoeFcCrcAction:
  47628         if (soc_feature(unit, soc_feature_fcoe)) {
  47629             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  47630                                     FCOE_FC_CRC_ACTIONf)) {
  47631                 egr_ing_port_entry_t egr_ing_port_entry;
  47632 
  47633                 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port,
  47634                                         &egr_ing_port_entry);
  47635                 if (BCM_SUCCESS(rv)) {
  47636                     *value = soc_mem_field32_get(unit, EGR_ING_PORTm,
  47637                                                  &egr_ing_port_entry,
  47638                                                  FCOE_FC_CRC_ACTIONf);
  47639                 }
  47640             }
  47641         }
  47642         break;
  47643 
  47644     case bcmPortControlFcoeFcCrcRecompute:
  47645         if (soc_feature(unit, soc_feature_fcoe)) {
  47646             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  47647                 SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  47648                                     FCOE_FC_CRC_RECOMPUTEf)) {
  47649                 egr_port_entry_t egr_port_entry;
  47650 
  47651                 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port,
  47652                                     &egr_port_entry);
  47653                 if (BCM_SUCCESS(rv)) {
  47654                     *value = soc_mem_field32_get(unit, EGR_PORTm,
  47655                                                  &egr_port_entry,
  47656                                                  FCOE_FC_CRC_RECOMPUTEf);
  47657                 }
  47658             }
  47659         }
  47660         break;
  47661 
  47662     case bcmPortControlFcoeFcEofIgnore:
  47663         if (soc_feature(unit, soc_feature_fcoe)) {
  47664             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  47665                                     FCOE_FC_EOF_IGNOREf)) {
  47666                 egr_ing_port_entry_t egr_ing_port_entry;
  47667 
  47668                 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port,
  47669                                         &egr_ing_port_entry);
  47670                 if (BCM_SUCCESS(rv)) {
  47671                     *value = soc_mem_field32_get(unit, EGR_ING_PORTm,
  47672                                                  &egr_ing_port_entry,
  47673                                                  FCOE_FC_EOF_IGNOREf);
  47674                 }
  47675             }
  47676         }
  47677         break;
  47678 
  47679     case bcmPortControlFcoeTranslateKeyFirst:
  47680     case bcmPortControlFcoeTranslateKeySecond:
  47681         if (soc_feature(unit, soc_feature_fcoe)) {
  47682             int reg_val;
  47683             int key_type;
  47684             int use_port = 0;
  47685             int vt_port_type;
  47686 
  47687             if (type == bcmPortControlFcoeTranslateKeyFirst) {
  47688                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) {
  47689                     rv = _bcm_esw_port_tab_get(unit, port,
  47690                                                FCOE_VT_KEY_TYPE_1f, &reg_val);
  47691                 }
  47692 
  47693                 if (BCM_SUCCESS(rv)) {
  47694                     rv = _bcm_esw_port_config_get(unit, port,
  47695                                                   _bcmPortVTKeyPortFirst,
  47696                                                  &vt_port_type);
  47697                     if (BCM_SUCCESS(rv)) {
  47698                         if (vt_port_type != 0) {
  47699                             use_port = 1;
  47700                         }
  47701                     }
  47702                 }
  47703             } else {
  47704                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) {
  47705                     rv = _bcm_esw_port_tab_get(unit, port,
  47706                                                FCOE_VT_KEY_TYPE_2f, &reg_val);
  47707                 }
  47708                 if (BCM_SUCCESS(rv)) {
  47709                     rv = _bcm_esw_port_config_get(unit, port,
  47710                                                   _bcmPortVTKeyPortSecond,
  47711                                                  &vt_port_type);
  47712                     if (BCM_SUCCESS(rv)) {
  47713                         if (vt_port_type != 0) {
  47714                             use_port = 1;
  47715                         }
  47716                     }
  47717                 }
  47718             }
  47719 
  47720             if (BCM_SUCCESS(rv)) {
  47721                 /* convert register value to common key type */
  47722                 rv = _bcm_esw_vlan_xlate_key_type_get(unit, reg_val, &key_type);
  47723                 if (!BCM_SUCCESS(rv)) {
  47724                     break;
  47725                 }
  47726 
  47727                 /* convert common key type value to
  47728                    bcm_fcoe_vsan_translate_key_t */
  47729                 switch (key_type) {
  47730                     case VLXLT_HASH_KEY_TYPE_IVID_OVID:
  47731                         if (use_port) {
  47732                             *value = bcmFcoeVsanTranslateKeyPortDouble;
  47733                         } else {
  47734                             *value = bcmFcoeVsanTranslateKeyDouble;
  47735                         }
  47736                         break;
  47737                     case VLXLT_HASH_KEY_TYPE_OTAG:
  47738                         if (use_port) {
  47739                             *value = bcmFcoeVsanTranslateKeyPortOuterTag;
  47740                         } else {
  47741                             *value = bcmFcoeVsanTranslateKeyOuterTag;
  47742                         }
  47743                         break;
  47744                     case VLXLT_HASH_KEY_TYPE_ITAG:
  47745                         if (use_port) {
  47746                             *value = bcmFcoeVsanTranslateKeyPortInnerTag;
  47747                         } else {
  47748                             *value = bcmFcoeVsanTranslateKeyInnerTag;
  47749                         }
  47750                         break;
  47751                     case VLXLT_HASH_KEY_TYPE_OVID:
  47752                         if (use_port) {
  47753                             *value = bcmFcoeVsanTranslateKeyPortOuter;
  47754                         } else {
  47755                             *value = bcmFcoeVsanTranslateKeyOuter;
  47756                         }
  47757                         break;
  47758                     case VLXLT_HASH_KEY_TYPE_IVID:
  47759                         if (use_port) {
  47760                             *value = bcmFcoeVsanTranslateKeyPortInner;
  47761                         } else {
  47762                             *value = bcmFcoeVsanTranslateKeyInner;
  47763                         }
  47764                         break;
  47765                     case VLXLT_HASH_KEY_TYPE_PRI_CFI:
  47766                         if (use_port) {
  47767                             *value = bcmFcoeVsanTranslateKeyPortOuterPri;
  47768                         } else {
  47769                             *value = bcmFcoeVsanTranslateKeyOuterPri;
  47770                         }
  47771                         break;
  47772                     case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
  47773                         if (use_port) {
  47774                             *value = bcmFcoeVsanTranslateKeyPortDoubleVsan;
  47775                         } else {
  47776                             *value = bcmFcoeVsanTranslateKeyDoubleVsan;
  47777                         }
  47778                         break;
  47779                     case VLXLT_HASH_KEY_TYPE_IVID_VSAN:
  47780                         if (use_port) {
  47781                             *value = bcmFcoeVsanTranslateKeyPortInnerVsan;
  47782                         } else {
  47783                             *value = bcmFcoeVsanTranslateKeyInnerVsan;
  47784                         }
  47785                         break;
  47786                     case VLXLT_HASH_KEY_TYPE_OVID_VSAN:
  47787                         if (use_port) {
  47788                             *value = bcmFcoeVsanTranslateKeyPortOuterVsan;
  47789                         } else {
  47790                             *value = bcmFcoeVsanTranslateKeyOuterVsan;
  47791                         }
  47792                         break;
  47793                     default:
  47794                         *value = bcmFcoeVsanTranslateKeyInvalid;
  47795                         break;
  47796                 }
  47797             }
  47798         } else {
  47799             rv = BCM_E_UNAVAIL;
  47800         }
  47801         break;
  47802 
  47803     case bcmPortControlFcoeTranslateKeyFirstEgress:
  47804     case bcmPortControlFcoeTranslateKeySecondEgress:
  47805         if (soc_feature(unit, soc_feature_fcoe)) {
  47806             int key_type = -1;
  47807 
  47808             if (type == bcmPortControlFcoeTranslateKeyFirstEgress) {
  47809                 if (SOC_IS_TRIDENT3X(unit) ||
  47810                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) {
  47811                     rv = _bcm_esw_egr_port_tab_get(unit, port,
  47812                                                    FCOE_VT_LOOKUP_1f,
  47813                                                    &key_type);
  47814                 }
  47815             } else {
  47816                 if (SOC_IS_TRIDENT3X(unit) ||
  47817                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) {
  47818                     rv = _bcm_esw_egr_port_tab_get(unit, port,
  47819                                                    FCOE_VT_LOOKUP_2f,
  47820                                                    &key_type);
  47821                 }
  47822             }
  47823 
  47824             if (BCM_SUCCESS(rv)) {
  47825                 /* convert common key type value to
  47826                    bcm_fcoe_vsan_translate_key_egress_t */
  47827                 switch (key_type) {
  47828                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
  47829                         *value = bcmFcoeVsanTranslateKeyEgressDoubleVsan;
  47830                         break;
  47831                     case EGR_VLXLT_HASH_KEY_TYPE_VSAN:
  47832                         *value = bcmFcoeVsanTranslateKeyEgressVsan;
  47833                         break;
  47834                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN:
  47835                         *value = bcmFcoeVsanTranslateKeyEgressInnerVsan;
  47836                         break;
  47837                     case EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN:
  47838                         *value = bcmFcoeVsanTranslateKeyEgressOuterVsan;
  47839                         break;
  47840                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID:
  47841                         *value = bcmFcoeVsanTranslateKeyEgressDouble;
  47842                         break;
  47843                     case EGR_VLXLT_HASH_KEY_TYPE_IVID:
  47844                         *value = bcmFcoeVsanTranslateKeyEgressInner;
  47845                         break;
  47846                     case EGR_VLXLT_HASH_KEY_TYPE_OVID:
  47847                         *value = bcmFcoeVsanTranslateKeyEgressOuter;
  47848                         break;
  47849                     default:
  47850                         *value = bcmFcoeVsanTranslateKeyEgressInvalid;
  47851                         break;
  47852                 }
  47853             }
  47854         } else {
  47855             rv = BCM_E_UNAVAIL;
  47856         }
  47857         break;
  47858 
  47859 #endif  /* BCM_TRIDENT2_SUPPORT */
  47860     case bcmPortControlEEEMode:
  47861         if (soc_feature(unit, soc_feature_eee_bb_mode)) {
  47862             uint32 fval = 0;
  47863             uint32 rval = 0;
  47864             uint32 temp = 0;
  47865             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  47866                 soc_reg_t eee_bb_reg;
  47867                 int phy_port;
  47868                 int mmu_port;
  47869                 int offset;
  47870 
  47871                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  47872                 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  47873                 if (mmu_port < 32) {
  47874                     eee_bb_reg = EEE_BB_ENABLE_0r;
  47875                     offset = mmu_port;
  47876                 } else if ((mmu_port >=32) && (mmu_port < 64)) {
  47877                     eee_bb_reg = EEE_BB_ENABLE_1r;
  47878                     offset = mmu_port - 32;
  47879                 } else { /* mmu_port >= 64 */
  47880                     eee_bb_reg = EEE_BB_ENABLE_2r;
  47881                     offset = mmu_port - 64;
  47882                 }
  47883                 temp = (1 << offset);
  47884                 BCM_IF_ERROR_RETURN(
  47885                     soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval));
  47886                 fval = soc_reg_field_get(unit, eee_bb_reg, rval,
  47887                                          EEE_BB_ENABLEf);
  47888                 *value = (fval & temp) ? \
  47889                          bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode;
  47890             } else {
  47891                 temp = (1 << port);
  47892                 temp >>= 2;
  47893                 rv = READ_EEE_BB_ENABLEr(unit, &rval);
  47894                 if (BCM_SUCCESS(rv)) {
  47895                     fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval,
  47896                                                EEE_BB_ENABLEf);
  47897                     *value = (fval & temp) ? \
  47898                      bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode;
  47899                 }
  47900             }
  47901         }
  47902         break;
  47903 #ifdef BCM_GREYHOUND_SUPPORT
  47904         case bcmPortControlWredDropCountUpdateEnableQueueMask:
  47905             if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  47906 #if defined(BCM_GREYHOUND2_SUPPORT)
  47907                 if (SOC_IS_GREYHOUND2(unit)) {
  47908                     rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type,
  47909                                                              value);
  47910                 } else
  47911 #endif /* BCM_GREYHOUND2_SUPPORT */
  47912                 {
  47913                     rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val);
  47914                     *value = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr,
  47915                                                val, QUEUE_MASKf);
  47916                 }
  47917             }
  47918             break;
  47919         case bcmPortControlWredDropCountUpdateEnableColorMask:
  47920             if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  47921 #if defined(BCM_GREYHOUND2_SUPPORT)
  47922                 if (SOC_IS_GREYHOUND2(unit)) {
  47923                     rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type,
  47924                                                              value);
  47925                 } else
  47926 #endif /* BCM_GREYHOUND2_SUPPORT */
  47927                 {
  47928                     uint32 fld_val;
  47929                     rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val);
  47930                     if (BCM_SUCCESS(rv)) {
  47931                         fld_val = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr,
  47932                                                     val, COLOR_MASKf);
  47933                         *value = 0;
  47934                         if (fld_val & 0x4) {
  47935                             *value |= (0x1 << bcmColorGreen);
  47936                         }
  47937                         if (fld_val & 0x2) {
  47938                             *value |= (0x1 << bcmColorYellow);
  47939                         }
  47940                         if (fld_val & 0x1) {
  47941                             *value |= (0x1 << bcmColorRed);
  47942                         }
  47943                     }
  47944                 }
  47945             }
  47946             break;
  47947 #endif /* BCM_GREYHOUND_SUPPORT */
  47948 #ifdef BCM_TRIDENT2_SUPPORT
  47949     case bcmPortControlProbeSerdesReset:
  47950         if (SOC_IS_TD2_TT2(unit)) {
  47951             *value =
  47952                 PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES ?
  47953                 1 : 0;
  47954             rv = BCM_E_NONE;
  47955         }
  47956         break;
  47957 #endif /* BCM_TRIDENT2_SUPPORT */
  47958         case bcmPortControlMmuTrafficEnable:
  47959             rv = bcm_esw_port_enqueue_get(unit, port, value);
  47960             break;
  47961     case bcmPortControlRxFastLOS:
  47962         rv = _bcm_esw_link_fast_get(unit, port, value);
  47963         break;
  47964     case bcmPortControlLLFCReceive:
  47965     case bcmPortControlLLFCTransmit:
  47966 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  47967     case bcmPortControlSAFCReceive:
  47968     case bcmPortControlSAFCTransmit:
  47969 #endif
  47970         rv = _bcm_esw_port_llfc_get(unit, port, type, value);
  47971         break;
  47972     case bcmPortControlTrunkLoadBalancingRandomizer:
  47973 #ifdef BCM_TOMAHAWK_SUPPORT
  47974         if (soc_feature(unit, soc_feature_randomized_load_balance)) {
  47975             rv = _bcm_esw_port_tab_get(unit, port,
  47976                                        OFFSET_TRUNK_RANDOM_LBf, value);
  47977         }
  47978 #endif /* BCM_TOMAHAWK_SUPPORT */
  47979         break;
  47980     case bcmPortControlECMPLevel1LoadBalancingRandomizer:
  47981 #ifdef BCM_TOMAHAWK_SUPPORT
  47982         if (soc_feature(unit, soc_feature_ecmp_random)) {
  47983             rv = _bcm_esw_port_tab_get(unit, port,
  47984                                        OFFSET_ECMP_RANDOM_LBf , value);
  47985         }
  47986 #endif /* BCM_TOMAHAWK_SUPPORT */
  47987         break;
  47988     case bcmPortControlECMPLevel2LoadBalancingRandomizer:
  47989 #ifdef BCM_TOMAHAWK_SUPPORT
  47990         if (soc_feature(unit, soc_feature_ecmp_random)) {
  47991             rv = _bcm_esw_port_tab_get(unit, port,
  47992                                        OFFSET_ECMP_LEVEL2_RANDOM_LBf,
  47993                                        value);
  47994         }
  47995 #endif /* BCM_TOMAHAWK_SUPPORT */
  47996         break;
  47997     case bcmPortControlMcastGroupRemap:
  47998        if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
  47999            SOC_IF_ERROR_RETURN
  48000                (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, port, &svp_entry));
  48001            *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  48002                                                NETWORK_PORTf);
  48003            rv = BCM_E_NONE;
  48004        }
  48005        break;
  48006     case bcmPortControlOOBFCTxReportIngEnable:
  48007         if (soc_feature(unit, soc_feature_oob_fc)) {
  48008 #ifdef BCM_TOMAHAWK_SUPPORT
  48009             if (SOC_IS_TOMAHAWKX(unit)) {
  48010                 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 0);
  48011             }
  48012 #endif
  48013 #ifdef BCM_KATANA2_SUPPORT
  48014             if (SOC_IS_KATANA2(unit)) {
  48015                 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 0);
  48016             }
  48017 #endif
  48018 #ifdef BCM_TRIDENT3_SUPPORT
  48019             if (SOC_IS_TRIDENT3X(unit)) {
  48020                 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 0);
  48021             }
  48022 #endif
  48023 #ifdef BCM_APACHE_SUPPORT
  48024             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  48025                 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 0);
  48026             }
  48027 #endif
  48028         }
  48029         break;
  48030     case bcmPortControlOOBFCTxReportEgrEnable:
  48031         if (soc_feature(unit, soc_feature_oob_fc)) {
  48032 #ifdef BCM_TOMAHAWK_SUPPORT
  48033             if (SOC_IS_TOMAHAWKX(unit)) {
  48034                 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 1);
  48035             }
  48036 #endif
  48037 #ifdef BCM_APACHE_SUPPORT
  48038             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  48039                 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 1);
  48040             }
  48041 #endif
  48042 #ifdef BCM_KATANA2_SUPPORT
  48043             if (SOC_IS_KATANA2(unit)) {
  48044                 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 1);
  48045             }
  48046 #endif
  48047 #ifdef BCM_TRIDENT3_SUPPORT
  48048             if (SOC_IS_TRIDENT3X(unit)) {
  48049                 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 1);
  48050             }
  48051 #endif
  48052         }
  48053         break;
  48054 
  48055 	case bcmPortControlSubportTagSize:
  48056 #ifdef BCM_HGPROXY_COE_SUPPORT
  48057           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  48058                                   DESTINATION_SUBPORT_TAG_TYPEf)) {
  48059 
  48060               int local_port = 0;
  48061 			  egr_port_entry_t  egr_port_entry;
  48062               if (BCM_GPORT_IS_SET(port)) {
  48063                   BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  48064               } else {
  48065                   if(!SOC_PORT_VALID(unit, port)) {
  48066                       return BCM_E_PORT;
  48067                   } else {
  48068                       local_port = port;
  48069                   }
  48070               }
  48071 
  48072               SOC_IF_ERROR_RETURN
  48073                   (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, local_port, &egr_port_entry));
  48074               *value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
  48075                                                   DESTINATION_SUBPORT_TAG_TYPEf);
  48076               rv = BCM_E_NONE;
  48077           }
  48078           if (SOC_IS_TRIDENT3X(unit)) {
  48079               *value = 0;
  48080               rv = BCM_E_NONE;
  48081           }
  48082 #endif
  48083 		  break;
  48084 
  48085 	case bcmPortControlSystemPortOverride:
  48086 #ifdef BCM_HGPROXY_COE_SUPPORT
  48087           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  48088                                   VT_SYS_PORT_OVERRIDEf)) {
  48089 
  48090               rv = bcmi_xgs5_subport_subtag_port_override_get(unit, port,
  48091                                                               value);
  48092           }
  48093 #endif
  48094           break;
  48095 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  48096     case bcmPortControlSampleIngressDest:
  48097         if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  48098             sflow_ing_data_source_entry_t sflow_entry;
  48099             uint32 field_values[2] = {0, 0};
  48100             BCM_IF_ERROR_RETURN
  48101                 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  48102                                              &sflow_entry));
  48103             soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48104                                                  CPUf, &field_values[0]);
  48105             soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48106                                                  MIRRORf, &field_values[1]);
  48107             *value = field_values[0] | (field_values[1] << 1);
  48108             rv = BCM_E_NONE;
  48109         }
  48110         break;
  48111     case bcmPortControlSampleFlexDest:
  48112         if(soc_feature(unit, soc_feature_sflow_flex)) {
  48113             sflow_ing_flex_data_source_entry_t sflow_entry;
  48114             uint32 field_values[2] = {0, 0};
  48115             BCM_IF_ERROR_RETURN
  48116                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  48117                                                   &sflow_entry));
  48118             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48119                                                       CPUf, &field_values[0]);
  48120             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48121                                                       MIRRORf, &field_values[1]);
  48122             *value = field_values[0] | (field_values[1] << 1);
  48123             rv = BCM_E_NONE;
  48124         }
  48125         break;
  48126     case bcmPortControlSampleFlexRate:
  48127         if(soc_feature(unit, soc_feature_sflow_flex)) {
  48128             sflow_ing_flex_data_source_entry_t sflow_entry;
  48129             uint32 field_enable, field_thresh;
  48130 
  48131             /* Read ENABLE and THRESHOLD fields from flex rate data table */
  48132             BCM_IF_ERROR_RETURN
  48133                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  48134                                                   &sflow_entry));
  48135             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48136                                                       ENABLEf, &field_enable);
  48137             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  48138                                                       THRESHOLDf,
  48139                                                       &field_thresh);
  48140 
  48141             if (field_enable) {
  48142                 if (field_thresh) {
  48143                     *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_thresh;
  48144                 } else {
  48145                     *value = 1 << (SFLOW_RANGE_MAX(unit));
  48146                 }
  48147             } else {
  48148                 *value = 0;
  48149                 if (field_thresh) {
  48150                     return BCM_E_INTERNAL;
  48151                 }
  48152             }
  48153             rv = BCM_E_NONE;
  48154         }
  48155         break;
  48156 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  48157 #ifdef BCM_XGS3_SWITCH_SUPPORT
  48158     case bcmPortControlSampleIngressEnable:
  48159         if (SOC_IS_XGS3_SWITCH(unit)) {
  48160             uint32 regval       = 0;
  48161             uint32 field_enable = 0;
  48162 #ifdef BCM_TOMAHAWK_SUPPORT
  48163             sflow_ing_data_source_entry_t sflow_entry;
  48164 #endif /* BCM_TOMAHAWK_SUPPORT */
  48165 
  48166 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  48167             if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  48168                 BCM_IF_ERROR_RETURN(
  48169                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  48170                                                 &sflow_entry));
  48171 
  48172                 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, ENABLEf,
  48173                                              &field_enable);
  48174             } else
  48175 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  48176             {
  48177                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  48178                     return BCM_E_UNAVAIL;
  48179                 }
  48180                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  48181                 field_enable = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, regval,
  48182                                                          ENABLEf);
  48183             }
  48184 
  48185             *value = field_enable ? 1 : 0;
  48186             rv = BCM_E_NONE;
  48187         } else {
  48188             rv = BCM_E_UNAVAIL;
  48189         }
  48190         break;
  48191     case bcmPortControlSampleEgressEnable:
  48192         if (SOC_IS_XGS3_SWITCH(unit)) {
  48193             uint32 regval       = 0;
  48194             uint32 field_enable = 0;
  48195 
  48196             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  48197                 return BCM_E_UNAVAIL;
  48198             }
  48199             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  48200             field_enable = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, regval,
  48201                                                     ENABLEf);
  48202 
  48203             *value = field_enable ? 1 : 0;
  48204             rv = BCM_E_NONE;
  48205         } else {
  48206             rv = BCM_E_UNAVAIL;
  48207         }
  48208         break;
  48209     case bcmPortControlSampleIngressRate:
  48210         if (SOC_IS_XGS3_SWITCH(unit)) {
  48211             uint32 regval       = 0;
  48212             uint32 field_value;
  48213 #ifdef BCM_TOMAHAWK_SUPPORT
  48214             sflow_ing_data_source_entry_t sflow_entry;
  48215 #endif /* BCM_TOMAHAWK_SUPPORT */
  48216 
  48217 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  48218             if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  48219                 BCM_IF_ERROR_RETURN(
  48220                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  48221                                                 &sflow_entry));
  48222 
  48223                 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, THRESHOLDf,
  48224                                              &field_value);
  48225             } else
  48226 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  48227             {
  48228                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  48229                     return BCM_E_UNAVAIL;
  48230                 }
  48231                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  48232 
  48233                 field_value = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr,
  48234                                                      regval, THRESHOLDf);
  48235             }
  48236 
  48237             /*
  48238              * For early sFlow implementations the 16-bit threshold value
  48239              * is compared to bits [23:8] of the sFlow random number.
  48240              */
  48241             if (soc_feature(unit, soc_feature_sample_offset8)) {
  48242                 field_value <<= 8;
  48243             }
  48244 
  48245             if (field_value) {
  48246                 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value;
  48247             } else {
  48248                 *value = 0;
  48249             }
  48250             rv = BCM_E_NONE;
  48251         } else {
  48252             rv = BCM_E_UNAVAIL;
  48253         }
  48254         break;
  48255     case bcmPortControlSampleEgressRate:
  48256         if (SOC_IS_XGS3_SWITCH(unit)) {
  48257             uint32 regval;
  48258             uint32 field_value;
  48259 
  48260             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  48261                 return BCM_E_UNAVAIL;
  48262             }
  48263             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  48264 
  48265             field_value = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr,
  48266                                                     regval, THRESHOLDf);
  48267 
  48268             /*
  48269              * For early sFlow implementations the 16-bit threshold value
  48270              * is compared to bits [23:8] of the sFlow random number.
  48271              */
  48272             if (soc_feature(unit, soc_feature_sample_offset8)) {
  48273                 field_value <<= 8;
  48274             }
  48275 
  48276             if (field_value) {
  48277                 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value;
  48278             } else {
  48279                 *value = 0;
  48280             }
  48281             rv = BCM_E_NONE;
  48282         } else {
  48283             rv = BCM_E_UNAVAIL;
  48284         }
  48285         break;
  48286 #endif
  48287     case bcmPortControlExternalBufferEnable:
  48288 #if defined(BCM_KATANA2_SUPPORT)
  48289           if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) {
  48290               rv = _bcm_kt2_cosq_port_ext_buf_get(unit, port, value);
  48291           }
  48292 #endif
  48293         break;
  48294 #ifdef BCM_HURRICANE3_SUPPORT
  48295     case bcmPortControlTrustMimlPri:
  48296         if (soc_feature(unit, soc_feature_miml)) {
  48297             rv = _bcm_esw_port_tab_get(unit, port,
  48298                                        USE_MIML_PCP_FOR_PRIf, value);
  48299         }
  48300         break;
  48301     case bcmPortControlTrustCustomHeaderPri:
  48302         if (soc_feature(unit, soc_feature_custom_header)) {
  48303             rv = _bcm_esw_port_tab_get(unit, port,
  48304                                        USE_CUSTOM_HEADER_FOR_PRIf, value);
  48305         }
  48306         break;
  48307     case bcmPortControlCustomHeaderEncapEnable:
  48308         if (soc_feature(unit, soc_feature_custom_header)) {
  48309             uint64 val64;
  48310 
  48311             rv = READ_EGR_PORT_64r(unit, port, &val64);
  48312             if (BCM_SUCCESS(rv)) {
  48313                 *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  48314                                         val64, CUSTOM_HEADER_ENABLEf);
  48315             }
  48316         }
  48317         break;
  48318 #endif /* BCM_HURRICANE3_SUPPORT */
  48319     case bcmPortControl1588P2PDelay:
  48320         {
  48321             uint32 link_delay;
  48322             int mac_rx_latency = 0;
  48323             int speed;
  48324             rv = bcm_esw_port_speed_get(unit, port, &speed);
  48325             soc_property_port_get(unit, port,
  48326                                               spn_LINK_DELAY(speed), mac_rx_latency);
  48327 
  48328             if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
  48329                 soc_reg32_get(unit, EGR_1588_LINK_DELAYr,
  48330                                         port, LINK_DELAYf, &link_delay);
  48331                 *value = link_delay - mac_rx_latency;
  48332                 rv =  BCM_E_NONE;
  48333             } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
  48334                 soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r,
  48335                                             port, 0, LINK_DELAYf, &link_delay);
  48336                 *value = link_delay - mac_rx_latency;
  48337                 rv =  BCM_E_NONE;
  48338             } else {
  48339                 rv = BCM_E_UNAVAIL;
  48340                 /* No LINK_DELAY register, so no-op */
  48341             }
  48342         }
  48343         break;
  48344     case bcmPortControlPacketTimeStampInsertRx:
  48345 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48346     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48347         if (soc_feature(unit, soc_feature_timestamp)) {
  48348             int ing_insert;
  48349             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48350 
  48351             BCM_IF_ERROR_RETURN(
  48352                 _bcm_esw_port_tab_get(unit, port, INSERT_RX_TIMESTAMPf,
  48353                                       &ing_insert));
  48354             *value = ing_insert;
  48355             rv = BCM_E_NONE;
  48356         }
  48357 #endif
  48358         break;
  48359     case bcmPortControlPacketTimeStampInsertTx:
  48360 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48361     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48362         if (soc_feature(unit, soc_feature_timestamp)) {
  48363             uint32 regval;
  48364             uint32 egr_insert;
  48365             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48366 
  48367             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  48368             egr_insert = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  48369                                            INSERT_TX_TIMESTAMPf);
  48370             *value = (int)egr_insert;
  48371             rv = BCM_E_NONE;
  48372         }
  48373 #endif
  48374         break;
  48375     case bcmPortControlPacketTimeStampSrcPortInsertCancel:
  48376 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48377     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48378         if (soc_feature(unit, soc_feature_timestamp)) {
  48379             int ing_disable;
  48380             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48381 
  48382             BCM_IF_ERROR_RETURN(
  48383                 _bcm_esw_port_tab_get(unit, port, DISABLE_TIMESTAMPINGf,
  48384                                       &ing_disable));
  48385             *value = ing_disable;
  48386             rv = BCM_E_NONE;
  48387         }
  48388 #endif
  48389         break;
  48390     case bcmPortControlPacketTimeStampDestPortInsertCancel:
  48391 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48392     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48393         if (soc_feature(unit, soc_feature_timestamp)) {
  48394             uint32 regval;
  48395             uint32 egr_disable;
  48396             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48397 
  48398             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  48399             egr_disable = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  48400                                             DISABLE_TIMESTAMPINGf);
  48401             *value = (int)egr_disable;
  48402             rv = BCM_E_NONE;
  48403         }
  48404 #endif
  48405         break;
  48406     case bcmPortControlPacketTimeStampRxId:
  48407 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48408     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48409         if (soc_feature(unit, soc_feature_timestamp)) {
  48410             uint32 regval;
  48411             egr_ts_ing_port_map_entry_t egr_ts_entry;
  48412             uint32 id;
  48413             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48414             if (SOC_REG_IS_VALID(unit, EGR_TS_ING_PORT_MAPr)) {
  48415                 BCM_IF_ERROR_RETURN(READ_EGR_TS_ING_PORT_MAPr(unit, port, &regval));
  48416                 id = soc_reg_field_get(unit, EGR_TS_ING_PORT_MAPr, regval,
  48417                                            TS_RX_ORIGIN_IDf);
  48418                 *value = (int)id;
  48419             } else {
  48420 
  48421                 BCM_IF_ERROR_RETURN(
  48422                       READ_EGR_TS_ING_PORT_MAPm(unit, MEM_BLOCK_ANY, port, &egr_ts_entry));
  48423                 soc_EGR_TS_ING_PORT_MAPm_field_get(unit, &egr_ts_entry, TS_RX_ORIGIN_IDf,
  48424                                                &regval);
  48425                 *value = (int)regval;
  48426 
  48427             }
  48428             rv = BCM_E_NONE;
  48429        }
  48430 #endif
  48431        break;
  48432     case bcmPortControlPacketTimeStampTxId:
  48433 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48434     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48435         if (soc_feature(unit, soc_feature_timestamp)) {
  48436             uint32 regval;
  48437             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48438 
  48439             if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf))
  48440             {
  48441                 BCM_IF_ERROR_RETURN(
  48442                             READ_EGR_TS_CONTROL_2r(unit, port, &regval));
  48443                 *value = soc_reg_field_get(
  48444                             unit, EGR_TS_CONTROL_2r, regval, TS_TX_ORIGIN_IDf);
  48445             } else {
  48446                 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  48447                 *value = soc_reg_field_get(
  48448                             unit, EGR_TS_CONTROLr, regval, TS_TX_ORIGIN_IDf);
  48449             }
  48450             rv = BCM_E_NONE;
  48451         }
  48452 #endif
  48453         break;
  48454     case bcmPortControlPacketTimeStampByteMeterAdjust:
  48455 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  48456     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  48457         if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit))
  48458         {
  48459             uint32 regval;
  48460             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48461 
  48462             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  48463             *value = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  48464                                        TS_ADJUST_METERSf);
  48465             rv = BCM_E_NONE;
  48466         }
  48467 #endif
  48468         break;
  48469     case bcmPortControlE2EFCTransmitEnable:
  48470         if (soc_feature(unit, soc_feature_e2efc)) {
  48471             uint32 fval;
  48472             uint64 val;
  48473 
  48474             if (!IS_HG_PORT(unit, port)) {
  48475                 LOG_ERROR(
  48476                     BSL_LS_BCM_PORT,
  48477                     (BSL_META_U(unit,
  48478                                 "Error: unit %d port %d is not a Higig port. "
  48479                                 "E2EFC messages can only be transmitted to "
  48480                                 "or received from Higig ports.\n"),
  48481                      unit, port));
  48482                 return BCM_E_PARAM;
  48483             }
  48484 #if defined(BCM_KATANA2_SUPPORT)
  48485             if (SOC_IS_KATANA2(unit)) {
  48486                 BCM_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &fval));
  48487                 *value = fval;
  48488             } else
  48489 #endif
  48490             if (IS_XL_PORT(unit, port)) {
  48491                 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val));
  48492                 fval = soc_reg64_field32_get(unit, XLMAC_E2E_CTRLr,
  48493                                              val, E2E_ENABLEf);
  48494                 *value = fval;
  48495             } else if (IS_CL_PORT(unit, port)) {
  48496                 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val));
  48497                 fval = soc_reg64_field32_get(unit, CLMAC_E2E_CTRLr,
  48498                                              val, E2E_ENABLEf);
  48499                 *value = fval;
  48500             } else {
  48501                 return BCM_E_PARAM;
  48502             }
  48503 
  48504             rv = BCM_E_NONE;
  48505         }
  48506         break;
  48507     case bcmPortControlE2EFCReceiveEnable:
  48508         if (soc_feature(unit, soc_feature_e2efc)) {
  48509             uint32 val, fval;
  48510 
  48511             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  48512             fval = soc_reg_field_get(unit, IE2E_CONTROLr,
  48513                                      val, IBP_ENABLEf);
  48514             *value = fval;
  48515             rv = BCM_E_NONE;
  48516         }
  48517         break;
  48518     case bcmPortControlE2EFCCopyToCpuEnable:
  48519         if (soc_feature(unit, soc_feature_e2efc)) {
  48520             uint32 val, fval;
  48521 
  48522             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  48523             fval = soc_reg_field_get(unit, IE2E_CONTROLr,
  48524                                      val, IBP_TOCPUf);
  48525             *value = fval;
  48526             rv = BCM_E_NONE;
  48527         }
  48528         break;
  48529     /* Higher 3 bytes of Destination MAC address */
  48530     case bcmPortControlE2EFCDestMacOui:
  48531         if (soc_feature(unit, soc_feature_e2efc)) {
  48532             uint32 val_hi;
  48533             uint64 val_64, data_0;
  48534             soc_reg_t reg;
  48535 #if defined(BCM_KATANA2_SUPPORT)
  48536             uint32 val;
  48537 #endif
  48538             if (!IS_HG_PORT(unit, port)) {
  48539                 LOG_ERROR(
  48540                     BSL_LS_BCM_PORT,
  48541                     (BSL_META_U(unit,
  48542                                 "Error: unit %d port %d is not a Higig port. "
  48543                                 "E2EFC messages can only be transmitted to "
  48544                                 "or received from Higig ports.\n"),
  48545                      unit, port));
  48546                 return BCM_E_PARAM;
  48547             }
  48548 #if defined(BCM_KATANA2_SUPPORT)
  48549             if (SOC_IS_KATANA2(unit)) {
  48550 #if defined(BCM_SABER2_SUPPORT)
  48551                 if (SOC_IS_SABER2(unit)) {
  48552                     /* Do nothing */
  48553                 } else
  48554 #endif /* BCM_SABER2_SUPPORT */
  48555               {
  48556                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  48557                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  48558                     *value = (val_hi >> 8) & 0xffffff;
  48559                     rv = BCM_E_NONE;
  48560                     break;
  48561                }
  48562            }
  48563 #endif /* BCM_KATANA2_SUPPORT */
  48564             if (IS_XL_PORT(unit, port)) {
  48565                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  48566             } else if (IS_CL_PORT(unit, port)) {
  48567                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  48568             } else {
  48569                 return BCM_E_PARAM;
  48570             }
  48571 
  48572             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  48573                                             port, 0, &val_64));
  48574             data_0 = soc_reg64_field_get(unit, reg,
  48575                                          val_64, E2EFC_DATA_HDR_0f);
  48576             COMPILER_64_TO_32_HI(val_hi, data_0);
  48577             *value = (val_hi >> 8) & 0xffffff;
  48578             rv = BCM_E_NONE;
  48579         }
  48580         break;
  48581     /* Lower 3 bytes of Destination MAC address */
  48582     case bcmPortControlE2EFCDestMacNonOui:
  48583         if (soc_feature(unit, soc_feature_e2efc)) {
  48584             uint32 val_lo, val_hi;
  48585             uint64 val_64, data_0;
  48586             soc_reg_t reg;
  48587 #if defined(BCM_KATANA2_SUPPORT)
  48588             uint32 val;
  48589 #endif
  48590             if (!IS_HG_PORT(unit, port)) {
  48591                 LOG_ERROR(
  48592                     BSL_LS_BCM_PORT,
  48593                     (BSL_META_U(unit,
  48594                                 "Error: unit %d port %d is not a Higig port. "
  48595                                 "E2EFC messages can only be transmitted to "
  48596                                 "or received from Higig ports.\n"),
  48597                      unit, port));
  48598                 return BCM_E_PARAM;
  48599             }
  48600 #if defined(BCM_KATANA2_SUPPORT)
  48601             if (SOC_IS_KATANA2(unit)) {
  48602 #if defined(BCM_SABER2_SUPPORT)
  48603                 if (SOC_IS_SABER2(unit)) {
  48604                     /* Do nothing */
  48605                 } else
  48606 #endif /* BCM_SABER2_SUPPORT */
  48607               {
  48608                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  48609                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  48610                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  48611                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  48612                     *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff);
  48613                     rv = BCM_E_NONE;
  48614                     break;
  48615                }
  48616            }
  48617 #endif /* BCM_KATANA2_SUPPORT */
  48618             if (IS_XL_PORT(unit, port)) {
  48619                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  48620             } else if (IS_CL_PORT(unit, port)) {
  48621                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  48622             } else {
  48623                 return BCM_E_PARAM;
  48624             }
  48625 
  48626             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  48627                                             port, 0, &val_64));
  48628             data_0 = soc_reg64_field_get(unit, reg,
  48629                                          val_64, E2EFC_DATA_HDR_0f);
  48630             COMPILER_64_TO_32_LO(val_lo, data_0);
  48631             COMPILER_64_TO_32_HI(val_hi, data_0);
  48632             *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff);
  48633             rv = BCM_E_NONE;
  48634         }
  48635         break;
  48636     /* Higher 3 bytes of Source MAC address */
  48637     case bcmPortControlE2EFCSrcMacOui:
  48638         if (soc_feature(unit, soc_feature_e2efc)) {
  48639             uint32 val_0_lo, val_1_hi;
  48640             uint64 val_64, data_1, data_0;
  48641             soc_reg_t reg_0, reg_1;
  48642 #if defined(BCM_KATANA2_SUPPORT)
  48643             uint32 val;
  48644 #endif
  48645             if (!IS_HG_PORT(unit, port)) {
  48646                 LOG_ERROR(
  48647                     BSL_LS_BCM_PORT,
  48648                     (BSL_META_U(unit,
  48649                                 "Error: unit %d port %d is not a Higig port. "
  48650                                 "E2EFC messages can only be transmitted to "
  48651                                 "or received from Higig ports.\n"),
  48652                      unit, port));
  48653                 return BCM_E_PARAM;
  48654             }
  48655 #if defined(BCM_KATANA2_SUPPORT)
  48656             if (SOC_IS_KATANA2(unit)) {
  48657 #if defined(BCM_SABER2_SUPPORT)
  48658                 if (SOC_IS_SABER2(unit)) {
  48659                     /* Do nothing */
  48660                 } else
  48661 #endif /* BCM_SABER2_SUPPORT */
  48662               {
  48663                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  48664                     val_0_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  48665                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  48666                     val_1_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  48667                     *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8);
  48668                     rv = BCM_E_NONE;
  48669                    break;
  48670                }
  48671            }
  48672 #endif /* BCM_KATANA2_SUPPORT */
  48673             if (IS_XL_PORT(unit, port)) {
  48674                 reg_0 = XLMAC_E2EFC_DATA_HDR_0r;
  48675                 reg_1 = XLMAC_E2EFC_DATA_HDR_1r;
  48676             } else if (IS_CL_PORT(unit, port)) {
  48677                 reg_0 = CLMAC_E2EFC_DATA_HDR_0r;
  48678                 reg_1 = CLMAC_E2EFC_DATA_HDR_1r;
  48679             } else {
  48680                 return BCM_E_PARAM;
  48681             }
  48682 
  48683             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1,
  48684                                             port, 0, &val_64));
  48685             data_1 = soc_reg64_field_get(unit, reg_1,
  48686                                          val_64, E2EFC_DATA_HDR_1f);
  48687             COMPILER_64_TO_32_HI(val_1_hi, data_1);
  48688             /* SA MAC setting across 2 registers */
  48689             COMPILER_64_ZERO(val_64);
  48690             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0,
  48691                                             port, 0, &val_64));
  48692             data_0 = soc_reg64_field_get(unit, reg_0,
  48693                                          val_64, E2EFC_DATA_HDR_0f);
  48694             COMPILER_64_TO_32_LO(val_0_lo, data_0);
  48695             *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8);
  48696             rv = BCM_E_NONE;
  48697         }
  48698         break;
  48699     /* Lower 3 bytes of Source MAC address */
  48700     case bcmPortControlE2EFCSrcMacNonOui:
  48701         if (soc_feature(unit, soc_feature_e2efc)) {
  48702             uint32 val_hi;
  48703             uint64 val_64, data_1;
  48704             soc_reg_t   reg;
  48705 #if defined(BCM_KATANA2_SUPPORT)
  48706             uint32 val;
  48707 #endif
  48708             if (!IS_HG_PORT(unit, port)) {
  48709                 LOG_ERROR(
  48710                     BSL_LS_BCM_PORT,
  48711                     (BSL_META_U(unit,
  48712                                 "Error: unit %d port %d is not a Higig port. "
  48713                                 "E2EFC messages can only be transmitted to "
  48714                                 "or received from Higig ports.\n"),
  48715                      unit, port));
  48716                 return BCM_E_PARAM;
  48717             }
  48718 #if defined(BCM_KATANA2_SUPPORT)
  48719             if (SOC_IS_KATANA2(unit)) {
  48720 #if defined(BCM_SABER2_SUPPORT)
  48721                if (SOC_IS_SABER2(unit)) {
  48722                     /* Do nothing */
  48723                 } else
  48724 #endif /* BCM_SABER2_SUPPORT */
  48725                {
  48726                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  48727                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  48728                     *value = val_hi & 0xffffff;
  48729                     rv = BCM_E_NONE;
  48730                     break;
  48731                }
  48732             }
  48733 #endif /* BCM_KATANA2_SUPPORT */
  48734 
  48735             if (IS_XL_PORT(unit, port)) {
  48736                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  48737             } else if (IS_CL_PORT(unit, port)) {
  48738                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  48739             } else {
  48740                 return BCM_E_PARAM;
  48741             }
  48742 
  48743             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  48744                                             port, 0, &val_64));
  48745             data_1 = soc_reg64_field_get(unit, reg,
  48746                                          val_64, E2EFC_DATA_HDR_1f);
  48747             COMPILER_64_TO_32_HI(val_hi, data_1);
  48748             *value = val_hi & 0xffffff;
  48749             rv = BCM_E_NONE;
  48750         }
  48751         break;
  48752     case bcmPortControlE2EFCEtherType:
  48753         if (soc_feature(unit, soc_feature_e2efc)) {
  48754             uint32 val_lo;
  48755             uint64 val_64, data_1;
  48756             soc_reg_t reg;
  48757 #if defined(BCM_KATANA2_SUPPORT)
  48758             uint32 val;
  48759 #endif
  48760             if (!IS_HG_PORT(unit, port)) {
  48761                 LOG_ERROR(
  48762                     BSL_LS_BCM_PORT,
  48763                     (BSL_META_U(unit,
  48764                                 "Error: unit %d port %d is not a Higig port. "
  48765                                 "E2EFC messages can only be transmitted to "
  48766                                 "or received from Higig ports.\n"),
  48767                      unit, port));
  48768                 return BCM_E_PARAM;
  48769             }
  48770 #if defined(BCM_KATANA2_SUPPORT)
  48771             if (SOC_IS_KATANA2(unit)) {
  48772 #if defined(BCM_SABER2_SUPPORT)
  48773                if (SOC_IS_SABER2(unit)) {
  48774                     /* Do nothing */
  48775                 } else
  48776 #endif /* BCM_SABER2_SUPPORT */
  48777                {
  48778                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  48779                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  48780                     *value = (val_lo >> 16) & 0xffff;
  48781                     rv = BCM_E_NONE;
  48782                     break;
  48783                }
  48784             }
  48785 #endif /* BCM_KATANA2_SUPPORT */
  48786             if (IS_XL_PORT(unit, port)) {
  48787                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  48788             } else if (IS_CL_PORT(unit, port)) {
  48789                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  48790             } else {
  48791                 return BCM_E_PARAM;
  48792             }
  48793 
  48794             BCM_IF_ERROR_RETURN(
  48795                 soc_reg_get(unit, reg, port, 0, &val_64));
  48796                 data_1 = soc_reg64_field_get(unit, reg,
  48797                                              val_64, E2EFC_DATA_HDR_1f);
  48798             COMPILER_64_TO_32_LO(val_lo, data_1);
  48799             *value = (val_lo >> 16) & 0xffff;
  48800             rv = BCM_E_NONE;
  48801         }
  48802         break;
  48803     case bcmPortControlE2EFCOpcode:
  48804         if (soc_feature(unit, soc_feature_e2efc)) {
  48805             uint32 val_lo;
  48806             uint64 val_64, data_1;
  48807             soc_reg_t reg;
  48808 #if defined(BCM_KATANA2_SUPPORT)
  48809             uint32 val;
  48810 #endif
  48811             if (!IS_HG_PORT(unit, port)) {
  48812                 LOG_ERROR(
  48813                     BSL_LS_BCM_PORT,
  48814                     (BSL_META_U(unit,
  48815                                 "Error: unit %d port %d is not a Higig port. "
  48816                                 "E2EFC messages can only be transmitted to "
  48817                                 "or received from Higig ports.\n"),
  48818                      unit, port));
  48819                 return BCM_E_PARAM;
  48820             }
  48821 #if defined(BCM_KATANA2_SUPPORT)
  48822             if (SOC_IS_KATANA2(unit)) {
  48823 #if defined(BCM_SABER2_SUPPORT)
  48824                if (SOC_IS_SABER2(unit)) {
  48825                     /* Do nothing */
  48826                 } else
  48827 #endif /* BCM_SABER2_SUPPORT */
  48828                {
  48829                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  48830                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  48831                     *value = val_lo & 0xffff;
  48832                     rv = BCM_E_NONE;
  48833                     break;
  48834                }
  48835             }
  48836 #endif /* BCM_KATANA2_SUPPORT */
  48837             if (IS_XL_PORT(unit, port)) {
  48838                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  48839             } else if (IS_CL_PORT(unit, port)) {
  48840                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  48841             } else {
  48842                 return BCM_E_PARAM;
  48843             }
  48844 
  48845             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  48846                                             port, 0, &val_64));
  48847             data_1 = soc_reg64_field_get(unit, reg,
  48848                                          val_64, E2EFC_DATA_HDR_1f);
  48849             COMPILER_64_TO_32_LO(val_lo, data_1);
  48850             *value = val_lo & 0xffff;
  48851             rv = BCM_E_NONE;
  48852         }
  48853         break;
  48854     case bcmPortControlIntEnable:
  48855 #if defined(BCM_TOMAHAWK3_SUPPORT)
  48856         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  48857             rv = _bcm_esw_port_tab_get(unit, port, INT_ENABLEf, value);
  48858         }
  48859 #endif
  48860         break;
  48861     case bcmPortControlIntTurnaround:
  48862 #if defined(BCM_TOMAHAWK3_SUPPORT)
  48863         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  48864             SOC_IF_ERROR_RETURN
  48865                 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  48866                                      &int_turnaround_en_bmap_entry));
  48867             soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm,
  48868                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  48869             *value = 0;
  48870             if (SOC_PBMP_MEMBER(pbmp, port)) {
  48871                 *value = 1;
  48872             }
  48873 
  48874             rv = BCM_E_NONE;
  48875         }
  48876 #endif
  48877         break;
  48878     case bcmPortControlObmClassifierPriority:
  48879     case bcmPortControlObmClassifierEnableDscp:
  48880     case bcmPortControlObmClassifierEnableMpls:
  48881     case bcmPortControlObmClassifierEnableEtag:
  48882     case bcmPortControlObmClassifierEtagEthertype:
  48883     case bcmPortControlObmClassifierVntagEthertype:
  48884 
  48885 #if defined(BCM_MONTEREY_SUPPORT)
  48886         if (SOC_IS_MONTEREY(unit)) {
  48887             rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value);
  48888         } else
  48889 #endif
  48890 #if defined(BCM_APACHE_SUPPORT)
  48891         if (SOC_IS_APACHE(unit)) {
  48892             rv = bcm_apache_obm_classifier_port_control_get(unit, port, type, value);
  48893         } else
  48894 #endif
  48895 #if defined(BCM_HELIX5_SUPPORT)
  48896         if (SOC_IS_HELIX5(unit)) {
  48897             rv = bcm_hx5_obm_classifier_port_control_get(unit, port, type, value);
  48898         } else
  48899 #endif
  48900 #if defined(BCM_TRIDENT3_SUPPORT)
  48901         if (soc_feature(unit, soc_feature_td3_style_obm_classifier_map)) {
  48902             rv = bcm_td3_obm_classifier_port_control_get(unit, port, type, value);
  48903         } else
  48904 #endif
  48905         {
  48906             rv = BCM_E_UNAVAIL;
  48907         }
  48908         break;
  48909     case bcmPortControlObmClassifierInternal:
  48910 #if defined(BCM_MONTEREY_SUPPORT)
  48911         if (SOC_IS_MONTEREY(unit)) {
  48912             rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value);
  48913         } else
  48914 #endif
  48915         {
  48916             rv = BCM_E_UNAVAIL;
  48917         }
  48918         break;
  48919 
  48920    case bcmPortControlWirelessCosMapSelect:
  48921 #if defined(BCM_HELIX5_SUPPORT)
  48922         if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit)) {
  48923             rv = _bcm_esw_port_tab_get(unit, port, WIRED_WIRELESSf, value);
  48924         } else
  48925 #endif
  48926         {
  48927            rv = BCM_E_UNAVAIL;
  48928         }
  48929     break;
  48930 
  48931    case bcmPortControlHiGigCosSelect:
  48932 #if defined(BCM_HURRICANE4_SUPPORT)
  48933         if (SOC_IS_HURRICANE4(unit)) {
  48934             rv = bcm_hr4_hgcos_select_port_control_get(unit, port, type, value);
  48935         } else
  48936 #endif
  48937 #if defined(BCM_HELIX5_SUPPORT)
  48938         if (SOC_IS_HELIX5(unit)) {
  48939             rv = bcm_hx5_hgcos_select_port_control_get(unit, port, type, value);
  48940         } else
  48941 #endif
  48942         {
  48943            rv = BCM_E_UNAVAIL;
  48944         }
  48945     break;
  48946     case bcmPortControlInternalLoopback:
  48947 #ifdef BCM_TRIDENT3_SUPPORT
  48948         if (SOC_IS_TRIDENT3X(unit)) {
  48949             int port_type;
  48950             rv = _bcm_esw_port_tab_get(unit, port, PORT_TYPEf, &port_type);
  48951             (port_type == 2) ? (*value = 1) : (*value = 0);
  48952         } else
  48953 #endif
  48954         {
  48955             rv = BCM_E_UNAVAIL;
  48956         }
  48957     break;
  48958 #ifdef BCM_MONTEREY_SUPPORT
  48959     case bcmPortControlObmInterruptTypeDropPreempt :
  48960     case bcmPortControlObmInterruptTypeOverflowPreempt :
  48961     case bcmPortControlObmInterruptTypeDropExpress :
  48962     case  bcmPortControlObmInterruptTypeOverflowExpress :
  48963         if (SOC_IS_MONTEREY(unit)) {
  48964             rv = bcm_mn_obm_interrupt_port_control_get(unit, port, type, value);
  48965 
  48966         }else
  48967 #endif
  48968         {
  48969             rv = BCM_E_UNAVAIL;
  48970         }
  48971         break;
  48972     case bcmPortControlRuntThreshold:
  48973         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  48974                              SOC_MAC_CONTROL_RX_RUNT_THRESHOLD, value);
  48975         break;
  48976     case bcmPortControlPacketProcssingPort:
  48977 #ifdef BCM_TRIDENT3_SUPPORT
  48978         if (soc_feature(unit, soc_feature_pp_port_control)) {
  48979             rv = bcmi_td3_port_pp_num_get(unit, port, value);
  48980         } else
  48981 #endif /* BCM_TRIDENT3_SUPPORT */
  48982         {
  48983             rv = BCM_E_UNAVAIL;
  48984         }
  48985         break;
  48986      default:
  48987         break;
  48988     }
  48989 
  48990     if (BCM_SUCCESS(rv)) {
  48991         LOG_INFO(BSL_LS_BCM_PORT,
  48992                  (BSL_META_U(unit,
  48993                              "bcm_port_control_get: u=%d p=%d v=%d\n"),
  48994                   unit, port, *value));
  48995     } else {
  48996         /* On error, the value is not guaranteed valid */
  48997         LOG_INFO(BSL_LS_BCM_PORT,
  48998                  (BSL_META_U(unit,
  48999                              "bcm_port_control_get failure: u=%d p=%d: %s\n"),
  49000                   unit, port, bcm_errmsg(rv)));
  49001     }
  49002 
  49003     return rv;
  49004 }
  49005 
  49006 /*
  49007  * Function:
  49008  *      bcm_esw_port_mac_failover_notify
  49009  * Description:
  49010  *      disable RX routine on MAC
  49011  *      note: omitting XLMAC since it should not be disabled during failover
  49012  * Parameters:
  49013  *      unit - Device number
  49014  *      port - Port number
  49015  * Return Value:
  49016  *      BCM_E_NONE
  49017  *      BCM_E_UNAVAIL - Functionality not available
  49018  */
  49019 int
  49020 _bcm_esw_port_mac_failover_notify(int unit, bcm_port_t port)
  49021 {
  49022     int rv = BCM_E_NONE;
  49023 
  49024     if (!SOC_PORT_USE_PORTCTRL(unit, port)) {
  49025         /* disable RX for MAC and XMAC controller.
  49026            for TD2, lag failover has been implemented within XLMAC;
  49027            thus, XLMAC rx should not be disabled during failover */
  49028         PORT_LOCK(unit);
  49029         rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  49030                           SOC_MAC_CONTROL_FAILOVER_RX_SET, FALSE));
  49031         PORT_UNLOCK(unit);
  49032     }
  49033     return rv;
  49034 }
  49035 
  49036 
  49037 /*
  49038  * Function:
  49039  *      _bcm_esw_port_policer_get
  49040  * Purpose:
  49041  *       Internal function to Retrieve the Policer ID accociated
  49042  *       with specified physical port.
  49043  * Parameters:
  49044  *     Unit                  - (IN) unit number
  49045  *     port                  - (IN) Port Number
  49046  *     policer_id            - (OUT) policer Id
  49047  * Returns:
  49048  *     BCM_E_XXX
  49049  */
  49050 int _bcm_esw_port_policer_get(
  49051     int unit,
  49052     bcm_port_t port,
  49053     bcm_policer_t *policer_id)
  49054 {
  49055     int rv = BCM_E_NONE;
  49056 
  49057 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  49058     defined(BCM_GREYHOUND2_SUPPORT)
  49059     int index = 0;
  49060     int offset_mode = 0;
  49061 
  49062     BCM_IF_ERROR_RETURN
  49063             (_bcm_esw_port_config_get(unit, port,
  49064                                       _bcmPortSvcMeterIndex, &index));
  49065     BCM_IF_ERROR_RETURN
  49066             (_bcm_esw_port_config_get(unit, port,
  49067                                     _bcmPortSvcMeterOffsetMode, &offset_mode));
  49068     _bcm_esw_get_policer_id_from_index_offset(unit, index,
  49069                                                     offset_mode, policer_id);
  49070 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49071           BCM_GREYHOUND2_SUPPORT */
  49072     return rv;
  49073 }
  49074 
  49075 /*
  49076  * Function:
  49077  *      bcm_esw_port_policer_get
  49078  * Purpose:
  49079  *       Retrieve the Policer ID accociated for the specified physical port.
  49080  * Parameters:
  49081  *     Unit                  - (IN) unit number
  49082  *     port                  - (IN) Port Number
  49083  *     policer_id            - (OUT) policer Id
  49084  * Returns:
  49085  *     BCM_E_XXX
  49086  */
  49087 int bcm_esw_port_policer_get(
  49088     int unit,
  49089     bcm_port_t port,
  49090     bcm_policer_t *policer_id)
  49091 {
  49092 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  49093     defined(BCM_GREYHOUND2_SUPPORT)
  49094     int rv = BCM_E_NONE;
  49095 
  49096     /* Make sure port module is initialized. */
  49097     PORT_INIT(unit);
  49098     if (!soc_feature(unit, soc_feature_global_meter)) {
  49099         return BCM_E_UNAVAIL;
  49100     }
  49101     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  49102     rv = _bcm_esw_port_gport_validate(unit, port, &port);
  49103     BCM_IF_ERROR_RETURN(rv);
  49104     rv = _bcm_esw_port_policer_get(unit, port, policer_id);
  49105     return rv;
  49106 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49107          BCM_GREYHOUND2_SUPPORT */
  49108     return BCM_E_UNAVAIL;
  49109 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49110           BCM_GREYHOUND2_SUPPORT */
  49111 }
  49112 
  49113 #if defined(BCM_GLOBAL_METER_V2_SUPPORT)
  49114 /*
  49115  * Function:
  49116  *     bcmi_esw_port_policer_set
  49117  * Purpose:
  49118  *     Set the Policer ID accociated for the specified physical port.
  49119  * Parameters:
  49120  *     Unit                  - (IN) unit number
  49121  *     port                  - (IN) Port Number
  49122  *     policer_id            - (IN) policer Id
  49123  * Returns:
  49124  *     BCM_E_XXX
  49125  */
  49126 STATIC int
  49127 bcmi_esw_port_policer_set(
  49128     int unit,
  49129     bcm_port_t port,
  49130     bcm_policer_t policer_id)
  49131 {
  49132     int rv = BCM_E_UNAVAIL;
  49133 #if defined(BCM_GREYHOUND2_SUPPORT)
  49134     int index = 0;
  49135     int offset_mode = 0;
  49136     bcm_policer_t current_policer_id = 0;
  49137 
  49138     if (SOC_IS_GREYHOUND2(unit)) {
  49139         /* Make sure port module is initialized. */
  49140         PORT_INIT(unit);
  49141         if (!soc_feature(unit, soc_feature_global_meter)) {
  49142             return BCM_E_UNAVAIL;
  49143         }
  49144         BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  49145         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  49146         BCM_IF_ERROR_RETURN(rv);
  49147         /* validate policer id */
  49148         rv = _bcm_esw_policer_validate(unit, &policer_id);
  49149         if (BCM_FAILURE(rv)) {
  49150             LOG_VERBOSE(BSL_LS_BCM_PORT,
  49151                         (BSL_META_U(unit,
  49152                                     "Invalid policer id passed: %x \n"),
  49153                          policer_id));
  49154             return (rv);
  49155         }
  49156         /* get the policer id that is currently configured */
  49157         rv = _bcm_esw_port_policer_get(unit, port, &current_policer_id);
  49158         if (BCM_FAILURE(rv)) {
  49159             LOG_VERBOSE(BSL_LS_BCM_PORT,
  49160                         (BSL_META_U(unit,
  49161                                     "Unabel to get the current policer configured \n")));
  49162             return (rv);
  49163         }
  49164 
  49165         /* Set policer id */
  49166         BCM_IF_ERROR_RETURN(
  49167             _bcm_esw_get_policer_table_index(unit, policer_id, &index));
  49168         BCM_IF_ERROR_RETURN(
  49169             _bcm_esw_policer_offset_mode_get(unit, policer_id, &offset_mode));
  49170 
  49171         BCM_IF_ERROR_RETURN(
  49172             _bcm_esw_port_config_set(
  49173                 unit, port, _bcmPortSvcMeterIndex, index));
  49174         BCM_IF_ERROR_RETURN(
  49175             _bcm_esw_port_config_set(
  49176                 unit, port, _bcmPortSvcMeterOffsetMode, offset_mode));
  49177 
  49178         /* increment new set policer ref_cnt */
  49179         rv = _bcm_esw_policer_increment_ref_count(unit, policer_id);
  49180         BCM_IF_ERROR_RETURN(rv);
  49181 
  49182         /* decrement current hw policer ref_cnt */
  49183         rv = _bcm_esw_policer_validate(unit, &current_policer_id);
  49184 
  49185         /* Don't need to handle fail case since existed index could be 0 */
  49186         if (BCM_SUCCESS(rv)) {
  49187             rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer_id);
  49188             BCM_IF_ERROR_RETURN(rv);
  49189         }
  49190 
  49191         rv = BCM_E_NONE;
  49192     }
  49193 #endif /* BCM_GREYHOUND2_SUPPORT */
  49194     return rv;
  49195 }
  49196 
  49197 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */
  49198 
  49199 /*
  49200  * Function:
  49201  *      bcm_esw_port_policer_set
  49202  * Purpose:
  49203  *      Set the Policer ID accociated for the specified physical port.
  49204  * Parameters:
  49205  *     Unit                  - (IN) unit number
  49206  *     port                  - (IN) Port Number
  49207  *     policer_id            - (IN) policer Id
  49208  * Returns:
  49209  *     BCM_E_XXX
  49210  */
  49211 int bcm_esw_port_policer_set(
  49212     int unit,
  49213     bcm_port_t port,
  49214     bcm_policer_t policer)
  49215 {
  49216 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||    \
  49217      defined(BCM_APACHE_SUPPORT))
  49218     int rv = BCM_E_NONE;
  49219     int index=0;
  49220     int offset_mode=0;
  49221     bcm_policer_t current_policer = 0;
  49222 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49223          BCM_APACHE_SUPPORT */
  49224 
  49225 #if defined(BCM_GLOBAL_METER_V2_SUPPORT)
  49226     if (soc_feature(unit, soc_feature_global_meter_v2)) {
  49227         return bcmi_esw_port_policer_set(unit, port, policer);
  49228     }
  49229 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */
  49230 
  49231 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||    \
  49232      defined(BCM_APACHE_SUPPORT))
  49233 
  49234     /* Make sure port module is initialized. */
  49235     PORT_INIT(unit);
  49236     if (!soc_feature(unit, soc_feature_global_meter)) {
  49237         return BCM_E_UNAVAIL;
  49238     }
  49239     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  49240     rv = _bcm_esw_port_gport_validate(unit, port, &port);
  49241     BCM_IF_ERROR_RETURN(rv);
  49242     /* validate policer id */
  49243     rv = _bcm_esw_policer_validate(unit, &policer);
  49244     if (BCM_FAILURE(rv)) {
  49245         LOG_VERBOSE(BSL_LS_BCM_PORT,
  49246                     (BSL_META_U(unit,
  49247                                 "Invalid policer id passed: %x \n"),
  49248                      policer));
  49249         return (rv);
  49250     }
  49251     /* get the policer id that is currently configured */
  49252     rv = _bcm_esw_port_policer_get(unit, port, &current_policer);
  49253     if (BCM_FAILURE(rv)) {
  49254         LOG_VERBOSE(BSL_LS_BCM_PORT,
  49255                     (BSL_META_U(unit,
  49256                                 "Unabel to get the current policer configured \n")));
  49257         return (rv);
  49258     }
  49259     rv = BCM_E_UNAVAIL;
  49260     /* Set policer id */
  49261     _bcm_esw_get_policer_table_index(unit, policer, &index);
  49262     offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >>
  49263                                     BCM_POLICER_GLOBAL_METER_MODE_SHIFT);
  49264     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  49265         if ((offset_mode == 0) && (policer != 0)) {
  49266             /*
  49267              * Not a Global meter policer,
  49268              * policer zero is used to detach already configured policer
  49269              */
  49270             return (BCM_E_PARAM);
  49271         }
  49272     }
  49273     if (offset_mode >= 1) {
  49274         offset_mode = offset_mode - 1;
  49275     }
  49276     if (index >= soc_mem_index_count(unit,SVM_METER_TABLEm))  {
  49277         LOG_VERBOSE(BSL_LS_BCM_PORT,
  49278                     (BSL_META_U(unit,
  49279                                 "Invalid table index\n")));
  49280         return BCM_E_PARAM;
  49281     }
  49282     if (offset_mode >= (soc_mem_index_count(unit,SVM_OFFSET_TABLEm) >>
  49283                                BCM_POLICER_SVC_METER_OFFSET_TABLE_KEY_SIZE))  {
  49284         LOG_VERBOSE(BSL_LS_BCM_PORT,
  49285                     (BSL_META_U(unit,
  49286                                 "Invalid offset mode\n")));
  49287         return BCM_E_PARAM;
  49288     }
  49289     BCM_IF_ERROR_RETURN(
  49290             _bcm_esw_port_config_set(unit, port,
  49291                                       _bcmPortSvcMeterIndex, index));
  49292     BCM_IF_ERROR_RETURN(
  49293              _bcm_esw_port_config_set(unit, port,
  49294                                      _bcmPortSvcMeterOffsetMode, offset_mode));
  49295     /* decrement current policer if any */
  49296     if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) {
  49297         rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
  49298         BCM_IF_ERROR_RETURN(rv);
  49299     }
  49300     /* increment policer reference count */
  49301     if ((policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0 ) {
  49302         rv = _bcm_esw_policer_increment_ref_count(unit, policer);
  49303         BCM_IF_ERROR_RETURN(rv);
  49304     }
  49305     return rv;
  49306 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49307          BCM_APACHE_SUPPORT */
  49308     return BCM_E_UNAVAIL;
  49309 #endif
  49310 }
  49311 
  49312 /*
  49313  * Function:
  49314  *      bcm_port_vlan_inner_tag_set
  49315  * Purpose:
  49316  *      Set the inner tag to be added to the packet.
  49317  * Parameters:
  49318  *      unit       - (IN) BCM unit.
  49319  *      port       - (IN) Port number.
  49320  *      inner_tag  - (IN) Inner tag.
  49321  *                    Priority[15:13] CFI[12] VLAN ID [11:0]
  49322  * Returns:
  49323  *      BCM_E_XXX
  49324  */
  49325 int
  49326 bcm_esw_port_vlan_inner_tag_set(int unit, bcm_port_t port, uint16 inner_tag)
  49327 {
  49328     int rv;
  49329 
  49330     /* Make sure port module is initialized. */
  49331     PORT_INIT(unit);
  49332 
  49333     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49334 
  49335     rv = BCM_E_UNAVAIL;
  49336 
  49337 #ifdef BCM_TRX_SUPPORT
  49338     if (SOC_IS_TRX(unit)) {
  49339         bcm_vlan_action_set_t action;
  49340 
  49341         if (!soc_feature(unit, soc_feature_vlan_action)) {
  49342             return BCM_E_UNAVAIL;
  49343         }
  49344 
  49345         PORT_LOCK(unit);
  49346         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  49347             (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
  49348         action.new_inner_vlan = BCM_VLAN_CTRL_ID(inner_tag);
  49349 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  49350         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  49351             rv =_bcm_trx_vlan_port_default_action_profile_set(unit, port, &action);
  49352         } else
  49353 #endif
  49354         {
  49355             rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action);
  49356         }
  49357         PORT_UNLOCK(unit);
  49358         return rv;
  49359     }
  49360 #endif
  49361 
  49362 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  49363     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  49364         PORT_LOCK(unit);
  49365 
  49366         rv = soc_reg_field32_modify(unit, EGR_SRC_PORTr, port,
  49367                                     INNER_TAGf, inner_tag);
  49368         PORT_UNLOCK(unit);
  49369     }
  49370 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  49371 
  49372     return rv;
  49373 }
  49374 
  49375 /*
  49376  * Function:
  49377  *      bcm_port_vlan_inner_tag_get
  49378  * Purpose:
  49379  *      Get the inner tag to be added to the packet.
  49380  * Parameters:
  49381  *      unit       - (IN) BCM unit.
  49382  *      port       - (IN) Port number.
  49383  *      inner_tag  - (OUT) Inner tag.
  49384  *                    Priority[15:13] CFI[12] VLAN ID [11:0]
  49385  * Returns:
  49386  *      BCM_E_XXX
  49387  */
  49388 int
  49389 bcm_esw_port_vlan_inner_tag_get(int unit, bcm_port_t port, uint16 *inner_tag)
  49390 {
  49391     int rv;
  49392 
  49393     /* Make sure port module is initialized. */
  49394     PORT_INIT(unit);
  49395 
  49396     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49397 
  49398     rv = BCM_E_UNAVAIL;
  49399 
  49400 #ifdef BCM_TRX_SUPPORT
  49401     if (SOC_IS_TRX(unit)) {
  49402         bcm_vlan_action_set_t action;
  49403 
  49404         if (!soc_feature(unit, soc_feature_vlan_action)) {
  49405             return BCM_E_UNAVAIL;
  49406         }
  49407 
  49408         PORT_LOCK(unit);
  49409         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  49410             (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
  49411         *inner_tag = action.new_inner_vlan;
  49412         PORT_UNLOCK(unit);
  49413         return BCM_E_NONE;
  49414     }
  49415 #endif
  49416 
  49417 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  49418         if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  49419         uint32 value;
  49420 
  49421         rv = READ_EGR_SRC_PORTr(unit, port, &value);
  49422         *inner_tag = soc_reg_field_get(unit, EGR_SRC_PORTr, value,
  49423                                        INNER_TAGf);
  49424     }
  49425 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  49426     return rv;
  49427 }
  49428 
  49429 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT_SUPPORT)
  49430 STATIC int
  49431 _bcm_esw_port_vp_type_id_get(int unit, bcm_port_t port,
  49432                              _bcm_vp_type_e *vp_type, int *vp)
  49433 {
  49434     *vp = -1;
  49435     *vp_type = _bcmVpTypeAny;
  49436 
  49437     if (BCM_GPORT_IS_MIM_PORT(port) && soc_feature(unit, soc_feature_mim)) {
  49438         *vp_type = _bcmVpTypeMim;
  49439         *vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  49440     } else if (BCM_GPORT_IS_TRILL_PORT(port) && soc_feature(unit, soc_feature_trill)) {
  49441         *vp_type = _bcmVpTypeTrill;
  49442         *vp = BCM_GPORT_TRILL_PORT_ID_GET(port);
  49443     } else if (BCM_GPORT_IS_VXLAN_PORT(port) && soc_feature(unit, soc_feature_vxlan)) {
  49444         *vp_type = _bcmVpTypeVxlan;
  49445         *vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  49446     } else if (BCM_GPORT_IS_MPLS_PORT(port) && soc_feature(unit, soc_feature_mpls)) {
  49447         *vp_type = _bcmVpTypeMpls;
  49448         *vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  49449     } else if (BCM_GPORT_IS_EXTENDER_PORT(port) && soc_feature(unit, soc_feature_port_extension)) {
  49450         *vp_type = _bcmVpTypeExtender;
  49451         *vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
  49452     } else if (BCM_GPORT_IS_WLAN_PORT(port) && soc_feature(unit, soc_feature_wlan)) {
  49453         *vp_type = _bcmVpTypeWlan;
  49454         *vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  49455     } else if (BCM_GPORT_IS_NIV_PORT(port) && soc_feature(unit, soc_feature_niv)) {
  49456         *vp_type = _bcmVpTypeNiv;
  49457         *vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  49458     } else if (BCM_GPORT_IS_VLAN_PORT(port) && soc_feature(unit, soc_feature_vlan_vp)) {
  49459         *vp_type = _bcmVpTypeVlan;
  49460         *vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  49461     } else if (BCM_GPORT_IS_L2GRE_PORT(port) && soc_feature(unit, soc_feature_l2gre)) {
  49462         *vp_type = _bcmVpTypeL2Gre;
  49463         *vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  49464     } else if (BCM_GPORT_IS_FLOW_PORT(port) && soc_feature(unit, soc_feature_flex_flow)) {
  49465         *vp_type = _bcmVpTypeFlow;
  49466         *vp = BCM_GPORT_FLOW_PORT_ID_GET(port);
  49467     } else if (BCM_GPORT_IS_TRUNK(port) && soc_feature(unit, soc_feature_vp_lag)) {
  49468         *vp_type = _bcmVpTypeVpLag;
  49469         BCM_IF_ERROR_RETURN(
  49470             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  49471                                             vp));
  49472     }
  49473     return BCM_E_NONE;
  49474 }
  49475 #endif
  49476 
  49477 /*
  49478  * Function    :
  49479  *     bcm_port_class_set
  49480  * Description :
  49481  *     Set the ports class ID. Ports with the
  49482  *     same class ID can be treated as a group in
  49483  *     field processing and VLAN translation.
  49484  * Parameters  :
  49485  *     (IN) unit      - BCM device number
  49486  *     (IN) port      - Device or logical port number
  49487  *     (IN) pclass    - Classification type
  49488  *     (IN) pclass_id - New class ID of the port.
  49489  * Returns     :
  49490  *     BCM_E_NONE     - Success
  49491  *     BCM_E_XXX      - Failed
  49492  */
  49493 int
  49494 bcm_esw_port_class_set(int unit, bcm_port_t port,
  49495                        bcm_port_class_t pclass, uint32 pclass_id)
  49496 {
  49497     int        rv = BCM_E_UNAVAIL;
  49498     bcm_port_t port_out = port;
  49499 #if defined(BCM_TOMAHAWK_SUPPORT)
  49500     soc_mem_t port_mem = PORT_TABm;
  49501 #endif
  49502 
  49503     /* Make sure port module is initialized. */
  49504     PORT_INIT(unit);
  49505 
  49506 #if defined(INCLUDE_L3)
  49507 #if defined(BCM_TRIDENT_SUPPORT)
  49508     if (BCM_GPORT_IS_SET(port)) {
  49509         int vp;
  49510         _bcm_vp_type_e vp_type;
  49511         BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port,
  49512                                                          &vp_type, &vp));
  49513         switch (pclass) {
  49514         case bcmPortClassFieldIngress:
  49515             if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill ||
  49516                 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls ||
  49517                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan ||
  49518                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan ||
  49519                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag ||
  49520                 vp_type == _bcmVpTypeFlow){
  49521 
  49522                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49523                     return BCM_E_PORT;
  49524                 }
  49525                 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, CLASS_IDf, pclass_id);
  49526                 return rv;
  49527             }
  49528             break;
  49529         case bcmPortClassVlanTranslateEgress:
  49530 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49531             /* class_id of DVP used in egress VLAN translation */
  49532         /* class_id of DVP used in egress VLAN translation */
  49533             if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) ||
  49534                  (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre) ||
  49535                  (vp_type == _bcmVpTypeFlow) ) {
  49536                 int network_port;
  49537                 source_vp_entry_t svp;
  49538                 _bcm_vp_info_t vp_info;
  49539 
  49540                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49541                     return BCM_E_PORT;
  49542                 }
  49543                 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
  49544                 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  49545                 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
  49546                     network_port = TRUE;
  49547                 } else {
  49548                     network_port = FALSE;
  49549                 }
  49550 
  49551                 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  49552                                                         VT_DVP_GROUP_IDf)
  49553 #if defined(BCM_TRIDENT3_SUPPORT)
  49554                   || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  49555                                                         COMMON__VT_DVP_GROUP_IDf))
  49556 #endif
  49557                     ) {
  49558                     if ((network_port) && (vp_type == _bcmVpTypeVxlan)) {
  49559                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  49560                                                     VXLAN__VT_DVP_GROUP_IDf, pclass_id);
  49561                     } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) {
  49562                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  49563                                                     L2GRE__VT_DVP_GROUP_IDf, pclass_id);
  49564                     } else {
  49565                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  49566                                                     COMMON__VT_DVP_GROUP_IDf, pclass_id);
  49567                     }
  49568                 } else {
  49569                     return BCM_E_UNAVAIL;
  49570                 }
  49571                 return rv;
  49572             }
  49573 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  49574             break;
  49575 #if defined(BCM_TOMAHAWK_SUPPORT)
  49576         case bcmPortClassFieldIngressSourceGport:
  49577             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  49578                 return BCM_E_UNAVAIL;
  49579             }
  49580             if (pclass_id > 33) {
  49581                 return BCM_E_PARAM;
  49582             }
  49583             if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan ||
  49584                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag ||
  49585                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls ||
  49586                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim ||
  49587                 vp_type == _bcmVpTypeFlow) {
  49588                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49589                     return BCM_E_PORT;
  49590                 }
  49591                 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp,
  49592                                             IPBM_INDEXf, pclass_id);
  49593                 return rv;
  49594             }
  49595             break;
  49596 #endif /* BCM_TOMAHAWK_SUPPORT */
  49597 
  49598         default:
  49599             break;
  49600         }
  49601     }
  49602 #endif /* BCM_TRIDENT_SUPPORT*/
  49603 #endif /* INCLUDE_L3 */
  49604 
  49605 #ifdef BCM_XGS3_SWITCH_SUPPORT
  49606     if (SOC_IS_XGS3_SWITCH(unit)) {
  49607 #if defined(BCM_TOMAHAWK_SUPPORT)
  49608         bcm_module_t mod;
  49609         bcm_trunk_t tid_out;
  49610         int id_out;
  49611         int index;
  49612 #endif /* BCM_TOMAHAWK_SUPPORT */
  49613         switch (pclass) {
  49614             case bcmPortClassFieldIngressSystemPort:
  49615 #if defined(BCM_TOMAHAWK_SUPPORT)
  49616                 if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  49617                     return BCM_E_UNAVAIL;
  49618                 }
  49619                 if (pclass_id > 33) {
  49620 #if defined(BCM_TRIDENT3_SUPPORT)
  49621                     if (!SOC_IS_TRIDENT3X(unit) ||
  49622                       soc_feature(unit, soc_feature_ifp_no_inports_support))
  49623 #endif
  49624                     return BCM_E_PARAM;
  49625                 }
  49626                 if (BCM_GPORT_IS_SET(port)) {
  49627                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  49628                                         &mod, &port_out, &tid_out, &id_out));
  49629                     if (-1 != tid_out || -1 != id_out) {
  49630                         return BCM_E_PORT;
  49631                     }
  49632                 } else {
  49633                     if (!SOC_PORT_VALID(unit, port)) {
  49634                         return BCM_E_PORT;
  49635                     }
  49636                     port_out = port;
  49637                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod));
  49638                 }
  49639                 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
  49640                                     mod, port_out, &index));
  49641 #if defined(BCM_TRIDENT3_SUPPORT)
  49642                 if (SOC_IS_TRIDENT3X(unit) &&
  49643                       !soc_feature(unit, soc_feature_ifp_no_inports_support)) {
  49644                     rv = bcm_td3_port_ipbm_opaque_set(unit, index, pclass_id);
  49645                     return rv;
  49646                 }
  49647 #endif
  49648                 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, index,
  49649                                                 IPBM_INDEXf, pclass_id);
  49650                 return rv;
  49651 #endif /* BCM_TOMAHAWK_SUPPORT */
  49652                 break;
  49653             default:
  49654                 break;
  49655         }
  49656     }
  49657 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  49658     /*
  49659      * Skip port validation if soc_feature_shg_support_remote_port
  49660      * is true and ptype is bcmPortClassFieldIngress.
  49661      */
  49662     if (!(soc_feature(unit, soc_feature_shg_support_remote_port) &&
  49663         (pclass == bcmPortClassFieldIngress))) {
  49664     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  49665     }
  49666 
  49667 
  49668 #ifdef BCM_XGS3_SWITCH_SUPPORT
  49669     if (SOC_IS_XGS3_SWITCH(unit)) {
  49670 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49671         int        port_class_id;
  49672         soc_reg_t egr_port_reg;
  49673         egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  49674                         SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  49675                         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  49676                         EGR_PORT_64r : EGR_PORTr;
  49677 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  49678 
  49679         switch (pclass) {
  49680             case bcmPortClassFieldIngressGroupSel:
  49681 #if defined(BCM_TOMAHAWK_SUPPORT)
  49682                 if (SOC_IS_TRIDENT3X(unit)) {
  49683                     port_mem = LPORT_TABm;
  49684                 }
  49685                 if (soc_mem_field_valid(unit, port_mem, IFP_KEY_SEL_CLASS_IDf)) {
  49686                     rv = soc_mem_field_pbmp_fit(unit, port_mem,
  49687                                                 IFP_KEY_SEL_CLASS_IDf, &pclass_id);
  49688                     if (rv == BCM_E_NONE) {
  49689                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49690                                                    IFP_KEY_SEL_CLASS_IDf, pclass_id);
  49691                     }
  49692                 }
  49693 #endif
  49694                 break;
  49695         case bcmPortClassFieldLookup:
  49696 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49697             if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) ||
  49698                 SOC_IS_TRIDENT3X(unit)) {
  49699                 /* Intentional use of var pclass_id, to be filled here */
  49700                 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf)) {
  49701                     /* coverity [callee_ptr_arith] */
  49702                     rv = soc_mem_field_pbmp_fit(unit, PORT_TABm,
  49703                                 VFP_PORT_GROUP_IDf, &pclass_id);
  49704                 } else if (SOC_IS_TRIDENT3X(unit)) {
  49705                     rv = soc_mem_field_pbmp_fit(unit, LPORT_TABm,
  49706                                 VFP_PORT_GROUP_IDf, &pclass_id);
  49707                 }
  49708                 if (rv == BCM_E_NONE) {
  49709                     port_class_id = (int) pclass_id;
  49710                     rv = _bcm_esw_port_tab_set(unit, port,
  49711                                                _BCM_CPU_TABS_BOTH,
  49712                                                VFP_PORT_GROUP_IDf,
  49713                                                port_class_id);
  49714                 }
  49715             }
  49716 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  49717 #if defined(BCM_TRX_SUPPORT)
  49718             if ((SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  49719                                      VFP_PORT_GROUP_IDf)) &&
  49720                 (BCM_SUCCESS(rv))) {
  49721 #if defined(BCM_KATANA2_SUPPORT)
  49722                 if (SOC_IS_KATANA2(unit)) {
  49723                     rv = _bcm_kt2_source_trunk_map_set(unit, port_out,
  49724                                                    VFP_PORT_GROUP_IDf,
  49725                                                    pclass_id);
  49726                 } else
  49727 #endif
  49728                 {
  49729                     rv = _bcm_trx_source_trunk_map_set(unit, port,
  49730                                                    VFP_PORT_GROUP_IDf,
  49731                                                    pclass_id);
  49732                 }
  49733             }
  49734 #endif /* BCM_TRX_SUPPORT */
  49735             break;
  49736         case bcmPortClassVlanTranslateIngress:
  49737 #if defined(BCM_TRIDENT2_SUPPORT)
  49738             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) {
  49739                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  49740                                                    PORT_GROUPf, pclass_id);
  49741             }
  49742 #endif /* BCM_TRIDENT2_SUPPORT */
  49743             break;
  49744         case bcmPortClassFieldIngress:
  49745 #if defined(BCM_TRX_SUPPORT)
  49746             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) {
  49747 #if defined(BCM_KATANA2_SUPPORT)
  49748                 if (SOC_IS_KATANA2(unit)) {
  49749                     rv = _bcm_kt2_source_trunk_map_set(unit, port_out,
  49750                                                     CLASS_IDf, pclass_id);
  49751                 } else
  49752 #endif
  49753                 {
  49754                     rv = _bcm_trx_source_trunk_map_set(unit, port,
  49755                                                    CLASS_IDf, pclass_id);
  49756                 }
  49757             }
  49758 #endif /* BCM_TRX_SUPPORT */
  49759             break;
  49760         case bcmPortClassFieldEgress:
  49761 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49762             if (soc_reg_field_valid(unit, egr_port_reg, EGR_PORT_GROUP_IDf)) {
  49763                 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out,
  49764                                             EGR_PORT_GROUP_IDf, pclass_id);
  49765             }
  49766 #ifdef BCM_TRIDENT_SUPPORT
  49767             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) ||
  49768                      SOC_IS_TRIDENT3X(unit)) {
  49769                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  49770                                                EGR_PORT_GROUP_IDf, pclass_id);
  49771             }
  49772 #endif /* BCM_TRIDENT_SUPPORT */
  49773 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  49774             break;
  49775         case bcmPortClassVlanTranslateEgress:
  49776 #if defined(BCM_TRX_SUPPORT)
  49777             if (soc_reg_field_valid(unit, egr_port_reg, VT_PORT_GROUP_IDf)) {
  49778                 soc_control_t   *sc = SOC_CONTROL(unit);
  49779 
  49780                 if (sc->soc_flags & SOC_F_PORT_CLASS_BLOCKED) {
  49781                     return BCM_E_CONFIG;
  49782                 }
  49783                 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out,
  49784                                             VT_PORT_GROUP_IDf, pclass_id);
  49785                 if (BCM_SUCCESS(rv)) {
  49786                     /* Once port class is changed system will not allow */
  49787                     /* To use bcm_vlan_translate_egress */
  49788                     sc->soc_flags |= SOC_F_XLATE_EGR_BLOCKED;
  49789                 }
  49790             }
  49791 #ifdef BCM_TRIDENT_SUPPORT
  49792             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) ||
  49793                      SOC_IS_TRIDENT3X(unit)) {
  49794                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  49795                                                VT_PORT_GROUP_IDf, pclass_id);
  49796             }
  49797 #endif /* BCM_TRIDENT_SUPPORT */
  49798 #endif /* BCM_TRX_SUPPORT */
  49799             break;
  49800 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49801          case bcmPortClassEgress:
  49802             if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) ||
  49803                 SOC_IS_TRIDENT3X(unit)) {
  49804                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  49805                                                CLASS_IDf, pclass_id);
  49806             }
  49807             break;
  49808 #endif
  49809 #if defined(BCM_TOMAHAWK_SUPPORT)
  49810          case bcmPortClassFieldIngressDevicePort:
  49811             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  49812                 return BCM_E_UNAVAIL;
  49813             }
  49814             if (pclass_id > 33) {
  49815                 return BCM_E_PARAM;
  49816             }
  49817 #if defined (BCM_TOMAHAWK3_SUPPORT)
  49818             if (SOC_IS_TOMAHAWK3(unit)) {
  49819                 if (pclass_id > 19) {
  49820                     return BCM_E_PARAM;
  49821                 }
  49822             }
  49823 #endif
  49824 
  49825             if (BCM_GPORT_IS_SET(port)) {
  49826                 bcm_module_t mod;
  49827                 bcm_trunk_t tid_out;
  49828                 int id_out;
  49829                 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  49830                                     &mod, &port_out, &tid_out, &id_out));
  49831                 if (-1 != tid_out || -1 != id_out) {
  49832                     return BCM_E_PORT;
  49833                 }
  49834             } else {
  49835                 if (!SOC_PORT_VALID(unit, port)) {
  49836                     return BCM_E_PORT;
  49837                 }
  49838             }
  49839             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49840                                        PORT_IPBM_INDEXf, pclass_id);
  49841             break;
  49842 #endif /* BCM_TOMAHAWK_SUPPORT */
  49843         default:
  49844             rv = BCM_E_PARAM;
  49845         }
  49846     }
  49847 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  49848 
  49849     return rv;
  49850 }
  49851 
  49852 /*
  49853  * Function    :
  49854  *     bcm_port_class_get
  49855  * Description :
  49856  *     Get the ports class ID. Ports with the
  49857  *     same class ID can be treated as a group in
  49858  *     field processing and VLAN translation.
  49859  * Parameters  :
  49860  *     (IN) unit       - BCM device number
  49861  *     (IN) port       - Device or logical port number
  49862  *     (IN) pclass     - Classification type
  49863  *     (OUT) pclass_id - New class ID of the port.
  49864  * Returns     :
  49865  *     BCM_E_NONE      - Success
  49866  *     BCM_E_XXX       - Failed
  49867  */
  49868 int
  49869 bcm_esw_port_class_get(int unit, bcm_port_t port,
  49870                        bcm_port_class_t pclass, uint32 *pclass_id)
  49871 {
  49872     int        rv = BCM_E_UNAVAIL;
  49873     bcm_port_t port_out = port;
  49874 
  49875     /* Make sure port module is initialized. */
  49876     PORT_INIT(unit);
  49877 
  49878 #if defined(INCLUDE_L3)
  49879 #if defined(BCM_TRIDENT_SUPPORT)
  49880     if (BCM_GPORT_IS_SET(port)) {
  49881         int vp;
  49882         _bcm_vp_type_e vp_type;
  49883         source_vp_entry_t entry;
  49884         BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port,
  49885                                                          &vp_type, &vp));
  49886         switch (pclass) {
  49887         case bcmPortClassFieldIngress:
  49888             if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill ||
  49889                 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls ||
  49890                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan ||
  49891                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan ||
  49892                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag ||
  49893                 vp_type == _bcmVpTypeFlow){
  49894 
  49895                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49896                     return BCM_E_PORT;
  49897                 }
  49898                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry);
  49899                 if (BCM_SUCCESS(rv)) {
  49900                     *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm,
  49901                                                                         &entry, CLASS_IDf);
  49902                 }
  49903                 return rv;
  49904             }
  49905             break;
  49906         case bcmPortClassVlanTranslateEgress:
  49907 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49908           /* class_id of DVP used in egress VLAN translation */
  49909             if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) ||
  49910                 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre)) {
  49911                 int network_port;
  49912                 egr_dvp_attribute_entry_t dvp_entry;
  49913                 _bcm_vp_info_t vp_info;
  49914 
  49915                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49916                     return BCM_E_PORT;
  49917                 }
  49918 
  49919                 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  49920                 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
  49921                     network_port = TRUE;
  49922                 } else {
  49923                     network_port = FALSE;
  49924                 }
  49925 
  49926                 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  49927                                         VT_DVP_GROUP_IDf)
  49928 #if defined(BCM_TRIDENT3_SUPPORT)
  49929                   || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  49930                                                         COMMON__VT_DVP_GROUP_IDf))
  49931 #endif
  49932                    ) {
  49933                     rv = READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY,
  49934                                                                    vp, &dvp_entry);
  49935                     if (BCM_SUCCESS(rv)) {
  49936                         if ((network_port) && (vp_type == _bcmVpTypeVxlan)) {
  49937                             *pclass_id = soc_mem_field32_get
  49938                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry,
  49939                                          VXLAN__VT_DVP_GROUP_IDf);
  49940                        } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) {
  49941                             *pclass_id = soc_mem_field32_get
  49942                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry,
  49943                                          L2GRE__VT_DVP_GROUP_IDf);
  49944                        } else {
  49945                             *pclass_id = soc_mem_field32_get
  49946                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry,
  49947                                          COMMON__VT_DVP_GROUP_IDf);
  49948                        }
  49949                     }
  49950                 } else {
  49951                     return BCM_E_UNAVAIL;
  49952                 }
  49953                 return rv;
  49954             }
  49955 
  49956 #endif  /* BCM_TRIDENT2PLUS_SUPPORT */
  49957             break;
  49958 #if defined(BCM_TOMAHAWK_SUPPORT)
  49959         case bcmPortClassFieldIngressSourceGport:
  49960             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  49961                 return BCM_E_UNAVAIL;
  49962             }
  49963             if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan ||
  49964                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag ||
  49965                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls ||
  49966                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim ||
  49967                 vp_type == _bcmVpTypeFlow) {
  49968                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  49969                     return BCM_E_PORT;
  49970                 }
  49971                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry);
  49972                 if (BCM_SUCCESS(rv)) {
  49973                     *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm,
  49974                                                      &entry, IPBM_INDEXf);
  49975                 }
  49976                 return rv;
  49977             }
  49978             break;
  49979 #endif /* BCM_TOMAHAWK_SUPPORT */
  49980         default:
  49981             break;
  49982         }
  49983     }
  49984 #endif /* BCM_TRIDENT_SUPPORT */
  49985 #endif /* INCLUDE_L3 */
  49986 #ifdef BCM_XGS3_SWITCH_SUPPORT
  49987     if (SOC_IS_XGS3_SWITCH(unit)) {
  49988 #if defined(BCM_TOMAHAWK_SUPPORT)
  49989         source_trunk_map_table_entry_t entry;
  49990         bcm_module_t mod;
  49991         bcm_trunk_t tid_out;
  49992         int id_out;
  49993         int index;
  49994 #endif /* BCM_TOMAHAWK_SUPPORT */
  49995 
  49996         switch (pclass) {
  49997             case bcmPortClassFieldIngressSystemPort:
  49998 #if defined(BCM_TOMAHAWK_SUPPORT)
  49999                 if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  50000                     return BCM_E_UNAVAIL;
  50001                 }
  50002                 if (BCM_GPORT_IS_SET(port)) {
  50003                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  50004                                         &mod, &port_out, &tid_out, &id_out));
  50005                     if (-1 != tid_out || -1 != id_out) {
  50006                         return BCM_E_PORT;
  50007                     }
  50008                 } else {
  50009                     if (!SOC_PORT_VALID(unit, port)) {
  50010                         return BCM_E_PORT;
  50011                     }
  50012                     port_out = port;
  50013                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod));
  50014                 }
  50015                 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
  50016                                     mod, port_out, &index));
  50017 #if defined(BCM_TRIDENT3_SUPPORT)
  50018                 if (SOC_IS_TRIDENT3X(unit) &&
  50019                       !soc_feature(unit, soc_feature_ifp_no_inports_support)){
  50020                     rv = bcm_td3_port_ipbm_opaque_get(unit, index, pclass_id);
  50021                     return rv;
  50022                 }
  50023 #endif
  50024                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm,
  50025                                                  MEM_BLOCK_ANY, index, &entry));
  50026                 *pclass_id = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  50027                                &entry, IPBM_INDEXf);
  50028                 return BCM_E_NONE;
  50029 #endif /* BCM_TOMAHAWK_SUPPORT */
  50030                 break;
  50031             default:
  50032                 break;
  50033         }
  50034     }
  50035 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  50036     /*
  50037      * Skip port validation if soc_feature_shg_support_remote_port
  50038      * is true and ptype is bcmPortClassFieldIngress.
  50039      */
  50040     if (!(soc_feature(unit, soc_feature_shg_support_remote_port) &&
  50041         (pclass == bcmPortClassFieldIngress))) {
  50042     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  50043     }
  50044 
  50045     if (NULL == pclass_id) {
  50046         return BCM_E_PARAM;
  50047     }
  50048 
  50049 #ifdef BCM_XGS3_SWITCH_SUPPORT
  50050     if (SOC_IS_XGS3_SWITCH(unit)) {
  50051 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50052         uint32 reg_val;
  50053         uint64 reg_val64;
  50054         int    port_class_id;
  50055 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50056         switch (pclass) {
  50057             case bcmPortClassFieldIngressGroupSel:
  50058 #if defined(BCM_TOMAHAWK_SUPPORT)
  50059                 rv = _bcm_esw_port_tab_get(unit, port, IFP_KEY_SEL_CLASS_IDf,
  50060                                            (int32*) pclass_id);
  50061 #endif
  50062                 break;
  50063 
  50064         case bcmPortClassFieldLookup:
  50065 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50066             if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) ||
  50067                 SOC_IS_TRIDENT3X(unit)) {
  50068                 rv = _bcm_esw_port_tab_get(unit, port, VFP_PORT_GROUP_IDf,
  50069                                            &port_class_id);
  50070                 *pclass_id = (uint32) port_class_id;
  50071             }
  50072 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  50073             break;
  50074         case bcmPortClassVlanTranslateIngress:
  50075 #if defined(BCM_TRIDENT2_SUPPORT)
  50076             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) {
  50077                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  50078                                                    PORT_GROUPf, pclass_id);
  50079             }
  50080 #endif /* BCM_TRIDENT2_SUPPORT */
  50081             break;
  50082         case bcmPortClassFieldIngress:
  50083 #if defined(BCM_TRX_SUPPORT)
  50084             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) {
  50085 #if defined(BCM_KATANA2_SUPPORT)
  50086                 if (SOC_IS_KATANA2(unit)) {
  50087                     rv = _bcm_kt2_source_trunk_map_get(unit, port_out,
  50088                                                    CLASS_IDf, pclass_id);
  50089                 } else
  50090 #endif
  50091                 {
  50092                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  50093                                                    CLASS_IDf, pclass_id);
  50094                 }
  50095             }
  50096 #endif /* BCM_TRX_SUPPORT */
  50097             break;
  50098         case bcmPortClassFieldEgress:
  50099 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50100             if (soc_reg_field_valid(unit, EGR_PORT_64r, EGR_PORT_GROUP_IDf)) {
  50101                 rv = READ_EGR_PORT_64r(unit, port_out, &reg_val64);
  50102                 if (BCM_SUCCESS(rv)) {
  50103                     *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r,
  50104                                                    reg_val64, EGR_PORT_GROUP_IDf);
  50105                 }
  50106             } else if (soc_reg_field_valid(unit, EGR_PORTr, EGR_PORT_GROUP_IDf)) {
  50107                 rv = READ_EGR_PORTr(unit, port_out, &reg_val);
  50108                 if (BCM_SUCCESS(rv)) {
  50109                     *pclass_id = soc_reg_field_get(unit, EGR_PORTr,
  50110                                                    reg_val, EGR_PORT_GROUP_IDf);
  50111                 }
  50112             }
  50113 #ifdef BCM_TRIDENT_SUPPORT
  50114             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) ||
  50115                      SOC_IS_TRIDENT3X(unit)) {
  50116                 rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_PORT_GROUP_IDf,
  50117                                                (int *)pclass_id);
  50118 
  50119             }
  50120 #endif /* BCM_TRIDENT_SUPPORT */
  50121 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  50122             break;
  50123         case bcmPortClassVlanTranslateEgress:
  50124 #if defined(BCM_TRX_SUPPORT)
  50125             if (soc_reg_field_valid(unit, EGR_PORT_64r, VT_PORT_GROUP_IDf)) {
  50126                 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) {
  50127                     rv = READ_EGR_PORT_64r(unit, port_out, &reg_val64);
  50128                     if (BCM_SUCCESS(rv)) {
  50129                         *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r,
  50130                                                        reg_val64, VT_PORT_GROUP_IDf);
  50131                     }
  50132                 }
  50133             } else if (soc_reg_field_valid(unit, EGR_PORTr, VT_PORT_GROUP_IDf)) {
  50134                     rv = READ_EGR_PORTr(unit, port_out, &reg_val);
  50135                     if (BCM_SUCCESS(rv)) {
  50136                         *pclass_id = soc_reg_field_get(unit, EGR_PORTr,
  50137                                                        reg_val, VT_PORT_GROUP_IDf);
  50138                     }
  50139             }
  50140 #ifdef BCM_TRIDENT_SUPPORT
  50141             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) ||
  50142                      SOC_IS_TRIDENT3X(unit)) {
  50143                 rv = _bcm_esw_egr_port_tab_get(unit, port, VT_PORT_GROUP_IDf,
  50144                                                (int *)pclass_id);
  50145             }
  50146 #endif /* BCM_TRIDENT_SUPPORT */
  50147 #endif /* BCM_TRX_SUPPORT */
  50148             break;
  50149 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50150          case bcmPortClassEgress:
  50151             if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) ||
  50152                 SOC_IS_TRIDENT3X(unit)) {
  50153                 rv = _bcm_esw_egr_port_tab_get(unit, port, CLASS_IDf,
  50154                                                (int *)pclass_id);
  50155             }
  50156             break;
  50157 #endif
  50158 #if defined(BCM_TOMAHAWK_SUPPORT)
  50159          case bcmPortClassFieldIngressDevicePort:
  50160             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  50161                 return BCM_E_UNAVAIL;
  50162             }
  50163             rv = _bcm_esw_port_tab_get(unit, port, PORT_IPBM_INDEXf,
  50164                                        &port_class_id);
  50165             if (BCM_SUCCESS(rv)) {
  50166                 *pclass_id = (uint32) port_class_id;
  50167             }
  50168             break;
  50169 #endif /* BCM_TOMAHAWK_SUPPORT */
  50170 
  50171         default:
  50172             rv = BCM_E_PARAM;
  50173         }
  50174     }
  50175 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  50176 
  50177     return rv;
  50178 }
  50179 
  50180 
  50181 /*
  50182  * Function    : _bcm_esw_port_config_set
  50183  * Description : Internal function to set port configuration.
  50184  * Parameters  : (IN)unit  - BCM device number.
  50185  *               (IN)port  - Port number (see Notes for valid port formats).
  50186  *               (IN)type  - Port property.
  50187  *               (IN)value - New property value.
  50188  * Returns     : BCM_E_XXX
  50189  * Notes:
  50190  *      Current valid port types are:
  50191  *          GPORT PROXY
  50192  *          GPORT SUBPORT
  50193  *          GPORT (various types) that resolves to local physical port
  50194  *          BCM port (non-gport), local physical port
  50195  */
  50196 int
  50197 _bcm_esw_port_config_set(int unit, bcm_port_t port,
  50198                          _bcm_port_config_t type, int value)
  50199 {
  50200     int rv = BCM_E_UNAVAIL;    /* Operation return status. */
  50201 
  50202 #ifdef BCM_HGPROXY_COE_SUPPORT
  50203     if (BCM_GPORT_IS_SET(port) &&
  50204         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  50205         (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  50206         soc_feature(unit, soc_feature_channelized_switching))) {
  50207         /* Don't resolve port */
  50208     } else
  50209 #endif
  50210     if (BCM_GPORT_IS_PROXY(port)) {
  50211         /* Don't resolve port */
  50212     } else {
  50213         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  50214     }
  50215 
  50216 
  50217     PORT_LOCK(unit);
  50218 
  50219     switch (type) {
  50220     case _bcmPortL3UrpfMode:
  50221 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50222         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50223                                    URPF_MODEf, value);
  50224 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50225         break;
  50226     case _bcmPortL3UrpfDefaultRoute:
  50227 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50228         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50229                                    URPF_DEFAULTROUTECHECKf,
  50230                                    (value) ? 0 : 1);
  50231 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50232         break;
  50233     case _bcmPortVlanTranslate:
  50234         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50235                                    VT_ENABLEf, value);
  50236 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  50237     defined(BCM_KATANA2_SUPPORT)
  50238         if ((SOC_IS_TRIUMPH3(unit) ||
  50239              SOC_IS_TD2_TT2(unit) ||
  50240              SOC_IS_KATANA2(unit)) && (rv == SOC_E_NONE)) {
  50241             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50242                                        VT_PORT_TYPE_SELECTf, value);
  50243             if (rv == SOC_E_NONE) {
  50244                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50245                                            VT_PORT_TYPE_SELECT_2f, value);
  50246             }
  50247         } else
  50248 #endif
  50249         {
  50250 #if defined(BCM_TRX_SUPPORT)
  50251         if (SOC_IS_TRX(unit) && (rv == SOC_E_NONE)) {
  50252             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50253                                        VT_KEY_TYPE_USE_GLPf, value);
  50254             if (rv == SOC_E_NONE) {
  50255                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50256                                            VT_KEY_TYPE_2_USE_GLPf, value);
  50257             }
  50258         }
  50259 #endif
  50260         }
  50261         break;
  50262     case _bcmPortVlanPrecedence:
  50263         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50264                                    VLAN_PRECEDENCEf, value);
  50265         break;
  50266     case _bcmPortVTMissDrop:
  50267         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50268                                    VT_MISS_DROPf, value);
  50269         break;
  50270     case _bcmPortLookupMACEnable:
  50271         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50272                                    MAC_BASED_VID_ENABLEf, value);
  50273         break;
  50274     case _bcmPortLookupIPEnable:
  50275         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50276                                    SUBNET_BASED_VID_ENABLEf,
  50277                                    value);
  50278         break;
  50279     case _bcmPortUseInnerPri:
  50280 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50281     defined(BCM_TRX_SUPPORT)
  50282         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50283                                    USE_INNER_PRIf, value);
  50284 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50285         break;
  50286     case _bcmPortUseOuterPri:
  50287 #if defined(BCM_TRX_SUPPORT)
  50288         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50289                                    TRUST_OUTER_DOT1Pf, value);
  50290 #endif /* BCM_TRX_SUPPORT */
  50291         break;
  50292     case _bcmPortVerifyOuterTpid:
  50293 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50294     defined(BCM_TRX_SUPPORT)
  50295         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50296                                    OUTER_TPID_VERIFYf, value);
  50297 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50298         break;
  50299     case _bcmPortVTKeyTypeFirst:
  50300 #if defined(BCM_TRX_SUPPORT)
  50301         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50302                                    VT_KEY_TYPEf, value);
  50303 #endif /* BCM_TRX_SUPPORT */
  50304         break;
  50305     case _bcmPortVTKeyPortFirst:
  50306 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  50307     defined(BCM_KATANA2_SUPPORT)
  50308        if (SOC_IS_TRIUMPH3(unit) ||
  50309            SOC_IS_TD2_TT2(unit) ||
  50310            SOC_IS_KATANA2(unit)) {
  50311             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50312                                        VT_PORT_TYPE_SELECTf, value);
  50313         } else
  50314 #endif
  50315         {
  50316 #if defined(BCM_TRX_SUPPORT)
  50317         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50318                                    VT_KEY_TYPE_USE_GLPf, value);
  50319 #endif /* BCM_TRX_SUPPORT */
  50320         }
  50321         break;
  50322     case _bcmPortVTKeyTypeSecond:
  50323 #if defined(BCM_TRX_SUPPORT)
  50324         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50325                                    VT_KEY_TYPE_2f, value);
  50326 #endif /* BCM_TRX_SUPPORT */
  50327         break;
  50328     case _bcmPortVTKeyPortSecond:
  50329 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  50330     defined(BCM_KATANA2_SUPPORT)
  50331         if (SOC_IS_TRIUMPH3(unit) ||
  50332             SOC_IS_TD2_TT2(unit) ||
  50333             SOC_IS_KATANA2(unit)) {
  50334             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50335                                    VT_PORT_TYPE_SELECT_2f, value);
  50336         } else
  50337 #endif
  50338         {
  50339 #if defined(BCM_TRX_SUPPORT)
  50340         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50341                                    VT_KEY_TYPE_2_USE_GLPf, value);
  50342 #endif /* BCM_TRX_SUPPORT */
  50343         }
  50344         break;
  50345     case _bcmPortIpmcV4Enable:
  50346         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50347                                    V4IPMC_ENABLEf, value);
  50348         break;
  50349     case _bcmPortIpmcV6Enable:
  50350         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50351                                    V6IPMC_ENABLEf, value);
  50352         break;
  50353     case _bcmPortIpmcVlanKey:
  50354         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50355                                    IPMC_DO_VLANf, value);
  50356         break;
  50357     case _bcmPortCfiAsCng:
  50358         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50359                                    CFI_AS_CNGf, value);
  50360         break;
  50361     case _bcmPortNni:
  50362         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50363                                    NNI_PORTf, value);
  50364         break;
  50365     case _bcmPortHigigTrunkId:
  50366 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50367         if (value < 0) {
  50368             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50369                                        HIGIG_TRUNKf, 0);
  50370             if (BCM_SUCCESS(rv)) {
  50371                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50372                                            HIGIG_TRUNK_IDf, 0);
  50373             }
  50374         } else {
  50375             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50376                                        HIGIG_TRUNK_IDf, value);
  50377             if (BCM_SUCCESS(rv)) {
  50378                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50379                                            HIGIG_TRUNKf, 1);
  50380             }
  50381         }
  50382 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  50383         break;
  50384     case _bcmPortModuleLoopback:
  50385         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50386                                    ALLOW_SRC_MODf, value);
  50387         break;
  50388     case _bcmPortOuterTpidEnables:
  50389 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50390     defined(BCM_TRX_SUPPORT)
  50391         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  50392                                 OUTER_TPID_ENABLEf)) {
  50393 #ifdef BCM_TRX_SUPPORT
  50394             rv = _bcm_trx_source_trunk_map_set(unit, port, OUTER_TPID_ENABLEf,
  50395                                                (uint32)value);
  50396 #endif
  50397         } else {
  50398             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50399                                        OUTER_TPID_ENABLEf, value);
  50400         }
  50401 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50402         break;
  50403 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  50404     defined(BCM_GREYHOUND2_SUPPORT)
  50405     case _bcmPortSvcMeterIndex:
  50406         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||    \
  50407             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  50408             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50409                                    SVC_METER_INDEXf, value);
  50410         }
  50411         break;
  50412     case _bcmPortSvcMeterOffsetMode:
  50413         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||    \
  50414             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  50415             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50416                                    SVC_METER_OFFSET_MODEf, value);
  50417         }
  50418         break;
  50419 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  50420           BCM_GREYHOUND2_SUPPORT */
  50421 #if defined(BCM_KATANA2_SUPPORT)
  50422     case _bcmPortOamUseXlatedInnerVlan:
  50423         if (SOC_IS_KATANA2(unit)) {
  50424             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  50425                                    OAM_CVLAN_MEP_AFTER_VXLTf, value);
  50426             rv = _bcm_esw_egr_port_tab_set(unit, port,
  50427                                    OAM_CVLAN_MEP_AFTER_VXLTf, value);
  50428         }
  50429         break;
  50430 #endif /* BCM_KATANA2_SUPPORT */
  50431     default:
  50432         rv = BCM_E_INTERNAL;
  50433     }
  50434 
  50435     PORT_UNLOCK(unit);
  50436     return (rv);
  50437 }
  50438 
  50439 /*
  50440  * Function    : _bcm_esw_port_config_get
  50441  * Description : Internal function to get port configuration.
  50442  * Parameters  : (IN)unit  - BCM device number.
  50443  *               (IN)port  - Port number.
  50444  *               (IN)type  - Port property.
  50445  *               (OUT)value -Port property value.
  50446  * Returns     : BCM_E_XXX
  50447  * Notes:
  50448  *      Current valid port types are:
  50449  *          GPORT PROXY
  50450  *          GPORT SUBPORT
  50451  *          GPORT (various types) that resolves to local physical port
  50452  *          BCM port (non-gport), local physical port
  50453  */
  50454 int
  50455 _bcm_esw_port_config_get(int unit, bcm_port_t port,
  50456                      _bcm_port_config_t type, int *value)
  50457 {
  50458     int rv = BCM_E_UNAVAIL;    /* Operation return status. */
  50459 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50460     int tmp_value; /* Temporary value.     */
  50461 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50462 
  50463 #ifdef BCM_HGPROXY_COE_SUPPORT
  50464     if (BCM_GPORT_IS_SET(port) &&
  50465         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  50466         (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  50467         soc_feature(unit, soc_feature_channelized_switching))) {
  50468         /* Don't resolve port */
  50469     } else
  50470 #endif
  50471     if (BCM_GPORT_IS_PROXY(port)) {
  50472         /* Don't resolve port */
  50473     } else {
  50474         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  50475     }
  50476 
  50477     PORT_LOCK(unit);
  50478 
  50479     switch (type) {
  50480     case _bcmPortL3UrpfMode:
  50481 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50482         rv = _bcm_esw_port_tab_get(unit, port, URPF_MODEf, value);
  50483 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50484         break;
  50485     case _bcmPortL3UrpfDefaultRoute:
  50486 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50487         rv = _bcm_esw_port_tab_get(unit, port, URPF_DEFAULTROUTECHECKf,
  50488                                    &tmp_value);
  50489         *value = (tmp_value) ? FALSE : TRUE;
  50490 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50491         break;
  50492     case _bcmPortVlanTranslate:
  50493         rv = _bcm_esw_port_tab_get(unit, port, VT_ENABLEf, value);
  50494         break;
  50495     case _bcmPortVlanPrecedence:
  50496         rv = _bcm_esw_port_tab_get(unit, port, VLAN_PRECEDENCEf, value);
  50497         break;
  50498     case _bcmPortVTMissDrop:
  50499         rv = _bcm_esw_port_tab_get(unit, port, VT_MISS_DROPf, value);
  50500         break;
  50501     case _bcmPortLookupMACEnable:
  50502         rv = _bcm_esw_port_tab_get(unit, port, MAC_BASED_VID_ENABLEf, value);
  50503         break;
  50504     case _bcmPortLookupIPEnable:
  50505         rv = _bcm_esw_port_tab_get(unit, port, SUBNET_BASED_VID_ENABLEf,
  50506                                    value);
  50507         break;
  50508     case _bcmPortUseInnerPri:
  50509 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50510     defined(BCM_TRX_SUPPORT)
  50511         rv = _bcm_esw_port_tab_get(unit, port, USE_INNER_PRIf, value);
  50512 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50513         break;
  50514     case _bcmPortUseOuterPri:
  50515 #if defined(BCM_TRX_SUPPORT)
  50516         rv = _bcm_esw_port_tab_get(unit, port, TRUST_OUTER_DOT1Pf, value);
  50517 #endif /* BCM_TRX_SUPPORT */
  50518         break;
  50519     case _bcmPortVerifyOuterTpid:
  50520 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50521     defined(BCM_TRX_SUPPORT)
  50522         rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_VERIFYf, value);
  50523 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50524         break;
  50525     case _bcmPortVTKeyTypeFirst:
  50526 #if defined(BCM_TRX_SUPPORT)
  50527         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPEf, value);
  50528 #endif /* BCM_TRX_SUPPORT */
  50529         break;
  50530     case _bcmPortVTKeyPortFirst:
  50531 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  50532     defined(BCM_KATANA2_SUPPORT)
  50533        if (SOC_IS_TRIUMPH3(unit) ||
  50534            SOC_IS_TD2_TT2(unit) ||
  50535            SOC_IS_KATANA2(unit)) {
  50536             rv = _bcm_esw_port_tab_get(unit, port,
  50537                                        VT_PORT_TYPE_SELECTf, value);
  50538         } else
  50539 #endif
  50540         {
  50541 #if defined(BCM_TRX_SUPPORT)
  50542         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_USE_GLPf, value);
  50543 #endif /* BCM_TRX_SUPPORT */
  50544         }
  50545         break;
  50546     case _bcmPortVTKeyTypeSecond:
  50547 #if defined(BCM_TRX_SUPPORT)
  50548         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2f, value);
  50549 #endif /* BCM_TRX_SUPPORT */
  50550         break;
  50551     case _bcmPortVTKeyPortSecond:
  50552 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  50553     defined(BCM_KATANA2_SUPPORT)
  50554         if (SOC_IS_TRIUMPH3(unit) ||
  50555             SOC_IS_TD2_TT2(unit) ||
  50556             SOC_IS_KATANA2(unit)) {
  50557             rv = _bcm_esw_port_tab_get(unit, port,
  50558                          VT_PORT_TYPE_SELECT_2f, value);
  50559         } else
  50560 #endif
  50561         {
  50562 #if defined(BCM_TRX_SUPPORT)
  50563         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2_USE_GLPf, value);
  50564 #endif /* BCM_TRX_SUPPORT */
  50565         }
  50566         break;
  50567     case _bcmPortIpmcV4Enable:
  50568         rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value);
  50569         break;
  50570     case _bcmPortIpmcV6Enable:
  50571         rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value);
  50572         break;
  50573     case _bcmPortIpmcVlanKey:
  50574         rv = _bcm_esw_port_tab_get(unit, port, IPMC_DO_VLANf, value);
  50575         break;
  50576     case _bcmPortCfiAsCng:
  50577         rv = _bcm_esw_port_tab_get(unit, port, CFI_AS_CNGf, value);
  50578         break;
  50579     case _bcmPortNni:
  50580         rv = _bcm_esw_port_tab_get(unit, port, NNI_PORTf, value);
  50581         break;
  50582     case _bcmPortHigigTrunkId:
  50583 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  50584         rv = _bcm_esw_port_tab_get(unit, port, HIGIG_TRUNKf, value);
  50585         if (BCM_SUCCESS(rv)) {
  50586             if (*value == 0) {
  50587                 *value = -1;
  50588             } else {
  50589                 rv = _bcm_esw_port_tab_get(unit, port,
  50590                                            HIGIG_TRUNK_IDf, value);
  50591             }
  50592         }
  50593 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  50594         break;
  50595     case _bcmPortModuleLoopback:
  50596         rv = _bcm_esw_port_tab_get(unit, port, ALLOW_SRC_MODf, value);
  50597         break;
  50598     case _bcmPortOuterTpidEnables:
  50599 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  50600     defined(BCM_TRX_SUPPORT)
  50601         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  50602                                 OUTER_TPID_ENABLEf)) {
  50603 #ifdef BCM_TRX_SUPPORT
  50604             rv = _bcm_trx_source_trunk_map_get(unit, port, OUTER_TPID_ENABLEf,
  50605                                                (uint32 *)value);
  50606 #endif
  50607         } else {
  50608             rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, value);
  50609         }
  50610 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  50611         break;
  50612 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  50613     defined(BCM_GREYHOUND2_SUPPORT)
  50614     case _bcmPortSvcMeterIndex:
  50615         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)       \
  50616             || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  50617             rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_INDEXf, value);
  50618         }
  50619         break;
  50620     case _bcmPortSvcMeterOffsetMode:
  50621         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)       \
  50622             || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  50623             rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_OFFSET_MODEf, value);
  50624         }
  50625         break;
  50626 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  50627           BCM_GREYHOUND2_SUPPORT */
  50628 #if defined(BCM_KATANA2_SUPPORT)
  50629     case _bcmPortOamUseXlatedInnerVlan:
  50630         if (SOC_IS_KATANA2(unit)) {
  50631             rv = _bcm_esw_port_tab_get(unit, port, OAM_CVLAN_MEP_AFTER_VXLTf,
  50632                                        value);
  50633         }
  50634         break;
  50635 #endif /* BCM_KATANA2_SUPPORT */
  50636     default:
  50637         rv = BCM_E_INTERNAL;
  50638     }
  50639     PORT_UNLOCK(unit);
  50640     return (rv);
  50641 }
  50642 
  50643 /*
  50644  * Function:
  50645  *     bcm_port_force_vlan_set
  50646  * Description:
  50647  *     To set the force vlan attribute of a port
  50648  * Parameters:
  50649  *     unit        device number
  50650  *     port        port number
  50651  *     vlan        vlan identifier
  50652  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
  50653  *     pkt_prio    egress packet priority (-1, 0..7)
  50654  *                 any negative priority value disable the priority
  50655  *                 override if the egress packet is tagged
  50656  *     flags       bit fields
  50657  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
  50658  *                                              port
  50659  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
  50660  *                                             vlan is enabled on this port
  50661  *
  50662  * Return:
  50663  *     BCM_E_NONE
  50664  *     BCM_E_UNIT
  50665  *     BCM_E_PORT
  50666  *     BCM_E_PARAM
  50667  *     BCM_E_UNAVAIL
  50668  *     BCM_E_XXX
  50669  */
  50670 int
  50671 bcm_esw_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan,
  50672                             int pkt_prio, uint32 flags)
  50673 {
  50674     int rv = BCM_E_UNAVAIL;
  50675 
  50676     /* Make sure port module is initialized. */
  50677     PORT_INIT(unit);
  50678 
  50679 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  50680     if (BCM_GPORT_IS_VLAN_PORT(port) ||
  50681         BCM_GPORT_IS_NIV_PORT(port) ||
  50682         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  50683         return bcm_td_vp_force_vlan_set(unit, port, vlan, flags);
  50684     }
  50685 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  50686 
  50687     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  50688 #if defined(BCM_TRX_SUPPORT)
  50689     if ((!soc_feature(unit, soc_feature_egr_pvlan_eport_control_is_mem) &&
  50690          SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) ||
  50691         (soc_feature(unit, soc_feature_egr_pvlan_eport_control_is_mem) &&
  50692          SOC_MEM_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLm, PVLAN_UNTAGf))) {
  50693         rv = _bcm_trx_port_force_vlan_set(unit, port, vlan, pkt_prio, flags);
  50694     }
  50695 
  50696 #endif /* defined(BCM_TRX_SUPPORT) */
  50697 
  50698     return rv;
  50699 }
  50700 
  50701 /*
  50702  * Function:
  50703  *     bcm_port_force_vlan_get
  50704  * Description:
  50705  *     To get the force vlan attribute of a port
  50706  * Parameters:
  50707  *     unit        device number
  50708  N_UNTAGf*     port        port number
  50709  *     vlan        pointer to vlan identifier
  50710  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
  50711  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
  50712  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
  50713  *     pkt_prio    egress packet priority (-1, 0 - 7)
  50714  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
  50715  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
  50716  *     flags       bit fields
  50717  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
  50718  *                                              port
  50719  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
  50720  *                                             vlan is enabled on this port
  50721  *
  50722  * Return:
  50723  *     BCM_E_XXX
  50724  */
  50725 int
  50726 bcm_esw_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan,
  50727                             int *pkt_prio, uint32 *flags)
  50728 {
  50729     int rv = BCM_E_UNAVAIL;
  50730 
  50731     /* Make sure port module is initialized. */
  50732     PORT_INIT(unit);
  50733 
  50734 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  50735     if (BCM_GPORT_IS_VLAN_PORT(port) ||
  50736         BCM_GPORT_IS_NIV_PORT(port) ||
  50737         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  50738         return bcm_td_vp_force_vlan_get(unit, port, vlan, flags);
  50739     }
  50740 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  50741 
  50742     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  50743 
  50744 #if defined(BCM_TRX_SUPPORT)
  50745     if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) {
  50746         rv = _bcm_trx_port_force_vlan_get(unit, port, vlan, pkt_prio, flags);
  50747     }
  50748 #endif /* defined(BCM_TRX_SUPPORT) */
  50749 
  50750     return rv;
  50751 }
  50752 
  50753 /*
  50754  * Function:
  50755  *     bcm_port_phy_control_set
  50756  * Description:
  50757  *     Set PHY specific properties
  50758  * Parameters:
  50759  *     unit        device number
  50760  *     port        port number
  50761  *     type        configuration type
  50762  *     value       new value for the configuration
  50763  * Return:
  50764  *     BCM_E_XXX
  50765  */
  50766 int
  50767 bcm_esw_port_phy_control_set(int unit, bcm_port_t port,
  50768                              bcm_port_phy_control_t type, uint32 value)
  50769 {
  50770     int rv;
  50771     bcm_port_t local_port = 0;
  50772     int phy_lane = -1;
  50773     int phyn = 0, sys_side = 0;
  50774 
  50775     /* Make sure port module is initialized. */
  50776     PORT_INIT(unit);
  50777 
  50778     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  50779         BCM_IF_ERROR_RETURN
  50780             (bcmi_esw_portctrl_phy_control_set(unit, port, type, value));
  50781 #ifdef BCM_TOMAHAWK_SUPPORT
  50782         /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */
  50783         if (SOC_IS_TOMAHAWKX(unit)) {
  50784             if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91)
  50785                 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) {
  50786                 bcm_port_info_t port_info;
  50787 
  50788                 bcm_port_info_t_init(&port_info);
  50789                 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info));
  50790 
  50791                 if ((port_info.speed == 25000) || (port_info.speed == 27000) ||
  50792                         (port_info.speed == 50000) || (port_info.speed == 53000) ||
  50793                         (port_info.speed == 100000) || (port_info.speed == 106000)){
  50794                     int mode;
  50795 
  50796                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode));
  50797                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode));
  50798                 }
  50799             }
  50800         }
  50801 #endif
  50802         return BCM_E_NONE;
  50803     }
  50804 
  50805     if(BCM_PHY_GPORT_IS_PHYN(port)) {
  50806         local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  50807         phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  50808         phy_lane = -1;
  50809     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  50810         local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  50811         phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  50812         phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  50813     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  50814         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  50815         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  50816         sys_side = TRUE;
  50817         phy_lane = -1;
  50818     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  50819         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  50820         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  50821         phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  50822         sys_side = TRUE;
  50823     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  50824         local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  50825         phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  50826     } else {
  50827         BCM_IF_ERROR_RETURN
  50828             (_bcm_esw_port_gport_validate(unit, port, &local_port));
  50829 
  50830         PORT_LOCK(unit);
  50831         rv = soc_phyctrl_control_set(unit, local_port, (soc_phy_control_t) type, value);
  50832         if (BCM_SUCCESS(rv)) {
  50833             PORT_INFO_RX_LOS_SET(unit, local_port, type, value);
  50834         }
  50835         PORT_UNLOCK(unit);
  50836 
  50837 #ifdef BCM_TOMAHAWK_SUPPORT
  50838         /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */
  50839         if (SOC_IS_TOMAHAWKX(unit)) {
  50840             if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91)
  50841                 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) {
  50842                 bcm_port_info_t port_info;
  50843 
  50844                 bcm_port_info_t_init(&port_info);
  50845                 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info));
  50846 
  50847                 if ((port_info.speed == 25000) || (port_info.speed == 27000) ||
  50848                         (port_info.speed == 50000) || (port_info.speed == 53000) ||
  50849                         (port_info.speed == 100000) || (port_info.speed == 106000)){
  50850                     int mode;
  50851 
  50852                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode));
  50853                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode));
  50854                 }
  50855             }
  50856         }
  50857 #endif
  50858         return rv;
  50859     }
  50860 
  50861     if (!SOC_PORT_VALID(unit, local_port)) {
  50862         return BCM_E_PORT;
  50863     }
  50864 
  50865     PORT_LOCK(unit);
  50866     rv = soc_phyctrl_redirect_control_set(unit, local_port, phyn, phy_lane,
  50867                                           sys_side, (soc_phy_control_t) type, value);
  50868     if (BCM_SUCCESS(rv)) {
  50869         PORT_INFO_RX_LOS_SET(unit, local_port, type, value);
  50870     }
  50871     PORT_UNLOCK(unit);
  50872 
  50873     return rv;
  50874 }
  50875 
  50876 /*
  50877  * Function:
  50878  *     bcm_esw_port_phy_control_get
  50879  * Description:
  50880  *     Set PHY specific properties
  50881  * Parameters:
  50882  *     unit        device number
  50883  *     port        port number
  50884  *     type        configuration type
  50885  *     value       value for the configuration
  50886  * Return:
  50887  *     BCM_E_XXX
  50888  */
  50889 int
  50890 bcm_esw_port_phy_control_get(int unit, bcm_port_t port,
  50891                              bcm_port_phy_control_t type, uint32 *value)
  50892 {
  50893     int rv;
  50894     bcm_port_t local_port;
  50895     int phy_lane = -1;
  50896     int phyn = 0, sys_side = 0;
  50897 
  50898     if (NULL == value) {
  50899         return BCM_E_PARAM;
  50900     }
  50901 
  50902     /* Make sure port module is initialized. */
  50903     PORT_INIT(unit);
  50904 
  50905     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  50906         return bcmi_esw_portctrl_phy_control_get(unit, port, type, value);
  50907     }
  50908 
  50909     if(BCM_PHY_GPORT_IS_PHYN(port)) {
  50910         local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  50911         phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  50912         phy_lane = -1;
  50913     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  50914         local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  50915         phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  50916         phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  50917     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  50918         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  50919         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  50920         sys_side = TRUE;
  50921         phy_lane = -1;
  50922     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  50923         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  50924         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  50925         phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  50926         sys_side = TRUE;
  50927     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  50928         local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  50929         phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  50930     } else {
  50931         BCM_IF_ERROR_RETURN
  50932             (_bcm_esw_port_gport_validate(unit, port, &port));
  50933 
  50934         PORT_LOCK(unit);
  50935         rv = soc_phyctrl_control_get(unit, port, (soc_phy_control_t) type, value);
  50936         PORT_UNLOCK(unit);
  50937         return rv;
  50938     }
  50939 
  50940     if (!SOC_PORT_VALID(unit, local_port)) {
  50941         return BCM_E_PORT;
  50942     }
  50943 
  50944     PORT_LOCK(unit);
  50945     rv = soc_phyctrl_redirect_control_get(unit, local_port, phyn, phy_lane,
  50946                                           sys_side, (soc_phy_control_t) type, value);
  50947     PORT_UNLOCK(unit);
  50948 
  50949     return rv;
  50950 }
  50951 
  50952 /*
  50953  * Function:
  50954  *      bcm_esw_port_phy_firmware_set
  50955  * Purpose:
  50956  *      Write the firmware to the PHY device's non-volatile storage.
  50957  * Parameters:
  50958  *      unit - (IN) Unit number.
  50959  *      port - (IN) Port number
  50960  *      flags - (IN) PHY spcific flags, such as BCM_PORT_PHY_INTERNAL
  50961  *      offset - (IN) Offset to the firmware data array
  50962  *      array - (IN)  The firmware data array
  50963  *      length - (IN) The length of the firmware data array
  50964  * Returns:
  50965  *      BCM_E_XXX
  50966  * Notes:
  50967  */
  50968 int
  50969 bcm_esw_port_phy_firmware_set(int unit, bcm_port_t port, uint32 flags,
  50970                               int offset, uint8 *array, int length)
  50971 {
  50972     int rv;
  50973 
  50974     /* Make sure port module is initialized. */
  50975     PORT_INIT(unit);
  50976 
  50977     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  50978 
  50979     PORT_LOCK(unit);
  50980     rv = soc_phyctrl_firmware_set(unit, port, flags,offset,array,length);
  50981     PORT_UNLOCK(unit);
  50982 
  50983     return rv;
  50984 }
  50985 
  50986 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50987 /*
  50988  * Function    : _bcm_esw_port_subport_index_get
  50989  * Description : Get the subport index for the specified mod port.
  50990  *
  50991  * Parameters  : (IN)  unit             - BCM device number
  50992  *               (IN) modport        - GPORT ID
  50993  *               (OUT)  subport_index - subport index
  50994  * Returns     : BCM_E_XXX
  50995  */
  50996 int
  50997 _bcm_esw_port_subport_index_get(int unit, bcm_gport_t modport,
  50998                                 int *subport_index)
  50999 {
  51000     int id_out = 0;
  51001     bcm_module_t mod_out = 0;
  51002     bcm_port_t port_out = 0;
  51003     bcm_trunk_t tgid_out = 0;
  51004     int base_index = 0;
  51005     int result = FALSE;
  51006     modid_base_ptr_entry_t modid_base_entry;
  51007     soc_info_t *si = &SOC_INFO(unit);
  51008     int i = 0, valid = 0, modid = 0;
  51009 
  51010     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, modport,
  51011                             &mod_out, &port_out, &tgid_out, &id_out));
  51012     if ((-1 != tgid_out) || (-1 != id_out)) {
  51013         return BCM_E_PARAM;
  51014     }
  51015 
  51016     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51017         for (i = 0; i < si->num_modules; i++) {
  51018             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i]
  51019                 == mod_out) {
  51020                 BCM_IF_ERROR_RETURN(
  51021                     _bcm_esw_stk_get_mod_config_by_type(unit,
  51022                     BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  51023                     &base_index));
  51024                 if ((valid == 1) && (modid == mod_out)) {
  51025                     if (port_out >
  51026                         src_modid_base_index_bk[unit]->num_ports[modid]) {
  51027                         return BCM_E_PARAM;
  51028                     }
  51029                     *subport_index = base_index + port_out;
  51030                     return BCM_E_NONE;
  51031                 }
  51032             }
  51033         }
  51034     }
  51035 
  51036     /* Check modport in one of additional module */
  51037     BCM_IF_ERROR_RETURN (
  51038         _bcm_esw_my_modid_additional_check(unit, mod_out, &result));
  51039     if(result == FALSE) {
  51040         return BCM_E_PORT;
  51041     }
  51042     MODULE_ID_LOWER_6_BITS(mod_out); /* lower 6 bit */
  51043     SOC_IF_ERROR_RETURN(
  51044         READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_out,
  51045         &modid_base_entry));
  51046     base_index = soc_MODID_BASE_PTRm_field32_get(
  51047                     unit, &modid_base_entry, MODID_BASEf);
  51048     *subport_index = base_index; /* the index is indicated by module base ptr */
  51049 
  51050     return BCM_E_NONE;
  51051 }
  51052 
  51053 /*
  51054  * Function    : _bcm_esw_modport_local_get
  51055  * Description : Get the physical port for the specified mod port.
  51056  *
  51057  * Parameters  : (IN)     unit                 - BCM device number
  51058  *                     (IN)     modport          - Gport number
  51059  *                     (OUT)  local_port        - port number
  51060  *
  51061  * Returns     : BCM_E_XXX
  51062  */
  51063 int _bcm_esw_modport_local_get(int unit, bcm_gport_t modport, bcm_port_t *local_port)
  51064 {
  51065     int subport_index = 0;
  51066     modport_map_subport_entry_t modport_map_subport_entry;
  51067 
  51068     /* Make sure port module is initialized. */
  51069     PORT_INIT(unit);
  51070 
  51071     /* Parameter check */
  51072     if (!BCM_GPORT_IS_MODPORT(modport)) {
  51073         return BCM_E_PARAM;
  51074     }
  51075 
  51076     if(local_port == NULL) {
  51077         return BCM_E_PARAM;
  51078     }
  51079 
  51080     SOC_IF_ERROR_RETURN(
  51081         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  51082 
  51083     SOC_IF_ERROR_RETURN(
  51084         READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  51085                                   &modport_map_subport_entry));
  51086     *local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(
  51087                      unit, &modport_map_subport_entry, DESTf);
  51088 
  51089     return BCM_E_NONE;
  51090 }
  51091 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  51092 
  51093 /*
  51094  * Function    : bcm_esw_port_local_get
  51095  * Description : Get the local port from the given GPORT ID.
  51096  *
  51097  * Parameters  : (IN)  unit         - BCM device number
  51098  *               (IN)  gport        - global port identifier
  51099  *               (OUT) local_port   - local port encoded in gport
  51100  * Returns     : BCM_E_XXX
  51101  */
  51102 int
  51103 bcm_esw_port_local_get(int unit, bcm_gport_t gport, bcm_port_t *local_port)
  51104 {
  51105     bcm_module_t my_mod, encap_mod;
  51106     bcm_port_t encap_port;
  51107     int num_modid, isLocal = 0;
  51108     soc_info_t *si = &SOC_INFO(unit);
  51109 
  51110 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  51111     int rv = BCM_E_NONE;
  51112 #endif
  51113 
  51114 #if defined(BCM_KATANA2_SUPPORT)
  51115     bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  51116     int         id = -1;
  51117     int         pp_port = 0;
  51118     int         min_pp_port = SOC_INFO(unit).pp_port_index_min;
  51119     int         max_pp_port = SOC_INFO(unit).pp_port_index_max;
  51120 #endif /* BCM_KATANA2_SUPPORT */
  51121 
  51122     /* Make sure port module is initialized. */
  51123     PORT_INIT(unit);
  51124 
  51125     BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_count(unit, &num_modid));
  51126     if ((!num_modid) && !BCM_GPORT_IS_DEVPORT(gport) ){
  51127         /* Only devport gport can be supported on device with no modid */
  51128         return BCM_E_UNAVAIL;
  51129     }
  51130 
  51131     if (BCM_GPORT_IS_LOCAL(gport)) {
  51132          *local_port = BCM_GPORT_LOCAL_GET(gport);
  51133     } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) {
  51134         *local_port = CMIC_PORT(unit);
  51135     } else if (BCM_GPORT_IS_DEVPORT(gport)) {
  51136         *local_port = BCM_GPORT_DEVPORT_PORT_GET(gport);
  51137         if (unit != BCM_GPORT_DEVPORT_DEVID_GET(gport)) {
  51138             return BCM_E_PORT;
  51139         }
  51140     } else if (BCM_GPORT_IS_MODPORT(gport) || BCM_GPORT_IS_PROXY(gport)) {
  51141         BCM_IF_ERROR_RETURN(
  51142             bcm_esw_stk_my_modid_get(unit, &my_mod));
  51143 
  51144         if (BCM_GPORT_IS_MODPORT(gport)) {
  51145             encap_mod = BCM_GPORT_MODPORT_MODID_GET(gport);
  51146             encap_port = BCM_GPORT_MODPORT_PORT_GET(gport);
  51147         } else {
  51148             encap_mod = BCM_GPORT_PROXY_MODID_GET(gport);
  51149             encap_port = BCM_GPORT_PROXY_PORT_GET(gport);
  51150         }
  51151 
  51152         if (encap_mod == my_mod){
  51153             *local_port = encap_port;
  51154         } else if ((num_modid > 1) &&
  51155                    !si->coe_stacking_mode) {
  51156             BCM_IF_ERROR_RETURN(
  51157                 _bcm_esw_modid_is_local(unit, encap_mod, &isLocal));
  51158             if (isLocal) {
  51159 #if defined(BCM_TOMAHAWK_SUPPORT)
  51160                 /* Call asymmetric dual modid unmapping function */
  51161                 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  51162                     BCM_IF_ERROR_RETURN (
  51163                         _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  51164                                 BCM_STK_MODMAP_SET, &encap_mod, &encap_port));
  51165                     *local_port = encap_port;
  51166                 } else
  51167 #endif /* BCM_TOMAHAWK_SUPPORT */
  51168                 {
  51169                     *local_port = encap_port +
  51170                         (encap_mod - my_mod) * (SOC_MODPORT_MAX(unit) + 1);
  51171                 }
  51172             } else {
  51173                 return BCM_E_PORT;
  51174             }
  51175         } else {
  51176 
  51177 #if defined(BCM_KATANA2_SUPPORT)
  51178             if (soc_feature(unit, soc_feature_linkphy_coe) ||
  51179                 soc_feature(unit, soc_feature_subtag_coe)) {
  51180                 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) {
  51181                     BCM_IF_ERROR_RETURN(
  51182                         _bcm_kt2_modport_to_pp_port_get(unit,
  51183                             encap_mod, encap_port, &pp_port));
  51184 #if defined BCM_METROLITE_SUPPORT
  51185                     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  51186                         if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  51187                             *local_port = pp_port;
  51188                             return BCM_E_NONE;
  51189                         }
  51190                     } else
  51191 #endif
  51192                     {
  51193                         if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) {
  51194                             *local_port = pp_port;
  51195                             return BCM_E_NONE;
  51196                         }
  51197                     }
  51198                 }
  51199             } else
  51200 #endif
  51201 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  51202             if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  51203                 soc_feature(unit, soc_feature_channelized_switching)) &&
  51204                 _bcm_xgs5_subport_coe_mod_port_local(unit, encap_mod, encap_port)) {
  51205                 BCM_IF_ERROR_RETURN(
  51206                 _bcmi_coe_subport_mod_port_physical_port_get(unit, encap_mod,
  51207                                                         encap_port, local_port));
  51208             }
  51209             /* Call modport to local function */
  51210             else if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51211                 BCM_IF_ERROR_RETURN (
  51212                     _bcm_esw_modport_local_get(unit, gport, &encap_port));
  51213                 *local_port = encap_port;
  51214             } else
  51215 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  51216             {
  51217                 return BCM_E_PORT;
  51218             }
  51219         }
  51220         if (soc_feature(unit, soc_feature_sysport_remap)) {
  51221             BCM_XLATE_SYSPORT_S2P(unit, local_port);
  51222         }
  51223         if (!SOC_PORT_VALID(unit, *local_port)) {
  51224             return BCM_E_PORT;
  51225         }
  51226     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
  51227 
  51228 #if defined(BCM_HGPROXY_COE_SUPPORT)
  51229         if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  51230             soc_feature(unit, soc_feature_channelized_switching)) &&
  51231             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
  51232             return _bcmi_coe_subport_physical_port_get(unit, gport, local_port);
  51233         } else
  51234 #endif /* BCM_HGPROXY_COE_SUPPORT */
  51235 #if defined(BCM_KATANA2_SUPPORT)
  51236         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) {
  51237             pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport);
  51238             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod));
  51239             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &encap_mod,
  51240                                     &encap_port, &trunk_id, &id));
  51241             if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) {
  51242 #if defined BCM_METROLITE_SUPPORT
  51243                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  51244                     if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  51245                         *local_port = pp_port;
  51246                         return BCM_E_NONE;
  51247                     }
  51248                 } else
  51249 #endif
  51250                 {
  51251                     if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) {
  51252                         *local_port = pp_port;
  51253                         return BCM_E_NONE;
  51254                     }
  51255                 }
  51256             }
  51257         }
  51258 #endif
  51259         return BCM_E_PORT;
  51260     } else if (BCM_GPORT_IS_VLAN_PORT(gport)) {
  51261         *local_port = BCM_GPORT_VLAN_PORT_ID_GET(gport);
  51262     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
  51263         *local_port = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
  51264     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
  51265         *local_port = BCM_GPORT_NIV_PORT_ID_GET(gport);
  51266     } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  51267         *local_port = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
  51268     } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
  51269         *local_port = BCM_GPORT_FLOW_PORT_ID_GET(gport);
  51270     } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
  51271         *local_port = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
  51272     } else if (BCM_GPORT_IS_MIM_PORT(gport)) {
  51273         *local_port = BCM_GPORT_MIM_PORT_ID_GET(gport);
  51274     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  51275         *local_port = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  51276     } else if (BCM_GPORT_IS_TRUNK(gport)) {
  51277 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  51278         if (soc_feature(unit, soc_feature_vp_lag)) {
  51279             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit,
  51280                      BCM_GPORT_TRUNK_GET(gport),local_port);
  51281             return (rv != BCM_E_NONE) ? BCM_E_PORT : BCM_E_NONE;
  51282         }
  51283 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  51284         return BCM_E_PORT;
  51285     } else if (BCM_GPORT_IS_VP_GROUP(gport)) {
  51286         *local_port = BCM_GPORT_VP_GROUP_GET(gport);
  51287     } else {
  51288         return BCM_E_PORT;
  51289     }
  51290 
  51291     return BCM_E_NONE;
  51292 }
  51293 
  51294 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  51295 
  51296 /*
  51297  * Function    : _bcm_esw_modid_is_coe_mod
  51298  * Description : Identifies if given modid is a CoE module
  51299  *
  51300  * Parameters  : (IN)   unit      - BCM device number
  51301  *               (IN)   modnd     - Module ID
  51302  * Returns     : BCM_E_NONE, if it is a CoE Module
  51303  *               BCM_E_NOT_FOUND, if it is not a CoE Module
  51304  */
  51305 
  51306 int
  51307 _bcm_esw_modid_is_coe_mod(int unit, bcm_module_t modid)
  51308 {
  51309     bcm_stk_modid_config_t mod_cfg;
  51310     mod_cfg.modid = modid;
  51311 
  51312 	mod_cfg.modid_type = bcmStkModidTypeCoe;
  51313 
  51314     /* Also check if this is one of the CoE modules */
  51315     return bcm_esw_stk_modid_config_get(unit, &mod_cfg);
  51316 }
  51317 #endif
  51318 
  51319 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  51320 /*
  51321  * Function    : _bcm_esw_modid_is_multi_nexthop_mod
  51322  * Description : Identifies if given modid is a Multi Next Hop module
  51323  *
  51324  * Parameters  : (IN)   unit      - BCM device number
  51325  *               (IN)   modnd     - Module ID
  51326  * Returns     : BCM_E_NONE, if it is a Multi Next Hop Module
  51327  *               BCM_E_NOT_FOUND, if it is not a Multi Next Hop Module
  51328  */
  51329 
  51330 int
  51331 _bcm_esw_modid_is_multi_nexthop_mod(int unit, bcm_module_t modid)
  51332 {
  51333     bcm_stk_modid_config_t mod_cfg;
  51334 
  51335     if ((modid < 0) || (modid > SOC_MODID_MAX(unit))) {
  51336         return BCM_E_PARAM;
  51337     }
  51338     mod_cfg.modid = modid;
  51339     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  51340 
  51341     /* Also check if this is one of the Multi Next Hop modules */
  51342     return bcm_esw_stk_modid_config_get(unit, &mod_cfg);
  51343 }
  51344 
  51345 /*
  51346   * Function    : _bcm_esw_is_multi_nexthop_mod_port
  51347   * Description : Identifies if given modid is a Multi Next Hop module port
  51348   *
  51349   * Parameters  : (IN)   unit - BCM device number
  51350   *               (IN)   modid - Mod Id value
  51351   *               (IN)   port - Port Id value
  51352   * Returns : TRUE if is Multi Next Hop module port, FALSE otherwise
  51353   */
  51354 int
  51355 _bcm_esw_is_multi_nexthop_mod_port(int unit, bcm_module_t modid,
  51356                                          bcm_port_t port)
  51357 {
  51358     int rv = BCM_E_NONE;
  51359     int result = FALSE;
  51360 
  51361     if(_bcm_esw_modid_is_multi_nexthop_mod(unit, modid) == BCM_E_NONE) {
  51362         if (port <= src_modid_base_index_bk[unit]->num_ports[modid]) {
  51363             return TRUE;
  51364         }
  51365     } else {
  51366         rv = _bcm_esw_my_modid_additional_check(unit, modid, &result);
  51367         if (BCM_FAILURE(rv)) {
  51368             return FALSE;
  51369         }
  51370         return result;
  51371     }
  51372     return FALSE;
  51373 }
  51374 #endif
  51375 
  51376 /*
  51377  * Function    : _bcm_esw_modid_is_local
  51378  * Description : Identifies if given modid is local on a given unit
  51379  *
  51380  * Parameters  : (IN)   unit      - BCM device number
  51381  *               (IN)   modnd     - Module ID
  51382  *               (OUT)  result    - TRUE if modid is local, FALSE otherwise
  51383  * Returns     : BCM_E_XXX
  51384  */
  51385 int
  51386 _bcm_esw_modid_is_local(int unit, bcm_module_t modid, int *result)
  51387 {
  51388     bcm_module_t    mymodid;
  51389     int             rv;
  51390     soc_info_t *si=&SOC_INFO(unit);
  51391 
  51392     /* Input parameters check. */
  51393     if (NULL == result) {
  51394         return (BCM_E_PARAM);
  51395     }
  51396 
  51397     COMPILER_REFERENCE(si);
  51398 
  51399     /* Get local module id. */
  51400     rv = bcm_esw_stk_my_modid_get(unit, &mymodid);
  51401     if (BCM_E_UNAVAIL == rv) {
  51402         if (BCM_MODID_INVALID == modid) {
  51403             *result = TRUE;
  51404         } else {
  51405 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  51406             /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode)
  51407                check the local modid */
  51408             if (((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  51409                 soc_feature(unit, soc_feature_channelized_switching)) ||
  51410                 ((soc_feature(unit, soc_feature_subtag_coe) ||
  51411                   (soc_feature(unit, soc_feature_linkphy_coe))) &&
  51412                   si->coe_stacking_mode)) &&
  51413                 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) {
  51414                     *result = TRUE;
  51415             } else
  51416 #endif
  51417             {
  51418                 *result = FALSE;
  51419             }
  51420         }
  51421         return (BCM_E_NONE);
  51422     }
  51423 
  51424     if (mymodid == modid) {
  51425         *result = TRUE;
  51426     } else if ((modid > mymodid) && (modid < mymodid + NUM_MODID(unit))) {
  51427         *result = TRUE;
  51428     }
  51429 #if defined(BCM_HGPROXY_COE_SUPPORT)  || defined(BCM_KATANA2_SUPPORT)
  51430     /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode)
  51431        check the local modid */
  51432     else if (((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  51433         soc_feature(unit, soc_feature_channelized_switching)) ||
  51434         ((soc_feature(unit, soc_feature_subtag_coe) ||
  51435           (soc_feature(unit, soc_feature_linkphy_coe))) &&
  51436           si->coe_stacking_mode)) &&
  51437         (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) {
  51438             *result = TRUE;
  51439 	}
  51440 #endif /* BCM_HGPROXY_COE_SUPPORT || BCM_KATANA2_SUPPORT */
  51441     else {
  51442         *result = FALSE;
  51443     }
  51444 
  51445     return (BCM_E_NONE);
  51446 }
  51447 
  51448 
  51449 /*
  51450  * Function    : _bcm_gport_modport_hw2api_map
  51451  * Description : Remaps module and port from HW space to API space
  51452  *
  51453  * Parameters  : (IN)  unit      - BCM device number
  51454  *               (IN)  mod_in    - Module ID to map
  51455  *               (IN)  port_in   - Physical port to map
  51456  *               (OUT)  mod_out  - Module ID after mapping
  51457  *               (OUT)  port_out - Port number after mapping
  51458  * Returns     : BCM_E_XXX
  51459  * Notes       : If mod_out == NULL then port_out will be local physical port.
  51460  */
  51461 int
  51462 _bcm_gport_modport_hw2api_map(int unit, bcm_module_t mod_in, bcm_port_t port_in,
  51463                               bcm_module_t *mod_out, bcm_port_t *port_out)
  51464 {
  51465     if (port_out == NULL) {
  51466         return (BCM_E_PARAM);
  51467     }
  51468 
  51469     if (NUM_MODID(unit) == 1) { /* HW device has single modid */
  51470         if (mod_out != NULL) {
  51471             *mod_out = mod_in;
  51472         }
  51473         *port_out = port_in;
  51474 
  51475         return (BCM_E_NONE);
  51476     }
  51477     /* Here only for devices with multiple modid NUM_MODID(unit) > 1 */
  51478     if (mod_out == NULL) {  /* physical port requested */
  51479         int             isLocal = 0;
  51480         bcm_module_t    mymodid;
  51481         BCM_IF_ERROR_RETURN(
  51482             _bcm_esw_modid_is_local(unit, mod_in, &isLocal));
  51483         if (isLocal != TRUE) {
  51484             return (BCM_E_PARAM);
  51485         }
  51486         BCM_IF_ERROR_RETURN (bcm_esw_stk_my_modid_get(unit, &mymodid));
  51487 
  51488 #if defined(BCM_TOMAHAWK_SUPPORT)
  51489         /* Call asymmetric dual modid unmapping function */
  51490         if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  51491             BCM_IF_ERROR_RETURN (
  51492                 _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  51493                             BCM_STK_MODMAP_SET, &mod_in, &port_in));
  51494             *port_out = port_in;
  51495         } else
  51496 #endif /* BCM_TOMAHAWK_SUPPORT */
  51497         {
  51498             *port_out = port_in +
  51499                 (mod_in - mymodid) * (SOC_MODPORT_MAX(unit) + 1);
  51500         }
  51501     } else {    /* NUM_MODID(unit) > 1 and not local physical port */
  51502 #if defined(BCM_TOMAHAWK_SUPPORT)
  51503         /* Call asymmetric dual modid mapping function */
  51504         if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  51505             BCM_IF_ERROR_RETURN (
  51506                 _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  51507                             BCM_STK_MODMAP_GET, &mod_in, &port_in));
  51508             *mod_out = mod_in;
  51509             *port_out = port_in;
  51510         } else
  51511 #endif /* BCM_TOMAHAWK_SUPPORT */
  51512         {
  51513             *port_out = port_in % (SOC_MODPORT_MAX(unit) + 1);
  51514             *mod_out = mod_in + port_in / (SOC_MODPORT_MAX(unit) + 1);
  51515         }
  51516     }
  51517 
  51518     return (BCM_E_NONE);
  51519 }
  51520 
  51521 /*
  51522  * Function    : bcm_port_gport_get
  51523  * Description : Get the GPORT ID for the specified physical port.
  51524  *
  51525  * Parameters  : (IN)  unit      - BCM device number
  51526  *               (IN)  port      - Port number
  51527  *               (OUT) gport     - GPORT ID
  51528  * Returns     : BCM_E_XXX
  51529  * Notes:
  51530  *     Always returns a MODPORT gport or an error.
  51531  */
  51532 int
  51533 bcm_esw_port_gport_get(int unit, bcm_port_t port, bcm_gport_t *gport)
  51534 {
  51535     int                 rv;
  51536     _bcm_gport_dest_t   dest;
  51537 
  51538     /* Make sure port module is initialized. */
  51539     PORT_INIT(unit);
  51540 
  51541     _bcm_gport_dest_t_init(&dest);
  51542 
  51543 #if defined(BCM_FIREBOLT6_SUPPORT)
  51544     if (SOC_IS_FIREBOLT6(unit)) {
  51545         BCM_IF_ERROR_RETURN
  51546             (bcm_fb6_port_param_check(unit, port));
  51547     } else
  51548 #endif
  51549     {
  51550         PORT_PARAM_CHECK(unit, port);
  51551     }
  51552 
  51553     rv = bcm_esw_stk_my_modid_get(unit, &dest.modid);
  51554 
  51555     if (BCM_FAILURE(rv)) {
  51556         return BCM_E_UNAVAIL;
  51557     }
  51558 
  51559     if (soc_feature(unit, soc_feature_sysport_remap)) {
  51560         BCM_XLATE_SYSPORT_P2S(unit, &port);
  51561     }
  51562 
  51563     dest.port = port;
  51564     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  51565 
  51566     /* In this case we can safely assume that a port is in hw format */
  51567     /* since it is a physical port number */
  51568     BCM_IF_ERROR_RETURN
  51569         (_bcm_gport_modport_hw2api_map(unit, dest.modid, dest.port,
  51570                                        &(dest.modid), &(dest.port)));
  51571 
  51572     return _bcm_esw_gport_construct(unit, &dest, gport);
  51573 }
  51574 
  51575 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  51576 /*
  51577  * Function    : bcm_port_gport_add
  51578  * Description : Add the GPORT ID for the specified physical port.
  51579  *
  51580  * Parameters  : (IN)  unit             - BCM device number
  51581  *               (IN)  local_port     - Port number
  51582  *               (IN)  modport       - GPORT ID
  51583  * Returns     : BCM_E_XXX
  51584  */
  51585 int
  51586 _bcm_esw_port_gport_add(int unit, bcm_port_t local_port,
  51587                                bcm_gport_t modport)
  51588 {
  51589     int subport_index = 0;
  51590     bcm_port_t old_local_port = 0;
  51591     modport_map_subport_entry_t modport_map_subport_entry;
  51592 
  51593     /* Make sure port module is initialized. */
  51594     PORT_INIT(unit);
  51595 
  51596     /* Parameter check */
  51597     PORT_PARAM_CHECK(unit, local_port);
  51598     if (!BCM_GPORT_IS_MODPORT(modport)) {
  51599         return BCM_E_PARAM;
  51600     }
  51601 
  51602     SOC_IF_ERROR_RETURN(
  51603         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  51604 
  51605     SOC_IF_ERROR_RETURN
  51606         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  51607                                        &modport_map_subport_entry));
  51608     old_local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51609                                        &modport_map_subport_entry, DESTf);
  51610     if(old_local_port == local_port) {
  51611         return BCM_E_NONE;
  51612     }
  51613     if(old_local_port) {
  51614         return BCM_E_RESOURCE;
  51615     }
  51616 
  51617     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  51618                          &modport_map_subport_entry, DESTf, local_port);
  51619     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  51620                          &modport_map_subport_entry, ISTRUNKf, 0);
  51621     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  51622                          &modport_map_subport_entry, ENABLEf, 1);
  51623     SOC_IF_ERROR_RETURN
  51624         (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  51625                                         &modport_map_subport_entry));
  51626 
  51627     return BCM_E_NONE;
  51628 }
  51629 
  51630 /*
  51631  * Function    : bcm_port_gport_get_all
  51632  * Description : Get all the extra GPORT ID for the specified physical port.
  51633  *
  51634  * Parameters  : (IN)     unit                 - BCM device number
  51635  *                     (IN)     local_port        - Port number
  51636  *                     (IN)     modport_max   - size of gport array
  51637  *                     (OUT)  gport_array      - Gport number
  51638  *                     (OUT)  count              - GPORT count
  51639  * Returns     : BCM_E_XXX
  51640  * Notes:
  51641  *     Always returns MODPORT gports or an error.
  51642  */
  51643 int _bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size,
  51644                                       bcm_gport_t *gport_array, int *count)
  51645 {
  51646     int rv = BCM_E_NONE;
  51647     int mod_idx = 0;
  51648     int port_idx = 0;
  51649     int base_index = 0;
  51650     bcm_gport_t modport = 0;
  51651     _bcm_gport_dest_t dest;
  51652     bcm_port_t egress_port = 0;
  51653     bcm_stk_modid_config_t mod_cfg;
  51654     modid_base_ptr_entry_t modid_base_entry;
  51655     modport_map_subport_entry_t modport_map_subport_entry;
  51656     soc_info_t *si = &SOC_INFO(unit);
  51657     int i = 0, valid = 0, modid = 0, n_ports = 0;
  51658 
  51659     /* Make sure port module is initialized. */
  51660     PORT_INIT(unit);
  51661 
  51662     /* Parameter check */
  51663     PORT_PARAM_CHECK(unit, local_port);
  51664     if (size < 0 || count == NULL) {
  51665         return BCM_E_PARAM;
  51666     }
  51667 
  51668     if ((size > 0) && gport_array == NULL) {
  51669         return BCM_E_PARAM;
  51670     }
  51671 
  51672     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  51673     mod_cfg.modid = BCM_MODID_INVALID;
  51674     BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_config_get(unit, &mod_cfg));
  51675 
  51676     *count = 0;
  51677     if (size == 0) {
  51678         if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51679             for (i = 0; i < si->num_modules; i++) {
  51680                 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  51681                     BCM_MODID_INVALID) {
  51682                     continue;
  51683                 }
  51684                 BCM_IF_ERROR_RETURN(
  51685                     _bcm_esw_stk_get_mod_config_by_type(unit,
  51686                     BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  51687                     &base_index));
  51688                 if (valid == 0) {
  51689                     continue;
  51690                 }
  51691                 n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  51692                 for (port_idx = base_index; port_idx < base_index + n_ports;
  51693                      port_idx++) {
  51694                      SOC_IF_ERROR_RETURN
  51695                          (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  51696                                                     &modport_map_subport_entry));
  51697                      /* Check if index is used. */
  51698                      egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51699                                                  &modport_map_subport_entry, DESTf);
  51700                      if(egress_port == local_port) {/*  Entry found. */
  51701                          (*count)++;
  51702                      }
  51703                 }
  51704             }
  51705         }
  51706 
  51707         for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods;
  51708              mod_idx ++) {
  51709             MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  51710             SOC_IF_ERROR_RETURN(
  51711                 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx,
  51712                 &modid_base_entry));
  51713             base_index =
  51714                 soc_MODID_BASE_PTRm_field32_get(unit, &modid_base_entry,
  51715                 MODID_BASEf);
  51716             SOC_IF_ERROR_RETURN(
  51717                 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  51718                 &modport_map_subport_entry));
  51719             /* Check if index is used. */
  51720             egress_port =
  51721                 soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51722                 &modport_map_subport_entry, DESTf);
  51723             if (egress_port == local_port) {/*  Entry found. */
  51724                 (*count)++;
  51725             }
  51726         }
  51727         return BCM_E_NONE;
  51728     }
  51729 
  51730     _bcm_gport_dest_t_init(&dest);
  51731     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51732         for (i = 0; i < si->num_modules; i++) {
  51733             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  51734                 BCM_MODID_INVALID) {
  51735                 continue;
  51736             }
  51737             BCM_IF_ERROR_RETURN(
  51738                 _bcm_esw_stk_get_mod_config_by_type(unit,
  51739                 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  51740                 &base_index));
  51741             if (valid == 0) {
  51742                 continue;
  51743             }
  51744             n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  51745             for (port_idx = base_index; port_idx < base_index + n_ports;
  51746                  port_idx++) {
  51747                 if ((*count) < size) {
  51748                     SOC_IF_ERROR_RETURN
  51749                         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  51750                                                    &modport_map_subport_entry));
  51751                     /* Check if index is used. */
  51752                     egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51753                                                 &modport_map_subport_entry, DESTf);
  51754                     if (egress_port == local_port) {
  51755                         /*  Entry found. */
  51756                         dest.port = port_idx - base_index;
  51757                         dest.modid = modid;
  51758                         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  51759                         rv = _bcm_esw_gport_construct(unit, &dest, &modport);
  51760                         gport_array[(*count)++] = modport;
  51761                     }
  51762                 }
  51763             }
  51764         }
  51765     }
  51766 
  51767     for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods;
  51768          mod_idx ++) {
  51769         MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  51770         SOC_IF_ERROR_RETURN
  51771             (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry));
  51772         base_index = soc_MODID_BASE_PTRm_field32_get(unit,
  51773                                        &modid_base_entry, MODID_BASEf);
  51774         if ((*count) < size) {
  51775             SOC_IF_ERROR_RETURN(
  51776                 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  51777                 &modport_map_subport_entry));
  51778             /* Check if index is used. */
  51779             egress_port =
  51780                 soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51781                 &modport_map_subport_entry, DESTf);
  51782             if (egress_port == local_port) {
  51783                 /*  Entry found. */
  51784                 dest.port = BCM_PORT_INVALID;
  51785                 dest.modid = mod_idx;
  51786                 dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  51787                 rv = _bcm_esw_gport_construct(unit, &dest, &modport);
  51788                 gport_array[(*count)++] = modport;
  51789             }
  51790         }
  51791     }
  51792 
  51793     return rv;
  51794 }
  51795 
  51796 /*
  51797  * Function    : bcm_port_gport_delete
  51798  * Description : Delete the mapping of the specified GPORT.
  51799  *
  51800  * Parameters  : (IN)  unit             - BCM device number
  51801  *                     (IN) modport        - GPORT ID
  51802  * Returns     : BCM_E_XXX
  51803  */
  51804 int
  51805 _bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport)
  51806 {
  51807     int subport_index = 0;
  51808     modport_map_subport_entry_t modport_map_subport_entry;
  51809 
  51810     /* Make sure port module is initialized. */
  51811     PORT_INIT(unit);
  51812 
  51813     /* Parameter check */
  51814     PORT_PARAM_CHECK(unit, local_port);
  51815     if (!BCM_GPORT_IS_MODPORT(modport)) {
  51816         return BCM_E_PARAM;
  51817     }
  51818 
  51819     SOC_IF_ERROR_RETURN(
  51820         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  51821 
  51822     SOC_IF_ERROR_RETURN
  51823         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  51824                                    &modport_map_subport_entry));
  51825     soc_MODPORT_MAP_SUBPORTm_field32_set(unit,
  51826                                    &modport_map_subport_entry, DESTf, 0);
  51827     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  51828                                    &modport_map_subport_entry, ISTRUNKf, 0);
  51829     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  51830                                  &modport_map_subport_entry, ENABLEf, 0);
  51831     SOC_IF_ERROR_RETURN
  51832         (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  51833                                         &modport_map_subport_entry));
  51834 
  51835     return BCM_E_NONE;
  51836 }
  51837 
  51838 /*
  51839  * Function    : bcm_port_gport_delete_all
  51840  * Description : Delete all the extra mapping of the specified physical port.
  51841  *
  51842  * Parameters  : (IN)  unit             - BCM device number
  51843  *                     (IN) local_port      - PORT ID
  51844  * Returns     : BCM_E_XXX
  51845  */
  51846 int
  51847 _bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port)
  51848 {
  51849     int mod_idx = 0;
  51850     int port_idx = 0;
  51851     int base_index = 0;
  51852     bcm_port_t egress_port = 0;
  51853     bcm_stk_modid_config_t mod_cfg;
  51854     modid_base_ptr_entry_t modid_base_entry;
  51855     modport_map_subport_entry_t modport_map_subport_entry;
  51856     soc_info_t *si = &SOC_INFO(unit);
  51857     int i = 0, valid = 0, modid = 0, n_ports = 0;
  51858 
  51859     /* Make sure port module is initialized. */
  51860     PORT_INIT(unit);
  51861 
  51862     /* Parameter check */
  51863     PORT_PARAM_CHECK(unit, local_port);
  51864 
  51865     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  51866     mod_cfg.modid = BCM_MODID_INVALID;
  51867     BCM_IF_ERROR_RETURN(
  51868         bcm_esw_stk_modid_config_get(unit, &mod_cfg));
  51869 
  51870     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51871         for (i = 0; i < si->num_modules; i++) {
  51872             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  51873                 BCM_MODID_INVALID) {
  51874                 continue;
  51875             }
  51876             BCM_IF_ERROR_RETURN(
  51877                 _bcm_esw_stk_get_mod_config_by_type(unit,
  51878                 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  51879                 &base_index));
  51880             if (valid == 0) {
  51881                 continue;
  51882             }
  51883             n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  51884             for (port_idx = base_index; port_idx < base_index + n_ports;
  51885                  port_idx++) {
  51886                  SOC_IF_ERROR_RETURN
  51887                      (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  51888                                                 &modport_map_subport_entry));
  51889                  /* Check if index is used. */
  51890                  egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51891                                              &modport_map_subport_entry, DESTf);
  51892                  if(egress_port == local_port) {
  51893                      /*  Entry found. */
  51894                      soc_MODPORT_MAP_SUBPORTm_field32_set(
  51895                          unit, &modport_map_subport_entry, DESTf, 0);
  51896                      soc_MODPORT_MAP_SUBPORTm_field32_set(
  51897                          unit, &modport_map_subport_entry, ENABLEf, 0);
  51898                      SOC_IF_ERROR_RETURN
  51899                          (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  51900                                                      &modport_map_subport_entry));
  51901                  }
  51902             }
  51903         }
  51904     }
  51905 
  51906     for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods;
  51907          mod_idx ++) {
  51908         MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  51909         SOC_IF_ERROR_RETURN
  51910             (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry));
  51911         base_index = soc_MODID_BASE_PTRm_field32_get(unit,
  51912                                            &modid_base_entry, MODID_BASEf);
  51913         SOC_IF_ERROR_RETURN(
  51914             READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  51915             &modport_map_subport_entry));
  51916         /* Check if index is used. */
  51917         egress_port =
  51918             soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  51919             &modport_map_subport_entry, DESTf);
  51920         if (egress_port == local_port) {
  51921             /*  Entry found. */
  51922             soc_MODPORT_MAP_SUBPORTm_field32_set(
  51923                 unit, &modport_map_subport_entry, DESTf, 0);
  51924             soc_MODPORT_MAP_SUBPORTm_field32_set(
  51925                 unit, &modport_map_subport_entry, ENABLEf, 0);
  51926             SOC_IF_ERROR_RETURN(
  51927                 WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  51928                 &modport_map_subport_entry));
  51929         }
  51930     }
  51931 
  51932     return BCM_E_NONE;
  51933 }
  51934 
  51935 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  51936 
  51937 /*
  51938  * Function    : bcm_port_gport_add
  51939  * Description : Add the GPORT ID for the specified physical port.
  51940  *
  51941  * Parameters  : (IN)  unit             - BCM device number
  51942  *                     (IN)  local_port     - Port number
  51943  *                     (IN)  modport       - GPORT ID
  51944  * Returns     : BCM_E_XXX
  51945  */
  51946 int
  51947 bcm_esw_port_gport_add(int unit, bcm_port_t local_port,
  51948                                bcm_gport_t modport)
  51949 {
  51950     int rv = BCM_E_UNAVAIL;
  51951 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  51952     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51953         rv = _bcm_esw_port_gport_add(unit, local_port, modport);
  51954     }
  51955 #endif
  51956     return rv;
  51957 }
  51958 
  51959 /*
  51960  * Function    : bcm_port_gport_get_all
  51961  * Description : Get all the extra GPORT ID for the specified physical port.
  51962  *
  51963  * Parameters  : (IN)     unit                 - BCM device number
  51964  *                     (IN)     local_port        - Port number
  51965  *                     (IN)     modport_max   - size of gport array
  51966  *                     (OUT)  gport_array      - Gport number
  51967  *                     (OUT)  count              - GPORT count
  51968  * Returns     : BCM_E_XXX
  51969  * Notes:
  51970  */
  51971 int bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size,
  51972                                       bcm_gport_t *gport_array, int *count)
  51973 {
  51974     int rv = BCM_E_UNAVAIL;
  51975 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  51976     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  51977         if (size < 0 || count == NULL) {
  51978             return BCM_E_PARAM;
  51979         }
  51980 
  51981         if ((size > 0) && gport_array == NULL) {
  51982             return BCM_E_PARAM;
  51983         }
  51984 
  51985         rv = _bcm_esw_port_gport_get_all(unit, local_port, size, gport_array, count);
  51986     }
  51987 #endif
  51988     return rv;
  51989 }
  51990 
  51991 /*
  51992  * Function    : bcm_port_gport_delete
  51993  * Description : Delete the mapping of the specified GPORT.
  51994  *
  51995  * Parameters  : (IN)  unit             - BCM device number
  51996  *                     (IN) modport        - GPORT ID
  51997  * Returns     : BCM_E_XXX
  51998  */
  51999 int
  52000 bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport)
  52001 {
  52002     int rv = BCM_E_UNAVAIL;
  52003 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  52004     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  52005         rv = _bcm_esw_port_gport_delete(unit, local_port, modport);
  52006     }
  52007 #endif
  52008     return rv;
  52009 }
  52010 
  52011 /*
  52012  * Function    : bcm_port_gport_delete_all
  52013  * Description : Delete all the extra mapping of the specified physical port.
  52014  *
  52015  * Parameters  : (IN)  unit             - BCM device number
  52016  *                     (IN) local_port      - PORT ID
  52017  * Returns     : BCM_E_XXX
  52018  */
  52019 int
  52020 bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port)
  52021 {
  52022     int rv = BCM_E_UNAVAIL;
  52023 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  52024     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  52025         rv = _bcm_esw_port_gport_delete_all(unit, local_port);
  52026     }
  52027 #endif
  52028     return rv;
  52029 }
  52030 
  52031 /*
  52032  * Function:
  52033  *      bcm_esw_port_gport_is_free
  52034  * Purpose:
  52035  *      Request if the given gport value is available on the device
  52036  * Parameters:
  52037  *      unit - (IN) Unit number.
  52038  *      gport - (IN) GPORT ID.
  52039  * Returns:
  52040  *      BCM_E_NONE -    gport is valid and available on the device
  52041  *      BCM_E_EXISTS -  gport is valid but already in use
  52042  *                      on this device
  52043  *      BCM_E_PARAM -   gport is not valid on this device
  52044  *      BCM_E_UNAVAIL - Feature unavailable
  52045  * Notes:
  52046  */
  52047 int
  52048 bcm_esw_port_gport_is_free(int unit, bcm_gport_t gport)
  52049 {
  52050 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  52051     int             rv = BCM_E_PARAM;
  52052     int             vp = 0, vp_idx, rv_vp = 0, is_vp = FALSE;
  52053     int             vp_count = 1;     /* Required consecutive VP's */
  52054 
  52055     /* Make sure port module is initialized. */
  52056     PORT_INIT(unit);
  52057 
  52058     if (!soc_mem_is_valid(unit, SOURCE_VPm)) {
  52059         /* No virtual ports at this time. */
  52060         return BCM_E_UNAVAIL;
  52061     }
  52062 
  52063 #if defined(BCM_MPLS_SUPPORT)
  52064     if (BCM_GPORT_IS_MPLS_PORT(gport) &&
  52065              soc_feature(unit, soc_feature_mpls)) {
  52066         is_vp = TRUE;
  52067         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  52068         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52069             rv_vp = -1;
  52070         } else {
  52071             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMpls);
  52072         }
  52073     } else
  52074 #endif /* BCM_MPLS_SUPPORT */
  52075     if (BCM_GPORT_IS_MIM_PORT(gport) &&
  52076              soc_feature(unit, soc_feature_mim)) {
  52077         is_vp = TRUE;
  52078         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  52079         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52080             rv_vp = -1;
  52081         } else {
  52082             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMim);
  52083         }
  52084     } else if (BCM_GPORT_IS_L2GRE_PORT(gport) &&
  52085              soc_feature(unit, soc_feature_l2gre)) {
  52086         is_vp = TRUE;
  52087         vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
  52088         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52089             rv_vp = -1;
  52090         } else {
  52091             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre);
  52092         }
  52093     } else if (BCM_GPORT_IS_VXLAN_PORT(gport) &&
  52094              soc_feature(unit, soc_feature_vxlan)) {
  52095         is_vp = TRUE;
  52096         vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
  52097         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52098             rv_vp = -1;
  52099         } else {
  52100             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan);
  52101         }
  52102     } else if (BCM_GPORT_IS_FLOW_PORT(gport) &&
  52103              soc_feature(unit, soc_feature_flex_flow)) {
  52104         is_vp = TRUE;
  52105         vp = BCM_GPORT_FLOW_PORT_ID_GET(gport);
  52106         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52107             rv_vp = -1;
  52108         } else {
  52109             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeFlow);
  52110         }
  52111     } else if (BCM_GPORT_IS_WLAN_PORT(gport) &&
  52112              soc_feature(unit, soc_feature_wlan)) {
  52113         is_vp = TRUE;
  52114         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  52115         if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) {
  52116             if (vp > soc_mem_index_count(unit, WLAN_SVP_TABLEm)) {
  52117                 rv_vp = -1;
  52118             } else {
  52119                 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan);
  52120             }
  52121 
  52122         } else if (SOC_MEM_IS_VALID(unit, SOURCE_VP_ATTRIBUTES_2m)) {
  52123             if (vp > soc_mem_index_count(unit, SOURCE_VP_ATTRIBUTES_2m)) {
  52124                 rv_vp = -1;
  52125             } else {
  52126                 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan);
  52127             }
  52128         } else {
  52129             rv_vp = -1;
  52130         }
  52131     } else if (BCM_GPORT_IS_TRILL_PORT(gport) &&
  52132              soc_feature(unit, soc_feature_trill)) {
  52133         is_vp = TRUE;
  52134         vp = BCM_GPORT_TRILL_PORT_ID_GET(gport);
  52135         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52136             rv_vp = -1;
  52137         } else {
  52138             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeTrill);
  52139         }
  52140     } else if (BCM_GPORT_IS_VLAN_PORT(gport) &&
  52141              soc_feature(unit, soc_feature_vlan_vp)) {
  52142         is_vp = TRUE;
  52143         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
  52144         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52145             rv_vp = -1;
  52146         } else {
  52147             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVlan);
  52148         }
  52149     } else if (BCM_GPORT_IS_NIV_PORT(gport) &&
  52150              soc_feature(unit, soc_feature_niv)) {
  52151         is_vp = TRUE;
  52152         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
  52153         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  52154             rv_vp = -1;
  52155         } else {
  52156             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeNiv);
  52157         }
  52158     }
  52159 #if defined(BCM_TRIUMPH2_SUPPORT)
  52160     else if ((BCM_GPORT_IS_SUBPORT_GROUP(gport) ||
  52161               BCM_GPORT_IS_SUBPORT_PORT(gport)) &&
  52162              soc_feature(unit, soc_feature_subport_enhanced)) {
  52163         /* No TR/SC support for now */
  52164         rv_vp = _bcm_tr2_subport_gport_used(unit, gport);
  52165         if (BCM_E_NOT_FOUND == rv_vp) {
  52166             rv = BCM_E_NONE;
  52167             /* Now we need to check if the VP is in use by something else,
  52168              * using the logic below. */
  52169             is_vp = TRUE;
  52170             rv_vp = 0;
  52171             if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) {
  52172                 vp = BCM_GPORT_SUBPORT_GROUP_GET(gport);
  52173                 vp = (vp / 8) * 8;
  52174                 vp_count = 8;
  52175             } else {
  52176                 vp = BCM_GPORT_SUBPORT_PORT_GET(gport);
  52177             }
  52178         } else if (BCM_E_NONE == rv_vp) {
  52179             rv = BCM_E_EXISTS;
  52180         } else {
  52181             rv = rv_vp;
  52182         }
  52183     }
  52184 #endif /* BCM_TRIUMPH2_SUPPORT */
  52185 
  52186     if (is_vp) {
  52187         if (0 == rv_vp) {
  52188             /* Double-check no other protocol is using this VP */
  52189             for (vp_idx = 0; vp_idx < vp_count; vp_idx++) {
  52190                 rv_vp = _bcm_vp_used_get(unit, vp + vp_idx, _bcmVpTypeAny);
  52191                 if (0 == rv_vp) {
  52192                     rv = BCM_E_NONE;
  52193                 } else {
  52194                     rv = BCM_E_EXISTS;
  52195                     break;
  52196                 }
  52197             }
  52198         } else if (-1 != rv_vp) {
  52199             rv =  BCM_E_EXISTS;
  52200         } /* else parameter error */
  52201     }
  52202     /* subport */
  52203 
  52204     return rv;
  52205 #else
  52206     return BCM_E_UNAVAIL;
  52207 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
  52208 }
  52209 
  52210 /*
  52211  * Function:
  52212  *      bcm_esw_port_gport_free_range_get
  52213  * Purpose:
  52214  *      Retrieve the minimum and maximum unallocated gport values for
  52215  *       a given gport type.
  52216  * Parameters:
  52217  *      unit - (IN) Unit number.
  52218  *      gport_type - (IN) One of BCM_GPORT_TYPE_* or BCM_GPORT_*_PORT values.
  52219  *      gport_min - (OUT) Minimum available gport value of type gport_type
  52220  *      gport_max - (OUT) Maximum available gport value of type gport_type
  52221  * Returns:
  52222  *      BCM_E_NONE -      Valid gports range of requested type returned
  52223  *      BCM_E_NOT_FOUND - No available gports of this type
  52224  *      BCM_E_PARAM -     Gport type is not valid on this device
  52225  *      BCM_E_UNAVAIL -   Feature unavailable
  52226  * Notes:
  52227  */
  52228 int
  52229 bcm_esw_port_gport_free_range_get(int unit, uint32 gport_type,
  52230                                   bcm_gport_t *gport_min,
  52231                                   bcm_gport_t *gport_max)
  52232 {
  52233 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  52234     bcm_gport_t     dev_min, dev_max, gport, free_min, free_max;
  52235     int             rv = BCM_E_PARAM;
  52236     int             svp_max;
  52237 
  52238     /* Make sure port module is initialized. */
  52239     PORT_INIT(unit);
  52240 
  52241     if (soc_mem_is_valid(unit, SOURCE_VPm)) {
  52242         svp_max = soc_mem_index_max(unit, SOURCE_VPm);
  52243     } else {
  52244         /* No virtual ports at this time. */
  52245         return BCM_E_UNAVAIL;
  52246     }
  52247 
  52248     switch (gport_type) {
  52249     case BCM_GPORT_MPLS_PORT:
  52250         BCM_GPORT_MPLS_PORT_ID_SET(dev_min, 0);
  52251         BCM_GPORT_MPLS_PORT_ID_SET(dev_max, svp_max);
  52252         break;
  52253     case BCM_GPORT_MIM_PORT:
  52254         BCM_GPORT_MIM_PORT_ID_SET(dev_min, 0);
  52255         BCM_GPORT_MIM_PORT_ID_SET(dev_max, svp_max);
  52256         break;
  52257     case BCM_GPORT_L2GRE_PORT:
  52258         BCM_GPORT_L2GRE_PORT_ID_SET(dev_min, 0);
  52259         BCM_GPORT_L2GRE_PORT_ID_SET(dev_max, svp_max);
  52260         break;
  52261     case BCM_GPORT_VXLAN_PORT:
  52262         BCM_GPORT_VXLAN_PORT_ID_SET(dev_min, 0);
  52263         BCM_GPORT_VXLAN_PORT_ID_SET(dev_max, svp_max);
  52264         break;
  52265     case BCM_GPORT_WLAN_PORT:
  52266         BCM_GPORT_WLAN_PORT_ID_SET(dev_min, 0);
  52267         BCM_GPORT_WLAN_PORT_ID_SET(dev_max, svp_max);
  52268         break;
  52269     case BCM_GPORT_TRILL_PORT:
  52270         BCM_GPORT_TRILL_PORT_ID_SET(dev_min, 0);
  52271         BCM_GPORT_TRILL_PORT_ID_SET(dev_max, svp_max);
  52272         break;
  52273     case BCM_GPORT_VLAN_PORT:
  52274         BCM_GPORT_VLAN_PORT_ID_SET(dev_min, 0);
  52275         BCM_GPORT_VLAN_PORT_ID_SET(dev_max, svp_max);
  52276         break;
  52277     case BCM_GPORT_NIV_PORT:
  52278         BCM_GPORT_NIV_PORT_ID_SET(dev_min, 0);
  52279         BCM_GPORT_NIV_PORT_ID_SET(dev_max, svp_max);
  52280         break;
  52281     case BCM_GPORT_SUBPORT_GROUP:
  52282         BCM_GPORT_SUBPORT_GROUP_SET(dev_min, 0);
  52283         BCM_GPORT_SUBPORT_GROUP_SET(dev_max, svp_max);
  52284         break;
  52285     case BCM_GPORT_SUBPORT_PORT:
  52286         BCM_GPORT_SUBPORT_PORT_SET(dev_min, 0);
  52287         BCM_GPORT_SUBPORT_PORT_SET(dev_max, svp_max);
  52288         break;
  52289     default:
  52290         /* Not a supported gport type at this time */
  52291         return rv;
  52292     }
  52293 
  52294     free_min = free_max = 0; /* Invalid multicast group */
  52295     for (gport = dev_min; gport <= dev_max; gport++) {
  52296         rv = bcm_esw_port_gport_is_free(unit, gport);
  52297         if (BCM_SUCCESS(rv)) {
  52298             if (0 == free_min) {
  52299                 free_min = gport;
  52300             }
  52301             free_max = gport;
  52302         } else if (BCM_E_EXISTS == rv) {
  52303             /* Nothing to do but clear the error */
  52304             rv = BCM_E_NONE;
  52305         } else if (BCM_E_PARAM == rv) {
  52306             /* Range is less than expected, stop iterating */
  52307             rv = BCM_E_NONE;
  52308             break;
  52309         } else {
  52310             /* Real error, return */
  52311             break;
  52312         }
  52313     }
  52314 
  52315     if (BCM_SUCCESS(rv)) {
  52316         if (0 == free_min) {
  52317             /* No available groups of this type */
  52318             return BCM_E_NOT_FOUND;
  52319         } else {
  52320             /* Copy the results */
  52321             *gport_min = free_min;
  52322             *gport_max = free_max;
  52323         }
  52324     }
  52325 
  52326     return rv;
  52327 
  52328 #else
  52329     return BCM_E_UNAVAIL;
  52330 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
  52331 }
  52332 
  52333 #if defined(BCM_TRIUMPH2_SUPPORT)
  52334 int
  52335 _bcm_esw_port_flex_stat_index_set(int unit, bcm_gport_t port, int fs_idx,
  52336                                   uint32 flags)
  52337 {
  52338     bcm_port_t loc_port;
  52339     int rv;
  52340 
  52341     rv = bcm_esw_port_local_get(unit, port, &loc_port);
  52342     if (BCM_FAILURE(rv)) {
  52343         return BCM_E_NOT_FOUND;  /* Local port disabled */
  52344     }
  52345 
  52346     PORT_LOCK(unit); /* Keep port tables in sync */
  52347     rv = BCM_E_NONE;
  52348     if (flags & _BCM_FLEX_STAT_HW_INGRESS) {
  52349         rv = soc_mem_field32_modify(unit, PORT_TABm, loc_port, VINTF_CTR_IDXf,
  52350                                 fs_idx);
  52351     }
  52352 
  52353     if (flags & _BCM_FLEX_STAT_HW_EGRESS) {
  52354         if (BCM_SUCCESS(rv)) {
  52355 #ifdef BCM_TRIDENT_SUPPORT
  52356             if (SOC_IS_TD_TT(unit)) {
  52357                 rv = soc_mem_field32_modify(unit, EGR_PORTm, loc_port,
  52358                                         VINTF_CTR_IDXf,  fs_idx);
  52359             } else
  52360 #endif /* BCM_TRIDENT_SUPPORT */
  52361             {
  52362                 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, loc_port,
  52363                                         VINTF_CTR_IDXf, fs_idx);
  52364             }
  52365         }
  52366     }
  52367     PORT_UNLOCK(unit);
  52368     return rv;
  52369 }
  52370 
  52371 STATIC int
  52372 _bcm_esw_port_stat_param_verify(int unit, bcm_gport_t port)
  52373 {
  52374     int vp;
  52375 
  52376     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  52377 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  52378         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  52379         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  52380             return BCM_E_PARAM;
  52381         }
  52382 #endif
  52383     } else if (BCM_GPORT_IS_NIV_PORT(port)) {
  52384 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  52385         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  52386 	    if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
  52387 	        return BCM_E_PARAM;
  52388 	    }
  52389 #endif
  52390     } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) ||
  52391                BCM_GPORT_IS_SUBPORT_PORT(port)) {
  52392 
  52393 #if defined(BCM_HGPROXY_COE_SUPPORT)
  52394         if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  52395             soc_feature(unit, soc_feature_channelized_switching)) &&
  52396             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  52397             return bcm_esw_port_local_get(unit, port, &vp);
  52398         }
  52399 #endif
  52400 #if defined(BCM_KATANA2_SUPPORT)
  52401         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){
  52402             return bcm_esw_port_local_get(unit, port, &vp);
  52403         }
  52404 #endif
  52405 #if defined(INCLUDE_L3)
  52406         if (BCM_FAILURE(_bcm_tr2_subport_gport_used(unit, port))) {
  52407             return BCM_E_PARAM;
  52408         }
  52409     } else if (BCM_GPORT_IS_MIM_PORT(port)) {
  52410         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  52411         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  52412             return BCM_E_PARAM;
  52413         }
  52414     } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  52415         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  52416         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  52417             return BCM_E_PARAM;
  52418         }
  52419 #endif
  52420     } else {
  52421         BCM_IF_ERROR_RETURN(
  52422             bcm_esw_port_local_get(unit, port, &vp));
  52423     }
  52424 
  52425     return BCM_E_NONE;
  52426 }
  52427 STATIC int
  52428 _bcm_esw_port_stat_param_valid(int unit, bcm_gport_t port)
  52429 {
  52430     PORT_INIT(unit);
  52431 
  52432     if (!soc_feature(unit, soc_feature_gport_service_counters)) {
  52433            return BCM_E_UNAVAIL;
  52434     }
  52435     return _bcm_esw_port_stat_param_verify(unit, port);
  52436 }
  52437 
  52438 STATIC _bcm_flex_stat_t
  52439 _bcm_esw_port_stat_to_flex_stat(bcm_port_stat_t stat)
  52440 {
  52441     _bcm_flex_stat_t flex_stat;
  52442 
  52443     switch (stat) {
  52444     case bcmPortStatIngressPackets:
  52445         flex_stat = _bcmFlexStatIngressPackets;
  52446         break;
  52447     case bcmPortStatIngressBytes:
  52448         flex_stat = _bcmFlexStatIngressBytes;
  52449         break;
  52450     case bcmPortStatEgressPackets:
  52451         flex_stat = _bcmFlexStatEgressPackets;
  52452         break;
  52453     case bcmPortStatEgressBytes:
  52454         flex_stat = _bcmFlexStatEgressBytes;
  52455         break;
  52456     default:
  52457         flex_stat = _bcmFlexStatNum;
  52458     }
  52459 
  52460     return flex_stat;
  52461 }
  52462 
  52463 /* Requires "idx" variable */
  52464 #define BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr) \
  52465     for (idx = 0; idx < nstat; idx++) { \
  52466         if (NULL == value_arr + idx) { \
  52467             return (BCM_E_PARAM); \
  52468         } \
  52469     }
  52470 
  52471 STATIC int
  52472 _bcm_port_stat_array_convert(int unit, int nstat, bcm_port_stat_t *stat_arr,
  52473                              _bcm_flex_stat_t *fs_arr)
  52474 {
  52475     int idx;
  52476 
  52477     if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) {
  52478         return BCM_E_PARAM;
  52479     }
  52480     if ((NULL == stat_arr) || (NULL == fs_arr)) {
  52481          return (BCM_E_PARAM);
  52482     }
  52483 
  52484     for (idx = 0; idx < nstat; idx++) {
  52485         fs_arr[idx] = _bcm_esw_port_stat_to_flex_stat(stat_arr[idx]);
  52486     }
  52487     return BCM_E_NONE;
  52488 }
  52489 #endif /* BCM_TRIUMPH2_SUPPORT */
  52490 
  52491 /*
  52492  * Function:
  52493  *      bcm_esw_port_stat_enable_set
  52494  * Purpose:
  52495  *      Enable/disable packet and byte counters for the selected
  52496  *      gport.
  52497  * Parameters:
  52498  *      unit - (IN) Unit number.
  52499  *      port - (IN) GPORT ID
  52500  *      enable - (IN) Non-zero to enable counter collection, zero to disable.
  52501  * Returns:
  52502  *      BCM_E_XXX
  52503  * Notes:
  52504  */
  52505 int
  52506 bcm_esw_port_stat_enable_set(int unit, bcm_gport_t port, int enable)
  52507 {
  52508 #if defined(BCM_TRIUMPH2_SUPPORT)
  52509 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52510   uint32                     num_of_tables=0;
  52511   uint32                     num_stat_counter_ids=0;
  52512   bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  52513   bcm_stat_object_t          object=bcmStatObjectIngPort;
  52514   uint32                     stat_counter_id[
  52515                                      BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0};
  52516   uint32                     num_entries=0;
  52517   int                        index=0;
  52518   int                        rv;
  52519 
  52520 #endif
  52521 
  52522   /* Make sure port module is initialized. */
  52523   PORT_INIT(unit);
  52524 
  52525   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52526     BCM_IF_ERROR_RETURN
  52527         (_bcm_esw_port_stat_param_valid(unit, port));
  52528     return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport,
  52529                              _bcm_esw_port_flex_stat_hw_index_set,
  52530                                          NULL, port, enable,0);
  52531   }
  52532 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52533   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  52534                         unit,port,&num_of_tables,&table_info[0]));
  52535     if (enable) {
  52536         rv = _bcm_esw_stat_flex_get_counter_id(unit, num_of_tables,
  52537                  &table_info[0], &num_stat_counter_ids, &stat_counter_id[0]);
  52538         if (BCM_SUCCESS(rv)) {
  52539             return BCM_E_EXISTS;
  52540         } else if (rv != BCM_E_NOT_FOUND) {
  52541             return rv;
  52542         }
  52543 
  52544        for(index=0;index < num_of_tables ;index++) {
  52545 	   if(table_info[index].direction == bcmStatFlexDirectionIngress) {
  52546               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object(
  52547                                   unit,table_info[index].table,
  52548                                   table_info[index].index,NULL,&object));
  52549            } else {
  52550               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object(
  52551                                   unit,table_info[index].table,
  52552                                   table_info[index].index,NULL,&object));
  52553            }
  52554            BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create(
  52555                                unit,object,bcmStatGroupModeSingle,
  52556                                &stat_counter_id[table_info[index].direction],
  52557                                &num_entries));
  52558            BCM_IF_ERROR_RETURN(bcm_esw_port_stat_attach(
  52559                                unit,port,
  52560                                stat_counter_id[table_info[index].direction]));
  52561        }
  52562        return BCM_E_NONE;
  52563   } else {
  52564       BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id(
  52565                            unit, num_of_tables,&table_info[0],
  52566                            &num_stat_counter_ids,&stat_counter_id[0]));
  52567       if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) &&
  52568           (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) {
  52569           return BCM_E_PARAM;
  52570       }
  52571       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_detach(unit,port));
  52572       if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) {
  52573           BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  52574                                 unit,
  52575                                 stat_counter_id[bcmStatFlexDirectionIngress]));
  52576       }
  52577       if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) {
  52578           BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  52579                                 unit,
  52580                                 stat_counter_id[bcmStatFlexDirectionEgress]));
  52581       }
  52582       return BCM_E_NONE;
  52583     }
  52584 #else
  52585     return BCM_E_UNAVAIL;
  52586 #endif
  52587 #else
  52588     return BCM_E_UNAVAIL;
  52589 #endif
  52590 }
  52591 
  52592 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52593 /*
  52594  * Function:
  52595  *      _bcm_esw_port_stat_get_table_info
  52596  * Description:
  52597  *      Provides relevant flex table information(table-name,index with
  52598  *      direction)  for given gport.
  52599  *
  52600  * Parameters:
  52601  *      unit             - (IN) unit number
  52602  *      port             - (IN) GPORT ID
  52603  *      num_of_tables    - (OUT) Number of flex counter tables
  52604  *      table_info       - (OUT) Flex counter tables information
  52605  *
  52606  * Return Value:
  52607  *      BCM_E_XXX
  52608  * Notes:
  52609  */
  52610 STATIC
  52611 bcm_error_t _bcm_esw_port_stat_get_table_info(
  52612                    int                        unit,
  52613                    bcm_gport_t                port,
  52614                    uint32                     *num_of_tables,
  52615                    bcm_stat_flex_table_info_t *table_info)
  52616 {
  52617 #if defined(INCLUDE_L3)
  52618 	int         vp=0;
  52619 	int         rv=0;
  52620 	int         nh_index=0;
  52621         int         vp_base=0;
  52622         int         vt_index =-1;
  52623 	bcm_vlan_t  ovid = 0;
  52624 	uint32      port_class = 0;
  52625 	bcm_port_t  egress_port = 0;
  52626 	ing_l3_next_hop_entry_t ing_nh={{0}};
  52627 	egr_vlan_xlate_entry_t 	egr_vent={{0}};
  52628 	ing_dvp_table_entry_t   dvp={{0}};
  52629 	egr_l3_next_hop_entry_t egr_nh={{0}};
  52630     source_vp_entry_t       svp;
  52631     int                     l3_idx=0;
  52632     egr_l3_intf_entry_t     l3_intf;
  52633 
  52634 #endif
  52635 	bcm_port_t  loc_port=0;
  52636 
  52637         (*num_of_tables) = 0;
  52638 
  52639 	if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52640 		return BCM_E_UNAVAIL;
  52641 	}
  52642     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_param_verify(unit, port));
  52643 	if (BCM_GPORT_IS_MPLS_PORT(port) ||
  52644 	    BCM_GPORT_IS_NIV_PORT(port)) {
  52645 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  52646 	if (BCM_GPORT_IS_MPLS_PORT(port)) {
  52647 		vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  52648 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  52649 			return BCM_E_NOT_FOUND;
  52650 		}
  52651     }
  52652     if (BCM_GPORT_IS_NIV_PORT(port)) {
  52653         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  52654 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
  52655 		    return BCM_E_NOT_FOUND;
  52656 		}
  52657 	}
  52658 
  52659     /* Ingress Side */
  52660     table_info[*num_of_tables].table=SOURCE_VPm;
  52661     table_info[*num_of_tables].index=vp;
  52662     table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  52663     (*num_of_tables)++;
  52664 	/* Egress Side */
  52665 	if (BCM_SUCCESS(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp))) {
  52666 	    nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp,
  52667                                            NEXT_HOP_INDEXf);
  52668 			if (BCM_SUCCESS(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY,
  52669                                          nh_index,&egr_nh))) {
  52670                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  52671                                     table_info[*num_of_tables].index=nh_index;
  52672             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  52673             (*num_of_tables)++;
  52674 				}
  52675 			}
  52676                 return BCM_E_NONE;
  52677 #endif/* BCM_MPLS_SUPPORT  && INCLUDE_L3*/
  52678 	} else if (BCM_GPORT_IS_SUBPORT_GROUP(port) ||
  52679                BCM_GPORT_IS_SUBPORT_PORT(port)) {
  52680 
  52681 
  52682 #if defined(BCM_HGPROXY_COE_SUPPORT)
  52683         if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  52684              soc_feature(unit, soc_feature_channelized_switching)) &&
  52685             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  52686 
  52687 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT)
  52688             if (soc_feature(unit, soc_feature_channelized_switching)) {
  52689                 int subport_num=0;
  52690                 BCM_IF_ERROR_RETURN(
  52691                     _bcm_coe_subtag_subport_port_subport_num_get(unit,
  52692                         port, NULL, &subport_num));
  52693 
  52694                 table_info[*num_of_tables].table = LPORT_TABm;
  52695                 table_info[*num_of_tables].index = subport_num;
  52696                 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  52697                 (*num_of_tables)++;
  52698                 table_info[*num_of_tables].table = EGR_LPORT_PROFILEm;
  52699                 table_info[*num_of_tables].index = subport_num;
  52700                 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  52701                 (*num_of_tables)++;
  52702                 return BCM_E_NONE;
  52703             }
  52704 #endif
  52705 
  52706             if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  52707                 return BCM_E_NOT_FOUND;  /* Local port disabled */
  52708             }
  52709             table_info[*num_of_tables].table = PORT_TABm;
  52710             table_info[*num_of_tables].index =loc_port;
  52711             table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  52712             (*num_of_tables)++;
  52713             table_info[*num_of_tables].table = EGR_PORTm;
  52714             table_info[*num_of_tables].index = loc_port;
  52715             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  52716             (*num_of_tables)++;
  52717             return BCM_E_NONE;
  52718         }
  52719 #endif
  52720 #if defined(BCM_KATANA2_SUPPORT)
  52721         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){
  52722             if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  52723                 return BCM_E_NOT_FOUND;  /* Local port disabled */
  52724             }
  52725             table_info[*num_of_tables].table = PORT_TABm;
  52726             table_info[*num_of_tables].index =loc_port;
  52727             table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  52728             (*num_of_tables)++;
  52729             table_info[*num_of_tables].table = EGR_PORTm;
  52730             table_info[*num_of_tables].index = loc_port;
  52731             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  52732             (*num_of_tables)++;
  52733             return BCM_E_NONE;
  52734         }
  52735 #endif /* BCM_KATANA2_SUPPORT */
  52736 #if defined(INCLUDE_L3)
  52737 		if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  52738                    l3_idx = BCM_GPORT_SUBPORT_PORT_GET(port) & 0xfff;
  52739                    BCM_IF_ERROR_RETURN(soc_mem_read(
  52740                                        unit, EGR_L3_INTFm, MEM_BLOCK_ALL,
  52741                                        l3_idx, &l3_intf));
  52742                    vp = soc_mem_field32_get(unit,EGR_L3_INTFm, &l3_intf, IVIDf);
  52743                    BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(
  52744                                        unit,MEM_BLOCK_ALL,vp,&svp));
  52745                    vp_base = soc_SOURCE_VPm_field32_get(unit, &svp, DVPf);
  52746                    /* vp = BCM_GPORT_SUBPORT_PORT_GET(port); */
  52747 			/* Get the base group VP */
  52748                    /* vp_base = vp & ~(0x7); */
  52749 			/* Get the group's next-hop index */
  52750                    BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  52751                                        unit, MEM_BLOCK_ALL, vp_base, &dvp));
  52752                    nh_index = soc_ING_DVP_TABLEm_field32_get(
  52753                                        unit, &dvp, NEXT_HOP_INDEXf);
  52754                    /*Get the group's OVID from the group's egress NextHopEntry*/
  52755                    BCM_IF_ERROR_RETURN(soc_mem_read(
  52756                                        unit, EGR_L3_NEXT_HOPm,
  52757                                              MEM_BLOCK_ALL, nh_index, &egr_nh));
  52758                    ovid = soc_mem_field32_get(
  52759                                   unit, EGR_L3_NEXT_HOPm, &egr_nh, OVIDf);
  52760 			/* Get the egress port class */
  52761                    BCM_IF_ERROR_RETURN (soc_mem_read(
  52762                                         unit, ING_L3_NEXT_HOPm,
  52763                                               MEM_BLOCK_ANY,nh_index, &ing_nh));
  52764 			if (!soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) {
  52765 			egress_port = soc_ING_L3_NEXT_HOPm_field32_get(
  52766                                           unit, &ing_nh, PORT_NUMf);
  52767 				BCM_IF_ERROR_RETURN(bcm_esw_port_class_get(
  52768                                     unit, egress_port,
  52769                                     bcmPortClassVlanTranslateEgress,
  52770                                     &port_class));
  52771 			}
  52772 			sal_memset(&egr_vent, 0, sizeof(egr_vent));
  52773 			soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, VALIDf, 1);
  52774                    soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, OVIDf,ovid);
  52775 			if (soc_feature(unit, soc_feature_subport_enhanced)) {
  52776                        soc_EGR_VLAN_XLATEm_field32_set(unit,&egr_vent,IVIDf,vp);
  52777     			}
  52778                    soc_EGR_VLAN_XLATEm_field32_set(
  52779                                        unit,&egr_vent,ENTRY_TYPEf, 0x01);
  52780 		   soc_EGR_VLAN_XLATEm_field32_set(
  52781                                       unit,&egr_vent,PORT_GROUP_IDf,port_class);
  52782 			MEM_LOCK(unit, EGR_VLAN_XLATEm);
  52783 		   rv = soc_mem_search(unit,EGR_VLAN_XLATEm,MEM_BLOCK_ALL,
  52784                                        &vt_index, &egr_vent, &egr_vent, 0);
  52785 			if (rv < 0) {
  52786 				MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  52787 				return rv;
  52788 			}
  52789 			rv = soc_mem_write(unit, EGR_VLAN_XLATEm,
  52790                                            MEM_BLOCK_ALL, vt_index,&egr_vent);
  52791 			if (BCM_FAILURE(rv)) {
  52792                             MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  52793                             return rv;
  52794 			}
  52795                         table_info[*num_of_tables].table= EGR_VLAN_XLATEm;
  52796                         table_info[*num_of_tables].index=vt_index;
  52797                         table_info[*num_of_tables].direction=
  52798                                                   bcmStatFlexDirectionEgress;
  52799                         (*num_of_tables)++;
  52800                         MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  52801                         return BCM_E_NONE;
  52802 		} else { /*BCM_GPORT_IS_SUBPORT_GROUP(port) */
  52803 #if defined(BCM_TRIUMPH2_SUPPORT)
  52804 			vp_base = BCM_GPORT_SUBPORT_GROUP_GET(port);
  52805 			BCM_IF_ERROR_RETURN(_bcm_tr2_subport_gport_used(unit,port));
  52806                         table_info[*num_of_tables].table= SOURCE_VPm;
  52807                         table_info[*num_of_tables].index=vp_base;
  52808                         table_info[*num_of_tables].direction=
  52809                                                   bcmStatFlexDirectionIngress;
  52810                         (*num_of_tables)++;
  52811                         return BCM_E_NONE;
  52812 #endif
  52813 		}
  52814 	} else if (BCM_GPORT_IS_MIM_PORT(port)) {
  52815 		vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  52816 		/*MIM_LOCK(unit); */
  52817 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  52818         		/*MIM_UNLOCK(unit); */
  52819         		return BCM_E_NOT_FOUND;
  52820     		}
  52821 		/* Ingress side */
  52822                 table_info[*num_of_tables].table= SOURCE_VPm;
  52823                 table_info[*num_of_tables].index=vp;
  52824                 table_info[*num_of_tables].direction=
  52825                                            bcmStatFlexDirectionIngress;
  52826                 (*num_of_tables)++;
  52827 		/* Egress side */
  52828                if (BCM_SUCCESS(READ_ING_DVP_TABLEm(
  52829                                     unit, MEM_BLOCK_ANY, vp, &dvp))) {
  52830 			nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp,
  52831                                            NEXT_HOP_INDEXf);
  52832                    if (BCM_SUCCESS(soc_mem_read(
  52833                                        unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY,
  52834                                          nh_index,&egr_nh))) {
  52835                             table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  52836                             table_info[*num_of_tables].index=nh_index;
  52837                             table_info[*num_of_tables].direction=
  52838                                                    bcmStatFlexDirectionEgress;
  52839                             (*num_of_tables)++;
  52840 			}
  52841 		}
  52842                 return BCM_E_NONE;
  52843 	} else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  52844 		vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  52845 		/*WLAN_LOCK(unit); */
  52846 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  52847         		/*WLAN_UNLOCK(unit); */
  52848         		return BCM_E_NOT_FOUND;
  52849     		}
  52850 		/*Ingress Side */
  52851                 table_info[*num_of_tables].table= SOURCE_VPm;
  52852                 table_info[*num_of_tables].index=vp;
  52853                table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  52854                 (*num_of_tables)++;
  52855                BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  52856                                         unit, MEM_BLOCK_ANY, vp, &dvp));
  52857                nh_index = soc_ING_DVP_TABLEm_field32_get(
  52858                                   unit, &dvp, NEXT_HOP_INDEXf);
  52859                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  52860                 table_info[*num_of_tables].index=nh_index;
  52861                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  52862                 (*num_of_tables)++;
  52863                 return BCM_E_NONE;
  52864 	} else if (BCM_GPORT_IS_VLAN_PORT(port)) {
  52865                 vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  52866 
  52867                 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  52868                        return BCM_E_NOT_FOUND;
  52869                 }
  52870 
  52871                 /*Ingress Side */
  52872                 table_info[*num_of_tables].table= SOURCE_VPm;
  52873                 table_info[*num_of_tables].index=vp;
  52874                 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  52875                 (*num_of_tables)++;
  52876                 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  52877                                         unit, MEM_BLOCK_ANY, vp, &dvp));
  52878                 nh_index = soc_ING_DVP_TABLEm_field32_get(
  52879                                   unit, &dvp, NEXT_HOP_INDEXf);
  52880                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  52881                 table_info[*num_of_tables].index=nh_index;
  52882                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  52883                 (*num_of_tables)++;
  52884                 return BCM_E_NONE;
  52885 #endif
  52886         }
  52887 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  52888     else if (BCM_GPORT_IS_TRUNK(port)) {
  52889         if (!soc_feature(unit, soc_feature_vp_lag)) {
  52890             return BCM_E_UNAVAIL;
  52891         }
  52892         BCM_IF_ERROR_RETURN(
  52893             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  52894                                             &vp));
  52895         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  52896             return BCM_E_NOT_FOUND;
  52897         }
  52898         /* Ingress Side */
  52899         table_info[*num_of_tables].table = SOURCE_VPm;
  52900         table_info[*num_of_tables].index = vp;
  52901         table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  52902         (*num_of_tables)++;
  52903         return BCM_E_NONE;
  52904     }
  52905 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3*/
  52906     else {
  52907 		if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  52908 			return BCM_E_NOT_FOUND;  /* Local port disabled */
  52909 		}
  52910 		/*PORT_LOCK(unit); */
  52911 #if defined(BCM_TRIDENT3_SUPPORT)
  52912                 if (SOC_IS_TRIDENT3X(unit)) {
  52913                     table_info[*num_of_tables].table = LPORT_TABm;
  52914                     table_info[*num_of_tables].index = loc_port;
  52915                     table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  52916                     (*num_of_tables)++;
  52917                     if (soc_mem_field_valid(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf) &&
  52918                         soc_mem_is_valid(unit, EGR_LPORT_PROFILEm)) {
  52919                         table_info[*num_of_tables].table = EGR_LPORT_PROFILEm;
  52920                         table_info[*num_of_tables].index = loc_port;
  52921                         table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  52922                         (*num_of_tables)++;
  52923                     } else {
  52924                         return BCM_E_NOT_FOUND;
  52925                     }
  52926                 } else
  52927 #endif
  52928                 {
  52929                     table_info[*num_of_tables].table= PORT_TABm;
  52930                     table_info[*num_of_tables].index=loc_port;
  52931                     table_info[*num_of_tables].direction= bcmStatFlexDirectionIngress;
  52932                     (*num_of_tables)++;
  52933                     table_info[*num_of_tables].table= EGR_PORTm;
  52934                     table_info[*num_of_tables].index=loc_port;
  52935                     table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  52936                     (*num_of_tables)++;
  52937                 }
  52938                 return BCM_E_NONE;
  52939 	}
  52940 	return BCM_E_NOT_FOUND;
  52941 }
  52942 #endif
  52943 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52944 /*
  52945  * Function:
  52946  *      _bcm_esw_port_stat_attach
  52947  * Description:
  52948  *      Attach counter entries to the given GPORT
  52949  *
  52950  * Parameters:
  52951  *      unit             - (IN) unit number
  52952  *      port             - (IN) GPORT ID
  52953  *      stat_counter_id  - (IN) Stat Counter ID.
  52954  *
  52955  * Return Value:
  52956  *      BCM_E_XXX
  52957  * Notes:
  52958  */
  52959 int _bcm_esw_port_stat_attach(
  52960             int	        unit,
  52961             bcm_gport_t	port,
  52962             uint32      stat_counter_id)
  52963 {
  52964     soc_mem_t                 table=0;
  52965     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  52966     uint32                    pool_number=0;
  52967     uint32                    base_index=0;
  52968     bcm_stat_flex_mode_t      offset_mode=0;
  52969     bcm_stat_object_t         object=bcmStatObjectIngPort;
  52970     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  52971     uint32                    count=0;
  52972     uint32                     actual_num_tables=0;
  52973     uint32                     num_of_tables=0;
  52974     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  52975     uint8                     skip_table_check = 0;
  52976 
  52977     _bcm_esw_stat_get_counter_id_info(
  52978                   unit, stat_counter_id,
  52979                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  52980     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  52981     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  52982     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  52983                         unit,object,1,&actual_num_tables,&table,&direction));
  52984 
  52985     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  52986                    unit, port,&num_of_tables,&table_info[0]));
  52987     skip_table_check = soc_property_get(unit, spn_FLEX_STAT_SHARE_ENABLE, 0);
  52988     for (count=0; count < num_of_tables ; count++) {
  52989       if ( (table_info[count].direction == direction) &&
  52990            ((table_info[count].table == table) || (skip_table_check)) ) {
  52991            if(direction == bcmStatFlexDirectionIngress) {
  52992               return _bcm_esw_stat_flex_attach_ingress_table_counters(
  52993                      unit,
  52994                      table_info[count].table,
  52995                      table_info[count].index,
  52996                      offset_mode,
  52997                      base_index,
  52998                      pool_number);
  52999            } else {
  53000               return _bcm_esw_stat_flex_attach_egress_table_counters(
  53001                      unit,
  53002                      table_info[count].table,
  53003                      table_info[count].index,
  53004                      0,
  53005                      offset_mode,
  53006                      base_index,
  53007                      pool_number);
  53008            }
  53009       }
  53010     }
  53011     return BCM_E_NOT_FOUND;
  53012 }
  53013 #endif
  53014 
  53015 /*
  53016  * Function:
  53017  *      bcm_esw_port_stat_attach
  53018  * Description:
  53019  *      Attach counter entries to the given GPORT
  53020  *
  53021  * Parameters:
  53022  *      unit             - (IN) unit number
  53023  *      port             - (IN) GPORT ID
  53024  *      stat_counter_id  - (IN) Stat Counter ID.
  53025  *
  53026  * Return Value:
  53027  *      BCM_E_XXX
  53028  * Notes:
  53029  */
  53030 int bcm_esw_port_stat_attach(
  53031             int         unit,
  53032             bcm_gport_t port,
  53033             uint32      stat_counter_id)
  53034 {
  53035 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53036     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53037         return _bcm_esw_port_stat_attach(unit,port,stat_counter_id);
  53038     } else
  53039 #endif
  53040 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  53041     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  53042         _bcm_flex_stat_type_t fs_type;
  53043         uint32 fs_inx;
  53044         uint32 flag;
  53045         int rv;
  53046 
  53047         fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id);
  53048         fs_inx  = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id);
  53049 
  53050         if (!((fs_type == _bcmFlexStatTypeGport ||
  53051             fs_type == _bcmFlexStatTypeEgressGport) && fs_inx)) {
  53052             return BCM_E_PARAM;
  53053         }
  53054         BCM_IF_ERROR_RETURN
  53055             (_bcm_esw_port_stat_param_valid(unit, port));
  53056 
  53057         flag = fs_type==_bcmFlexStatTypeGport? _BCM_FLEX_STAT_HW_INGRESS:
  53058                          _BCM_FLEX_STAT_HW_EGRESS;
  53059 
  53060         rv = _bcm_esw_flex_stat_enable_set(unit, fs_type,
  53061                              _bcm_esw_port_flex_stat_hw_index_set,
  53062                                       INT_TO_PTR(flag),
  53063                                       port, TRUE,fs_inx);
  53064         return rv;
  53065     } else
  53066 #endif
  53067     {
  53068         return BCM_E_UNAVAIL;
  53069     }
  53070 }
  53071 
  53072 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53073 /*
  53074  * Function:
  53075  *      _bcm_esw_port_stat_detach
  53076  * Description:
  53077  *      Detach counter entries to the given GPORT
  53078  *
  53079  * Parameters:
  53080  *      unit             - (IN) unit number
  53081  *      port             - (IN) GPORT ID
  53082  *
  53083  * Return Value:
  53084  *      BCM_E_XXX
  53085  * Notes:
  53086  */
  53087 int _bcm_esw_port_stat_detach(
  53088             int	        unit,
  53089             bcm_gport_t	port)
  53090 {
  53091     uint32                     count=0;
  53092     uint32                     num_of_tables=0;
  53093     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  53094     bcm_error_t                rv = BCM_E_NONE;
  53095     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  53096 
  53097     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  53098                    unit, port,&num_of_tables,&table_info[0]));
  53099 
  53100     for (count=0; count < num_of_tables ; count++) {
  53101       if (table_info[count].direction == bcmStatFlexDirectionIngress) {
  53102            rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  53103                          unit,
  53104                          table_info[count].table,
  53105                          table_info[count].index);
  53106            if (BCM_E_NONE != rv &&
  53107                 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  53108                 err_code[bcmStatFlexDirectionIngress] = rv;
  53109            }
  53110       } else {
  53111            rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  53112                           unit,
  53113                           0,
  53114                           table_info[count].table,
  53115                           table_info[count].index);
  53116            if (BCM_E_NONE != rv &&
  53117                 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  53118                 err_code[bcmStatFlexDirectionEgress] = rv;
  53119            }
  53120       }
  53121     }
  53122 
  53123     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  53124 }
  53125 
  53126 /*
  53127  * Function:
  53128  *      _bcm_esw_port_stat_detach_with_id
  53129  * Description:
  53130  *      Detach counter entries to the given GPORT with a given stat counter id
  53131  *
  53132  * Parameters:
  53133  *      unit             - (IN) unit number
  53134  *      port             - (IN) GPORT ID
  53135  *      stat_counter_id  - (IN) Stat Counter ID
  53136  *
  53137  * Return Value:
  53138  *      BCM_E_XXX
  53139  * Notes:
  53140  */
  53141 bcm_error_t _bcm_esw_port_stat_detach_with_id(
  53142             int	        unit,
  53143             bcm_gport_t	port,
  53144             uint32 stat_counter_id)
  53145 {
  53146     uint32                     count=0;
  53147     uint32                     num_of_tables=0;
  53148     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  53149     bcm_error_t                rv = BCM_E_NONE;
  53150     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  53151     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  53152     uint32                    pool_number=0;
  53153     uint32                    base_index=0;
  53154     bcm_stat_flex_mode_t      offset_mode=0;
  53155     bcm_stat_object_t         object=bcmStatObjectIngPort;
  53156     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  53157     uint32                     actual_num_tables=0;
  53158     soc_mem_t                 table=0;
  53159 
  53160     _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode, &object,
  53161                                       &offset_mode, &pool_number, &base_index);
  53162     BCM_IF_ERROR_RETURN
  53163         (_bcm_esw_stat_validate_object(unit, object, &direction));
  53164     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode));
  53165     BCM_IF_ERROR_RETURN
  53166         (_bcm_esw_stat_flex_get_table_info(unit, object, 1, &actual_num_tables,
  53167                                            &table, &direction));
  53168 
  53169     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  53170                    unit, port,&num_of_tables,&table_info[0]));
  53171 
  53172     for (count=0; count < num_of_tables ; count++) {
  53173         if((table_info[count].direction == direction) &&
  53174              (table_info[count].table == table)) {
  53175            if(direction == bcmStatFlexDirectionIngress) {
  53176                rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  53177                              unit,
  53178                              table_info[count].table,
  53179                              table_info[count].index);
  53180                if (BCM_E_NONE != rv &&
  53181                     BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  53182                     err_code[bcmStatFlexDirectionIngress] = rv;
  53183                }
  53184             } else {
  53185                rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  53186                               unit,
  53187                               0,
  53188                               table_info[count].table,
  53189                               table_info[count].index);
  53190                if (BCM_E_NONE != rv &&
  53191                     BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  53192                     err_code[bcmStatFlexDirectionEgress] = rv;
  53193                }
  53194             }
  53195         }
  53196     }
  53197 
  53198     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  53199 }
  53200 #endif
  53201 
  53202 /*
  53203  * Function:
  53204  *      bcm_esw_port_stat_detach
  53205  * Description:
  53206  *      Detach counter entries to the given GPORT
  53207  *
  53208  * Parameters:
  53209  *      unit             - (IN) unit number
  53210  *      port             - (IN) GPORT ID
  53211  *
  53212  * Return Value:
  53213  *      BCM_E_XXX
  53214  * Notes:
  53215  */
  53216 int bcm_esw_port_stat_detach(
  53217             int         unit,
  53218             bcm_gport_t port)
  53219 {
  53220 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53221     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53222         return _bcm_esw_port_stat_detach(unit,port);
  53223     } else
  53224 #endif
  53225 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  53226     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  53227         uint32 flag;
  53228         int rv;
  53229         int rv1;
  53230 
  53231         BCM_IF_ERROR_RETURN
  53232             (_bcm_esw_port_stat_param_valid(unit, port));
  53233 
  53234         /* no count_id, detach all counters associated with this port.*/
  53235         flag= _BCM_FLEX_STAT_HW_INGRESS;
  53236         rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport,
  53237                              _bcm_esw_port_flex_stat_hw_index_set,
  53238                                       INT_TO_PTR(flag),
  53239                                       port, FALSE,1);
  53240         flag= _BCM_FLEX_STAT_HW_EGRESS;
  53241         rv1 = _bcm_esw_flex_stat_enable_set(unit,
  53242                          _bcmFlexStatTypeEgressGport,
  53243                          _bcm_esw_port_flex_stat_hw_index_set,
  53244                                   INT_TO_PTR(flag),
  53245                                   port, FALSE,1);
  53246         if (BCM_SUCCESS(rv) && BCM_SUCCESS(rv1)) {
  53247             return BCM_E_NONE;
  53248         } else {
  53249             return BCM_E_NOT_FOUND;
  53250         }
  53251     } else
  53252 #endif
  53253     {
  53254         return BCM_E_UNAVAIL;
  53255     }
  53256 }
  53257 
  53258 /*
  53259  * Function:
  53260  *      bcm_esw_port_stat_detach_with_id
  53261  * Description:
  53262  *      Detach counter entries to the given GPORT with a given stat counter id
  53263  *
  53264  * Parameters:
  53265  *      unit             - (IN) unit number
  53266  *      port             - (IN) GPORT ID
  53267  *      stat_counter_id  - (IN) Stat Counter ID
  53268  *
  53269  * Return Value:
  53270  *      BCM_E_XXX
  53271  * Notes:
  53272  */
  53273 bcm_error_t bcm_esw_port_stat_detach_with_id(
  53274             int         unit,
  53275             bcm_gport_t port,
  53276             uint32 stat_counter_id)
  53277 {
  53278 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53279     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53280         return _bcm_esw_port_stat_detach_with_id(unit, port, stat_counter_id);
  53281     } else
  53282 #endif
  53283     {
  53284         return BCM_E_UNAVAIL;
  53285     }
  53286 }
  53287 
  53288 
  53289 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53290 /*
  53291  * Function:
  53292  *      _bcm_esw_port_stat_counter_get
  53293  * Description:
  53294  *      retrieve set of counter statistic values for the given GPORT
  53295  *      if sync_mode is set, sync the sw accumulated count
  53296  *      with hw count value first, else return sw count.
  53297  *
  53298  * Parameters:
  53299  *      unit             - (IN) unit number
  53300  *      port             - (IN) GPORT ID
  53301  *      stat             - (IN) Type of the counter to retrieve
  53302  *                              I.e. ingress/egress byte/packet)
  53303  *      num_entries      - (IN) Number of counter Entries
  53304  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53305  *      counter_values   - (OUT) Pointer to counter values
  53306  *
  53307  * Return Value:
  53308  *      BCM_E_XXX
  53309  * Notes:
  53310  */
  53311 int _bcm_esw_port_stat_counter_get(
  53312             int	             unit,
  53313             int	             sync_mode,
  53314             bcm_gport_t      port,
  53315             bcm_port_stat_t  stat,
  53316             uint32           num_entries,
  53317             uint32           *counter_indexes,
  53318             bcm_stat_value_t *counter_values)
  53319 {
  53320     uint32                          table_count=0;
  53321     uint32                          index_count=0;
  53322     uint32                          num_of_tables=0;
  53323     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  53324     uint32                          byte_flag=0;
  53325     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  53326 
  53327     if ((stat == bcmPortStatIngressPackets) ||
  53328         (stat == bcmPortStatIngressBytes)) {
  53329          direction = bcmStatFlexDirectionIngress;
  53330     } else {
  53331          direction = bcmStatFlexDirectionEgress;
  53332     }
  53333     if ((stat == bcmPortStatIngressPackets) ||
  53334         (stat == bcmPortStatEgressPackets)) {
  53335         byte_flag=0;
  53336     } else {
  53337         byte_flag=1;
  53338     }
  53339 
  53340     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  53341                    unit, port,&num_of_tables,&table_info[0]));
  53342 
  53343     for (table_count=0; table_count < num_of_tables ; table_count++) {
  53344       if (table_info[table_count].direction == direction) {
  53345           for (index_count=0; index_count < num_entries ; index_count++) {
  53346                /*ctr_offset_info.offset_index = counter_indexes[index_count];*/
  53347             BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get(
  53348                          unit, sync_mode,
  53349                          table_info[table_count].index,
  53350                          table_info[table_count].table,
  53351                          0,
  53352                          byte_flag,
  53353                          counter_indexes[index_count],
  53354                          &counter_values[index_count]));
  53355           }
  53356       }
  53357     }
  53358     return BCM_E_NONE;
  53359 }
  53360 #endif
  53361 
  53362 /*
  53363  * Function:
  53364  *      _bcm_esw_port_flex_stat_counter_get
  53365  * Description:
  53366  *      retrieve set of counter statistic values for the given GPORT
  53367  *      if sync_mode is set, sync the sw accumulated count
  53368  *      with hw count value first, else return sw count.
  53369  * Parameters:
  53370  *      unit             - (IN) unit number
  53371  *      sync_mode        - (IN) hwcount is to be synced to sw count
  53372  *      port             - (IN) GPORT ID
  53373  *      stat             - (IN) Type of the counter to retrieve
  53374  *                              I.e. ingress/egress byte/packet)
  53375  *      num_entries      - (IN) Number of counter Entries
  53376  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53377  *      counter_values   - (OUT) Pointer to counter values
  53378  *
  53379  * Return Value:
  53380  *      BCM_E_XXX
  53381  * Notes:
  53382  */
  53383 int _bcm_esw_port_flex_stat_counter_get(int              unit,
  53384                                         int              sync_mode,
  53385                                         bcm_gport_t      port,
  53386                                         bcm_port_stat_t  stat,
  53387                                         uint32           num_entries,
  53388                                         uint32           *counter_indexes,
  53389                                         bcm_stat_value_t *counter_values)
  53390 {
  53391 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53392     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53393         return _bcm_esw_port_stat_counter_get(unit, sync_mode, port, stat,
  53394                                               num_entries, counter_indexes,
  53395                                               counter_values);
  53396     } else
  53397 #endif
  53398 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  53399     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  53400         uint64 val;
  53401         int rv = BCM_E_NONE;
  53402 
  53403         rv =  _bcm_esw_flex_stat_get(unit, sync_mode,
  53404                ((stat == bcmPortStatIngressPackets) ||
  53405                 (stat == bcmPortStatIngressBytes)) ?
  53406                  _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport,
  53407                 port,
  53408                 _bcm_esw_port_stat_to_flex_stat(stat), &val);
  53409 
  53410         if ((stat == bcmPortStatIngressPackets) ||
  53411             (stat == bcmPortStatEgressPackets)) {
  53412             counter_values->packets = COMPILER_64_LO(val);
  53413         } else {
  53414             COMPILER_64_SET(counter_values->bytes,
  53415                       COMPILER_64_HI(val),
  53416                       COMPILER_64_LO(val));
  53417         }
  53418         return rv;
  53419 
  53420     } else
  53421 #endif
  53422     {
  53423         return BCM_E_UNAVAIL;
  53424     }
  53425 
  53426 }
  53427 
  53428 
  53429 /*
  53430  * Function:
  53431  *      bcm_esw_port_stat_counter_get
  53432  * Description:
  53433  *      retrieve set of counter statistic values for the given GPORT
  53434  * Parameters:
  53435  *      unit             - (IN) unit number
  53436  *      port             - (IN) GPORT ID
  53437  *      stat             - (IN) Type of the counter to retrieve
  53438  *                              I.e. ingress/egress byte/packet)
  53439  *      num_entries      - (IN) Number of counter Entries
  53440  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53441  *      counter_values   - (OUT) Pointer to counter values
  53442  *
  53443  * Return Value:
  53444  *      BCM_E_XXX
  53445  * Notes:
  53446  */
  53447 
  53448 int bcm_esw_port_stat_counter_get(int              unit,
  53449                                   bcm_gport_t      port,
  53450                                   bcm_port_stat_t  stat,
  53451                                   uint32           num_entries,
  53452                                   uint32           *counter_indexes,
  53453                                   bcm_stat_value_t *counter_values)
  53454 {
  53455     int rv = BCM_E_UNAVAIL;
  53456 
  53457     rv = _bcm_esw_port_flex_stat_counter_get(unit, 0, port, stat, num_entries,
  53458                                              counter_indexes, counter_values);
  53459 
  53460     return rv;
  53461 }
  53462 
  53463 
  53464 /*
  53465  * Function:
  53466  *      bcm_esw_port_stat_counter_sync_get
  53467  * Description:
  53468  *      retrieve set of counter statistic values for the given GPORT
  53469  *      sw accumulated counters synced with hw count.
  53470  * Parameters:
  53471  *      unit             - (IN) unit number
  53472  *      port             - (IN) GPORT ID
  53473  *      stat             - (IN) Type of the counter to retrieve
  53474  *                              I.e. ingress/egress byte/packet)
  53475  *      num_entries      - (IN) Number of counter Entries
  53476  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53477  *      counter_values   - (OUT) Pointer to counter values
  53478  *
  53479  * Return Value:
  53480  *      BCM_E_XXX
  53481  * Notes:
  53482  */
  53483 
  53484 int bcm_esw_port_stat_counter_sync_get(int              unit,
  53485                                        bcm_gport_t      port,
  53486                                        bcm_port_stat_t  stat,
  53487                                        uint32           num_entries,
  53488                                        uint32           *counter_indexes,
  53489                                        bcm_stat_value_t *counter_values)
  53490 {
  53491     int rv = BCM_E_UNAVAIL;
  53492 
  53493     rv = _bcm_esw_port_flex_stat_counter_get(unit, 1, port, stat, num_entries,
  53494                                         counter_indexes, counter_values);
  53495 
  53496     return rv;
  53497 }
  53498 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53499 /*
  53500  * Function:
  53501  *      _bcm_esw_port_stat_counter_set
  53502  * Description:
  53503  *      set counter statistic values for the given GPORT
  53504  *
  53505  * Parameters:
  53506  *      unit             - (IN) unit number
  53507  *      port             - (IN) GPORT ID
  53508  *      stat             - (IN) Type of the counter to retrieve
  53509  *                              I.e. ingress/egress byte/packet)
  53510  *      num_entries      - (IN) Number of counter Entries
  53511  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53512  *      counter_values   - (IN) Pointer to counter values
  53513  *
  53514  * Return Value:
  53515  *      BCM_E_XXX
  53516  * Notes:
  53517  */
  53518 int _bcm_esw_port_stat_counter_set(
  53519             int	             unit,
  53520             bcm_gport_t      port,
  53521             bcm_port_stat_t  stat,
  53522             uint32           num_entries,
  53523             uint32           *counter_indexes,
  53524             bcm_stat_value_t *counter_values)
  53525 {
  53526     uint32                          table_count=0;
  53527     uint32                          index_count=0;
  53528     uint32                          num_of_tables=0;
  53529     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  53530     uint32                          byte_flag=0;
  53531     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  53532 
  53533     if ((stat == bcmPortStatIngressPackets) ||
  53534         (stat == bcmPortStatIngressBytes)) {
  53535          direction = bcmStatFlexDirectionIngress;
  53536     } else {
  53537          direction = bcmStatFlexDirectionEgress;
  53538     }
  53539     if ((stat == bcmPortStatIngressPackets) ||
  53540         (stat == bcmPortStatEgressPackets)) {
  53541         byte_flag=0;
  53542     } else {
  53543         byte_flag=1;
  53544     }
  53545 
  53546     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  53547                    unit, port,&num_of_tables,&table_info[0]));
  53548 
  53549     for (table_count=0; table_count < num_of_tables ; table_count++) {
  53550       if (table_info[table_count].direction == direction) {
  53551           for (index_count=0; index_count < num_entries ; index_count++) {
  53552             BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set(
  53553                                 unit,
  53554                                 table_info[table_count].index,
  53555                                 table_info[table_count].table,
  53556                                 0,
  53557                                 byte_flag,
  53558                                 counter_indexes[index_count],
  53559                                 &counter_values[index_count]));
  53560           }
  53561       }
  53562     }
  53563     return BCM_E_NONE;
  53564 }
  53565 #endif
  53566 /*
  53567  * Function:
  53568  *      bcm_esw_port_stat_counter_set
  53569  * Description:
  53570  *      set counter statistic values for the given GPORT
  53571  *
  53572  * Parameters:
  53573  *      unit             - (IN) unit number
  53574  *      port             - (IN) GPORT ID
  53575  *      stat             - (IN) Type of the counter to retrieve
  53576  *                              I.e. ingress/egress byte/packet)
  53577  *      num_entries      - (IN) Number of counter Entries
  53578  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  53579  *      counter_values   - (IN) Pointer to counter values
  53580  *
  53581  * Return Value:
  53582  *      BCM_E_XXX
  53583  * Notes:
  53584  */
  53585 int bcm_esw_port_stat_counter_set(
  53586             int              unit,
  53587             bcm_gport_t      port,
  53588             bcm_port_stat_t  stat,
  53589             uint32           num_entries,
  53590             uint32           *counter_indexes,
  53591             bcm_stat_value_t *counter_values)
  53592 {
  53593     /* Make sure port module is initialized. */
  53594     PORT_INIT(unit);
  53595 
  53596 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53597     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53598         return _bcm_esw_port_stat_counter_set(unit,port,stat,
  53599                       num_entries,counter_indexes,counter_values);
  53600     } else
  53601 #endif
  53602 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  53603     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  53604         uint64 val;
  53605         int rv = BCM_E_NONE;
  53606 
  53607         if ((stat == bcmPortStatIngressPackets) ||
  53608             (stat == bcmPortStatEgressPackets)) {
  53609             COMPILER_64_SET(val,0,counter_values->packets);
  53610         } else {
  53611             COMPILER_64_SET(val,
  53612                       COMPILER_64_HI(counter_values->bytes),
  53613                       COMPILER_64_LO(counter_values->bytes));
  53614         }
  53615         rv =  _bcm_esw_flex_stat_set(unit,
  53616                ((stat == bcmPortStatIngressPackets) ||
  53617                 (stat == bcmPortStatIngressBytes)) ?
  53618                  _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport,
  53619                 port,
  53620                 _bcm_esw_port_stat_to_flex_stat(stat), val);
  53621 
  53622         return rv;
  53623 
  53624     } else
  53625 #endif
  53626     {
  53627         return BCM_E_UNAVAIL;
  53628     }
  53629 }
  53630 /*
  53631  * Function:
  53632  *      bcm_esw_port_stat_id_get
  53633  * Description:
  53634  *      Get stat counter id associated with given gport
  53635  *
  53636  * Parameters:
  53637  *      unit             - (IN) unit number
  53638  *      port             - (IN) GPORT ID
  53639  *      stat             - (IN) Type of the counter to retrieve
  53640  *                              I.e. ingress/egress byte/packet)
  53641  *      Stat_counter_id  - (OUT) Stat Counter ID
  53642  * Return Value:
  53643  *      BCM_E_XXX
  53644  * Notes:
  53645  */
  53646 int bcm_esw_port_stat_id_get(
  53647             int              unit,
  53648             bcm_gport_t      port,
  53649             bcm_port_stat_t  stat,
  53650             uint32           *stat_counter_id)
  53651 {
  53652 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53653     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  53654     uint32                     num_of_tables=0;
  53655     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  53656     uint32                     index=0;
  53657     uint32                     num_stat_counter_ids=0;
  53658 
  53659     /* Make sure port module is initialized. */
  53660     PORT_INIT(unit);
  53661 
  53662     if ((stat == bcmPortStatIngressPackets) ||
  53663         (stat == bcmPortStatIngressBytes)) {
  53664          direction = bcmStatFlexDirectionIngress;
  53665     } else {
  53666          direction = bcmStatFlexDirectionEgress;
  53667     }
  53668     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  53669                         unit,port,&num_of_tables,&table_info[0]));
  53670     for (index=0; index < num_of_tables ; index++) {
  53671          if (table_info[index].direction == direction)
  53672              return _bcm_esw_stat_flex_get_counter_id(
  53673                                   unit, 1, &table_info[index],
  53674                                   &num_stat_counter_ids,stat_counter_id);
  53675     }
  53676     return BCM_E_NOT_FOUND;
  53677 #else
  53678     return BCM_E_UNAVAIL;
  53679 #endif
  53680 }
  53681 
  53682 
  53683 /*
  53684  * Function:
  53685  *      _bcm_esw_port_stat_get
  53686  * Purpose:
  53687  *      Get 64-bit counter value for specified port statistic type.
  53688  *      if sync_mode is set, sync the sw accumulated count
  53689  *      with hw count value first, else return sw count.
  53690  * Parameters:
  53691  *      unit        - (IN) Unit number.
  53692  *      sync_mode   - (IN) hwcount is to be synced to sw count
  53693  *      port        - (IN) GPORT ID
  53694  *      stat        - (IN) Type of the counter to retrieve.
  53695  *      val         - (OUT) Pointer to a counter value.
  53696  * Returns:
  53697  *      BCM_E_XXX
  53698  * Notes:
  53699  */
  53700 int
  53701 _bcm_esw_port_stat_get(int unit, int sync_mode, bcm_gport_t port,
  53702                        bcm_port_stat_t stat, uint64 *val)
  53703 {
  53704 #if defined(BCM_TRIUMPH2_SUPPORT)
  53705 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53706   uint32           counter_indexes=0;
  53707   bcm_stat_value_t counter_values={0};
  53708 #endif
  53709 
  53710   /* Make sure port module is initialized. */
  53711   PORT_INIT(unit);
  53712 
  53713 #if defined(BCM_PREEMPTION_SUPPORT)
  53714   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  53715     bcm_port_t local_port;
  53716     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  53717     return bcmi_esw_preemption_counter_get(unit, sync_mode, local_port,
  53718                                            stat, val);
  53719   }
  53720 #endif /* BCM_PREEMPTION_SUPPORT */
  53721 
  53722   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53723     BCM_IF_ERROR_RETURN
  53724         (_bcm_esw_port_stat_param_valid(unit, port));
  53725     return _bcm_esw_flex_stat_get(unit, sync_mode, _bcmFlexStatTypeGport, port,
  53726                                   _bcm_esw_port_stat_to_flex_stat(stat), val);
  53727   }
  53728 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53729   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, port,
  53730                                                      stat, 1, &counter_indexes,
  53731                                                      &counter_values));
  53732   if ((stat == bcmPortStatIngressPackets) ||
  53733       (stat == bcmPortStatEgressPackets)) {
  53734       COMPILER_64_SET(*val,
  53735                       COMPILER_64_HI(counter_values.packets64),
  53736                       COMPILER_64_LO(counter_values.packets64));
  53737   } else {
  53738       COMPILER_64_SET(*val,
  53739                       COMPILER_64_HI(counter_values.bytes),
  53740                       COMPILER_64_LO(counter_values.bytes));
  53741   }
  53742   return BCM_E_NONE;
  53743 #else
  53744     return BCM_E_UNAVAIL;
  53745 #endif
  53746 #else
  53747     return BCM_E_UNAVAIL;
  53748 #endif
  53749 }
  53750 
  53751 
  53752 /*
  53753  * Function:
  53754  *      bcm_esw_port_stat_get
  53755  * Purpose:
  53756  *      Get 64-bit counter value for specified port statistic type.
  53757  * Parameters:
  53758  *      unit - (IN) Unit number.
  53759  *      port - (IN) GPORT ID
  53760  *      stat - (IN) Type of the counter to retrieve.
  53761  *      val - (OUT) Pointer to a counter value.
  53762  * Returns:
  53763  *      BCM_E_XXX
  53764  * Notes:
  53765  */
  53766 int
  53767 bcm_esw_port_stat_get(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  53768                       uint64 *val)
  53769 {
  53770     int rv = BCM_E_UNAVAIL;
  53771 
  53772     rv = _bcm_esw_port_stat_get(unit, 0, port, stat, val);
  53773 
  53774     return rv;
  53775 }
  53776 
  53777 
  53778 /*
  53779  * Function:
  53780  *      bcm_esw_port_stat_sync_get
  53781  * Purpose:
  53782  *      Get 64-bit counter value for specified port statistic type.
  53783  *      sw accumulated counters synced with hw count.
  53784  * Parameters:
  53785  *      unit - (IN) Unit number.
  53786  *      port - (IN) GPORT ID
  53787  *      stat - (IN) Type of the counter to retrieve.
  53788  *      val - (OUT) Pointer to a counter value.
  53789  * Returns:
  53790  *      BCM_E_XXX
  53791  * Notes:
  53792  */
  53793 int
  53794 bcm_esw_port_stat_sync_get(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  53795                       uint64 *val)
  53796 {
  53797     int rv = BCM_E_UNAVAIL;
  53798 
  53799     rv = _bcm_esw_port_stat_get(unit, 1, port, stat, val);
  53800 
  53801     return rv;
  53802 }
  53803 
  53804 /*
  53805  * Function:
  53806  *      _bcm_esw_port_stat_get32
  53807  * Purpose:
  53808  *      Get lower 32-bit counter value for specified port statistic
  53809  *      type.
  53810  *      if sync_mode is set, sync the sw accumulated count
  53811  *      with hw count value first, else return sw count.
  53812  * Parameters:
  53813  *      unit        - (IN) Unit number.
  53814  *      sync_mode   - (IN) hwcount is to be synced to sw count
  53815  *      port        - (IN) GPORT ID
  53816  *      stat        - (IN) Type of the counter to retrieve.
  53817  *      val         - (OUT) Pointer to a counter value.
  53818  * Returns:
  53819  *      BCM_E_XXX
  53820  * Notes:
  53821  */
  53822 int
  53823 _bcm_esw_port_stat_get32(int unit, int sync_mode, bcm_gport_t port,
  53824                          bcm_port_stat_t stat, uint32 *val)
  53825 {
  53826 #if defined(BCM_TRIUMPH2_SUPPORT)
  53827 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53828   uint32           counter_indexes=0;
  53829   bcm_stat_value_t counter_values={0};
  53830 #endif
  53831 
  53832   /* Make sure port module is initialized. */
  53833   PORT_INIT(unit);
  53834 
  53835 #if defined(BCM_PREEMPTION_SUPPORT)
  53836   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  53837     bcm_port_t local_port;
  53838     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  53839     return bcmi_esw_preemption_counter_get32(unit, sync_mode, local_port,
  53840                                              stat, val);
  53841   }
  53842 #endif /* BCM_PREEMPTION_SUPPORT */
  53843 
  53844   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53845     BCM_IF_ERROR_RETURN
  53846         (_bcm_esw_port_stat_param_valid(unit, port));
  53847     return _bcm_esw_flex_stat_get32(unit, sync_mode,
  53848                                     _bcmFlexStatTypeGport, port,
  53849                                     _bcm_esw_port_stat_to_flex_stat(stat), val);
  53850   }
  53851 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53852   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode,
  53853                                                      port, stat, 1,
  53854                                                      &counter_indexes,
  53855                                                      &counter_values));
  53856   if ((stat == bcmPortStatIngressPackets) ||
  53857       (stat == bcmPortStatEgressPackets)) {
  53858       *val = counter_values.packets;
  53859   } else {
  53860       /* Ignoring Hi bytes value */
  53861       *val = COMPILER_64_LO(counter_values.bytes);
  53862   }
  53863   return BCM_E_NONE;
  53864 #else
  53865     return BCM_E_UNAVAIL;
  53866 #endif
  53867 #else
  53868     return BCM_E_UNAVAIL;
  53869 #endif
  53870 }
  53871 
  53872 
  53873 /*
  53874  * Function:
  53875  *      bcm_esw_port_stat_get32
  53876  * Purpose:
  53877  *      Get lower 32-bit counter value for specified port statistic
  53878  *      type.
  53879  * Parameters:
  53880  *      unit - (IN) Unit number.
  53881  *      port - (IN) GPORT ID
  53882  *      stat - (IN) Type of the counter to retrieve.
  53883  *      val - (OUT) Pointer to a counter value.
  53884  * Returns:
  53885  *      BCM_E_XXX
  53886  * Notes:
  53887  */
  53888 int
  53889 bcm_esw_port_stat_get32(int unit, bcm_gport_t port,
  53890                         bcm_port_stat_t stat, uint32 *val)
  53891 {
  53892     int rv = BCM_E_UNAVAIL;
  53893 
  53894     rv = _bcm_esw_port_stat_get32(unit, 0, port, stat, val);
  53895 
  53896     return rv;
  53897 
  53898 }
  53899 
  53900 
  53901 /*
  53902  * Function:
  53903  *      bcm_esw_port_stat_sync_get32
  53904  * Purpose:
  53905  *      Get lower 32-bit counter value for specified port statistic
  53906  *      type. sw accumulated counters synced with hw count.
  53907  * Parameters:
  53908  *      unit - (IN) Unit number.
  53909  *      port - (IN) GPORT ID
  53910  *      stat - (IN) Type of the counter to retrieve.
  53911  *      val - (OUT) Pointer to a counter value.
  53912  * Returns:
  53913  *      BCM_E_XXX
  53914  * Notes:
  53915  */
  53916 int
  53917 bcm_esw_port_stat_sync_get32(int unit, bcm_gport_t port,
  53918                              bcm_port_stat_t stat, uint32 *val)
  53919 {
  53920     int rv = BCM_E_UNAVAIL;
  53921 
  53922     rv = _bcm_esw_port_stat_get32(unit, 1, port, stat, val);
  53923 
  53924     return rv;
  53925 }
  53926 
  53927 /*
  53928  * Function:
  53929  *      bcm_esw_port_stat_set
  53930  * Purpose:
  53931  *      Set 64-bit counter value for specified port statistic type.
  53932  * Parameters:
  53933  *      unit - (IN) Unit number.
  53934  *      port - (IN) GPORT ID
  53935  *      stat - (IN) Type of the counter to retrieve.
  53936  *      val - (IN) New counter value.
  53937  * Returns:
  53938  *      BCM_E_XXX
  53939  * Notes:
  53940  */
  53941 int
  53942 bcm_esw_port_stat_set(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  53943                       uint64 val)
  53944 {
  53945 #if defined(BCM_TRIUMPH2_SUPPORT)
  53946 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53947   uint32           counter_indexes=0;
  53948   bcm_stat_value_t counter_values={0};
  53949 #endif
  53950 
  53951   /* Make sure port module is initialized. */
  53952   PORT_INIT(unit);
  53953 
  53954 #if defined(BCM_PREEMPTION_SUPPORT)
  53955   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  53956     bcm_port_t local_port;
  53957     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  53958     return bcmi_esw_preemption_counter_set(unit, local_port,
  53959                                            stat, val);
  53960   }
  53961 #endif /* BCM_PREEMPTION_SUPPORT */
  53962 
  53963   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  53964     BCM_IF_ERROR_RETURN
  53965         (_bcm_esw_port_stat_param_valid(unit, port));
  53966     return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeGport, port,
  53967                            _bcm_esw_port_stat_to_flex_stat(stat), val);
  53968   }
  53969 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  53970   if ((stat == bcmPortStatIngressPackets) ||
  53971       (stat == bcmPortStatEgressPackets)) {
  53972       counter_values.packets = COMPILER_64_LO(val);
  53973   } else {
  53974       COMPILER_64_SET(counter_values.bytes,
  53975                       COMPILER_64_HI(val),
  53976                       COMPILER_64_LO(val));
  53977   }
  53978   BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  53979                         unit,port,stat, 1, &counter_indexes, &counter_values));
  53980   return BCM_E_NONE;
  53981 #else
  53982     return BCM_E_UNAVAIL;
  53983 #endif
  53984 #else
  53985     return BCM_E_UNAVAIL;
  53986 #endif
  53987 }
  53988 
  53989 /*
  53990  * Function:
  53991  *      bcm_esw_port_stat_set32
  53992  * Purpose:
  53993  *      Set lower 32-bit counter value for specified port statistic
  53994  *      type.
  53995  * Parameters:
  53996  *      unit - (IN) Unit number.
  53997  *      port - (IN) GPORT ID
  53998  *      stat - (IN) Type of the counter to retrieve.
  53999  *      val - (IN) New counter value.
  54000  * Returns:
  54001  *      BCM_E_XXX
  54002  * Notes:
  54003  */
  54004 int
  54005 bcm_esw_port_stat_set32(int unit, bcm_gport_t port,
  54006                         bcm_port_stat_t stat, uint32 val)
  54007 {
  54008 #if defined(BCM_TRIUMPH2_SUPPORT)
  54009 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54010   uint32           counter_indexes=0;
  54011   bcm_stat_value_t counter_values={0};
  54012 #endif
  54013 
  54014   /* Make sure port module is initialized. */
  54015   PORT_INIT(unit);
  54016 
  54017 #if defined(BCM_PREEMPTION_SUPPORT)
  54018   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  54019     bcm_port_t local_port;
  54020     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  54021     return bcmi_esw_preemption_counter_set32(unit, local_port,
  54022                                              stat, val);
  54023   }
  54024 #endif /* BCM_PREEMPTION_SUPPORT */
  54025 
  54026 
  54027   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  54028     BCM_IF_ERROR_RETURN
  54029         (_bcm_esw_port_stat_param_valid(unit, port));
  54030     return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeGport, port,
  54031                            _bcm_esw_port_stat_to_flex_stat(stat), val);
  54032   }
  54033 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54034   if ((stat == bcmPortStatIngressPackets) ||
  54035       (stat == bcmPortStatEgressPackets)) {
  54036       counter_values.packets = val;
  54037   } else {
  54038       /* Ignoring high value */
  54039       COMPILER_64_SET(counter_values.bytes,0,val);
  54040   }
  54041   BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  54042                         unit,port,stat, 1, &counter_indexes, &counter_values));
  54043   return BCM_E_NONE;
  54044 #else
  54045     return BCM_E_UNAVAIL;
  54046 #endif
  54047 #else
  54048     return BCM_E_UNAVAIL;
  54049 #endif
  54050 }
  54051 
  54052 /*
  54053  * Function:
  54054  *      bcm_esw_port_stat_multi_get
  54055  * Purpose:
  54056  *      Get 64-bit counter value for multiple port statistic types.
  54057  * Parameters:
  54058  *      unit - (IN) Unit number.
  54059  *      port - (IN) GPORT ID
  54060  *      nstat - (IN) Number of elements in stat array
  54061  *      stat_arr - (IN) Collected statistics descriptors array
  54062  *      value_arr - (OUT) Collected counters values
  54063  * Returns:
  54064  *      BCM_E_XXX
  54065  * Notes:
  54066  */
  54067 int
  54068 bcm_esw_port_stat_multi_get(int unit, bcm_gport_t port, int nstat,
  54069                             bcm_port_stat_t *stat_arr,
  54070                             uint64 *value_arr)
  54071 {
  54072 #if defined(BCM_TRIUMPH2_SUPPORT)
  54073     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  54074     int idx;
  54075 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54076   uint32           counter_indexes=0;
  54077   bcm_stat_value_t counter_values={0};
  54078 #endif
  54079 
  54080   /* Make sure port module is initialized. */
  54081   PORT_INIT(unit);
  54082 
  54083 #if defined(BCM_PREEMPTION_SUPPORT)
  54084   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  54085     bcm_port_t local_port;
  54086     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  54087     return bcmi_esw_preemption_counter_multi_get(unit, 0, local_port, nstat,
  54088                                                  stat_arr, value_arr);
  54089   }
  54090 #endif /* BCM_PREEMPTION_SUPPORT */
  54091 
  54092   if (!soc_feature(unit, soc_feature_advanced_flex_counter)) {
  54093     BCM_IF_ERROR_RETURN
  54094         (_bcm_esw_port_stat_param_valid(unit, port));
  54095     BCM_IF_ERROR_RETURN
  54096         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  54097     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  54098 
  54099     return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeGport, port,
  54100                                         nstat, fs_arr, value_arr);
  54101   }
  54102 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54103   for (idx=0;idx < nstat ; idx ++) {
  54104       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get(
  54105                              unit, port, stat_arr[idx],
  54106                              1, &counter_indexes, &counter_values));
  54107       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  54108           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  54109           COMPILER_64_SET(value_arr[idx],
  54110                           COMPILER_64_HI(counter_values.packets64),
  54111                           COMPILER_64_LO(counter_values.packets64));
  54112       } else {
  54113           COMPILER_64_SET(value_arr[idx],
  54114                           COMPILER_64_HI(counter_values.bytes),
  54115                           COMPILER_64_LO(counter_values.bytes));
  54116       }
  54117   }
  54118   return BCM_E_NONE;
  54119 #else
  54120     return BCM_E_UNAVAIL;
  54121 #endif
  54122 #else
  54123     return BCM_E_UNAVAIL;
  54124 #endif
  54125 }
  54126 
  54127 /*
  54128  * Function:
  54129  *      bcm_esw_port_stat_multi_get32
  54130  * Purpose:
  54131  *      Get lower 32-bit counter value for multiple port statistic
  54132  *      types.
  54133  * Parameters:
  54134  *      unit - (IN) Unit number.
  54135  *      port - (IN) GPORT ID
  54136  *      nstat - (IN) Number of elements in stat array
  54137  *      stat_arr - (IN) Collected statistics descriptors array
  54138  *      value_arr - (OUT) Collected counters values
  54139  * Returns:
  54140  *      BCM_E_XXX
  54141  * Notes:
  54142  */
  54143 int
  54144 bcm_esw_port_stat_multi_get32(int unit, bcm_gport_t port, int nstat,
  54145                               bcm_port_stat_t *stat_arr,
  54146                               uint32 *value_arr)
  54147 {
  54148 #if defined(BCM_TRIUMPH2_SUPPORT)
  54149     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  54150     int idx;
  54151 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54152   uint32           counter_indexes=0;
  54153   bcm_stat_value_t counter_values={0};
  54154 #endif
  54155 
  54156   /* Make sure port module is initialized. */
  54157   PORT_INIT(unit);
  54158 
  54159 #if defined(BCM_PREEMPTION_SUPPORT)
  54160   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  54161     bcm_port_t local_port;
  54162     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  54163     return bcmi_esw_preemption_counter_multi_get32(unit, 0, local_port, nstat,
  54164                                                    stat_arr, value_arr);
  54165   }
  54166 #endif /* BCM_PREEMPTION_SUPPORT */
  54167 
  54168 
  54169   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  54170     BCM_IF_ERROR_RETURN
  54171         (_bcm_esw_port_stat_param_valid(unit, port));
  54172     BCM_IF_ERROR_RETURN
  54173         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  54174     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  54175 
  54176     return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeGport, port,
  54177                                           nstat, fs_arr, value_arr);
  54178   }
  54179 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54180   for (idx=0;idx < nstat ; idx ++) {
  54181       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get(
  54182                              unit, port, stat_arr[idx],
  54183                              1, &counter_indexes, &counter_values));
  54184       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  54185           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  54186           value_arr[idx] = counter_values.packets;
  54187       } else {
  54188           value_arr[idx] = COMPILER_64_LO(counter_values.bytes);
  54189       }
  54190   }
  54191   return BCM_E_NONE;
  54192 #else
  54193     return BCM_E_UNAVAIL;
  54194 #endif
  54195 #else
  54196     return BCM_E_UNAVAIL;
  54197 #endif
  54198 }
  54199 
  54200 /*
  54201  * Function:
  54202  *      bcm_esw_port_stat_multi_set
  54203  * Purpose:
  54204  *      Set 64-bit counter value for multiple port statistic types.
  54205  * Parameters:
  54206  *      unit - (IN) Unit number.
  54207  *      port - (IN) GPORT ID
  54208  *      nstat - (IN) Number of elements in stat array
  54209  *      stat_arr - (IN) New statistics descriptors array
  54210  *      value_arr - (IN) New counters values
  54211  * Returns:
  54212  *      BCM_E_XXX
  54213  * Notes:
  54214  */
  54215 int
  54216 bcm_esw_port_stat_multi_set(int unit, bcm_gport_t port, int nstat,
  54217                             bcm_port_stat_t *stat_arr,
  54218                             uint64 *value_arr)
  54219 {
  54220 #if defined(BCM_TRIUMPH2_SUPPORT)
  54221     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  54222     int idx;
  54223 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54224   uint32           counter_indexes=0;
  54225   bcm_stat_value_t counter_values={0};
  54226 #endif
  54227 
  54228   /* Make sure port module is initialized. */
  54229   PORT_INIT(unit);
  54230 
  54231 #if defined(BCM_PREEMPTION_SUPPORT)
  54232   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  54233     bcm_port_t local_port;
  54234     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  54235     return bcmi_esw_preemption_counter_multi_set(unit, local_port, nstat,
  54236                                                  stat_arr, value_arr);
  54237   }
  54238 #endif /* BCM_PREEMPTION_SUPPORT */
  54239 
  54240   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  54241     BCM_IF_ERROR_RETURN
  54242         (_bcm_esw_port_stat_param_valid(unit, port));
  54243     BCM_IF_ERROR_RETURN
  54244         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  54245     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  54246 
  54247     return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeGport, port,
  54248                                           nstat, fs_arr, value_arr);
  54249   }
  54250 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54251   for (idx=0;idx < nstat ; idx ++) {
  54252       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  54253           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  54254           counter_values.packets = COMPILER_64_LO(value_arr[idx]);
  54255       } else {
  54256           COMPILER_64_SET(counter_values.bytes,
  54257                           COMPILER_64_HI(value_arr[idx]),
  54258                           COMPILER_64_LO(value_arr[idx]));
  54259       }
  54260       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  54261                              unit, port, stat_arr[idx],
  54262                              1, &counter_indexes, &counter_values));
  54263   }
  54264   return BCM_E_NONE;
  54265 #else
  54266     return BCM_E_UNAVAIL;
  54267 #endif
  54268 #else
  54269     return BCM_E_UNAVAIL;
  54270 #endif
  54271 }
  54272 
  54273 /*
  54274  * Function:
  54275  *      bcm_esw_port_stat_multi_set32
  54276  * Purpose:
  54277  *      Set lower 32-bit counter value for multiple port statistic
  54278  *      types.
  54279  * Parameters:
  54280  *      unit - (IN) Unit number.
  54281  *      port - (IN) GPORT ID
  54282  *      nstat - (IN) Number of elements in stat array
  54283  *      stat_arr - (IN) New statistics descriptors array
  54284  *      value_arr - (IN) New counters values
  54285  * Returns:
  54286  *      BCM_E_XXX
  54287  * Notes:
  54288  */
  54289 int
  54290 bcm_esw_port_stat_multi_set32(int unit, bcm_gport_t port, int nstat,
  54291                               bcm_port_stat_t *stat_arr,
  54292                               uint32 *value_arr)
  54293 {
  54294 #if defined(BCM_TRIUMPH2_SUPPORT)
  54295     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  54296     int idx;
  54297 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54298   uint32           counter_indexes=0;
  54299   bcm_stat_value_t counter_values={0};
  54300 #endif
  54301 
  54302   /* Make sure port module is initialized. */
  54303   PORT_INIT(unit);
  54304 
  54305 #if defined(BCM_PREEMPTION_SUPPORT)
  54306   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  54307     bcm_port_t local_port;
  54308     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  54309     return bcmi_esw_preemption_counter_multi_set32(unit, local_port, nstat,
  54310                                                    stat_arr, value_arr);
  54311   }
  54312 #endif /* BCM_PREEMPTION_SUPPORT */
  54313 
  54314   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  54315     BCM_IF_ERROR_RETURN
  54316         (_bcm_esw_port_stat_param_valid(unit, port));
  54317     BCM_IF_ERROR_RETURN
  54318         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  54319     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  54320 
  54321     return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeGport, port,
  54322                                           nstat, fs_arr, value_arr);
  54323   }
  54324 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54325   for (idx=0;idx < nstat ; idx ++) {
  54326       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  54327           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  54328           counter_values.packets = value_arr[idx];
  54329       } else {
  54330           COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]);
  54331       }
  54332       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  54333                              unit, port, stat_arr[idx],
  54334                              1, &counter_indexes, &counter_values));
  54335   }
  54336   return BCM_E_NONE;
  54337 #else
  54338     return BCM_E_UNAVAIL;
  54339 #endif
  54340 #else
  54341     return BCM_E_UNAVAIL;
  54342 #endif
  54343 }
  54344 
  54345 /*
  54346  * Function    : _bcm_gport_dest_t_init
  54347  * Description : Initialize gport_dest structure
  54348  * Parameters  : (IN/OUT)  gport_dest - Structure to initialize
  54349  * Returns     : None
  54350  */
  54351 
  54352 void
  54353 _bcm_gport_dest_t_init(_bcm_gport_dest_t *gport_dest)
  54354 {
  54355     sal_memset(gport_dest, 0, sizeof (_bcm_gport_dest_t));
  54356 }
  54357 
  54358 
  54359 /*
  54360  * Function    : _bcm_esw_gport_construct
  54361  * Description : Internal function to construct a gport from
  54362  *                given parameters
  54363  * Parameters  : (IN)  unit       - BCM device number
  54364  *               (IN)  gport_dest - Structure that contains destination
  54365  *                                   to encode into a gport
  54366  *               (OUT) gport      - Global port identifier
  54367  * Returns     : BCM_E_XXX
  54368  * Notes       : The modid and port are translated from the
  54369  *               local modid/port space to application space
  54370  */
  54371 int
  54372 _bcm_esw_gport_construct(int unit, _bcm_gport_dest_t *gport_dest, bcm_gport_t *gport)
  54373 {
  54374 
  54375     bcm_gport_t     l_gport = 0;
  54376     bcm_module_t    mod_out;
  54377     bcm_port_t      port_out;
  54378 
  54379     if ((NULL == gport_dest) || (NULL == gport) ){
  54380         return BCM_E_PARAM;
  54381     }
  54382 
  54383     switch (gport_dest->gport_type) {
  54384         case _SHR_GPORT_TYPE_TRUNK:
  54385             SOC_GPORT_TRUNK_SET(l_gport, gport_dest->tgid);
  54386             break;
  54387         case _SHR_GPORT_TYPE_LOCAL_CPU:
  54388             l_gport = BCM_GPORT_LOCAL_CPU;
  54389             break;
  54390         case _SHR_GPORT_TYPE_BLACK_HOLE:
  54391             l_gport = BCM_GPORT_BLACK_HOLE;
  54392             break;
  54393         case _SHR_GPORT_TYPE_LOCAL:
  54394             SOC_GPORT_LOCAL_SET(l_gport, gport_dest->port);
  54395             break;
  54396         case _SHR_GPORT_TYPE_SUBPORT_GROUP:
  54397             SOC_GPORT_SUBPORT_GROUP_SET(l_gport, gport_dest->subport_id);
  54398             break;
  54399         case _SHR_GPORT_TYPE_MPLS_PORT:
  54400             BCM_GPORT_MPLS_PORT_ID_SET(l_gport, gport_dest->mpls_id);
  54401             break;
  54402         case _SHR_GPORT_TYPE_MIM_PORT:
  54403             BCM_GPORT_MIM_PORT_ID_SET(l_gport, gport_dest->mim_id);
  54404             break;
  54405         case _SHR_GPORT_TYPE_WLAN_PORT:
  54406             BCM_GPORT_WLAN_PORT_ID_SET(l_gport, gport_dest->wlan_id);
  54407             break;
  54408         case _SHR_GPORT_TYPE_TRILL_PORT:
  54409             BCM_GPORT_TRILL_PORT_ID_SET(l_gport, gport_dest->trill_id);
  54410             break;
  54411         case _SHR_GPORT_TYPE_NIV_PORT:
  54412             BCM_GPORT_NIV_PORT_ID_SET(l_gport, gport_dest->niv_id);
  54413             break;
  54414         case _SHR_GPORT_TYPE_L2GRE_PORT:
  54415             BCM_GPORT_L2GRE_PORT_ID_SET(l_gport, gport_dest->l2gre_id);
  54416             break;
  54417         case _SHR_GPORT_TYPE_VXLAN_PORT:
  54418             BCM_GPORT_VXLAN_PORT_ID_SET(l_gport, gport_dest->vxlan_id);
  54419             break;
  54420         case _SHR_GPORT_TYPE_FLOW_PORT:
  54421             BCM_GPORT_FLOW_PORT_ID_SET(l_gport, gport_dest->flow_id);
  54422             break;
  54423         case _SHR_GPORT_TYPE_VLAN_PORT:
  54424             BCM_GPORT_VLAN_PORT_ID_SET(l_gport, gport_dest->vlan_vp_id);
  54425             break;
  54426         case _SHR_GPORT_TYPE_EXTENDER_PORT:
  54427             BCM_GPORT_EXTENDER_PORT_ID_SET(l_gport, gport_dest->extender_id);
  54428             break;
  54429         case _SHR_GPORT_TYPE_DEVPORT:
  54430             BCM_GPORT_DEVPORT_SET(l_gport, unit, gport_dest->port);
  54431             break;
  54432         case _SHR_GPORT_TYPE_MODPORT:
  54433             BCM_IF_ERROR_RETURN (
  54434                 _bcm_gport_modport_hw2api_map(unit, gport_dest->modid,
  54435                                               gport_dest->port, &mod_out,
  54436                                               &port_out));
  54437             SOC_GPORT_MODPORT_SET(l_gport, mod_out, port_out);
  54438             break;
  54439         default:
  54440             return BCM_E_PARAM;
  54441     }
  54442 
  54443     *gport = l_gport;
  54444     return BCM_E_NONE;
  54445 }
  54446 
  54447 /*
  54448  * Function    : _bcm_esw_gport_resolve
  54449  * Description : Internal function to get modid, port, and trunk_id
  54450  *               from a bcm_gport_t (global port)
  54451  * Parameters  : (IN)  unit      - BCM device number
  54452  *               (IN)  gport     - Global port identifier
  54453  *               (OUT) modid     - Module ID
  54454  *               (OUT) port      - Port number
  54455  *               (OUT) trunk_id  - Trunk ID
  54456  *               (OUT) id        - HW ID
  54457  * Returns     : BCM_E_XXX
  54458  * Notes       : The modid and port are translated from the
  54459  *               application space to local modid/port space if applicable,
  54460  *               on units without modid (Fabric) modid will be -1 and port
  54461  *               will be a local physical port.
  54462  */
  54463 int
  54464 _bcm_esw_gport_resolve(int unit, bcm_gport_t gport,
  54465                        bcm_module_t *modid, bcm_port_t *port,
  54466                        bcm_trunk_t *trunk_id, int *id)
  54467 {
  54468     int             local_id, rv = BCM_E_NONE;
  54469     bcm_module_t    mod_in, local_modid;
  54470     bcm_port_t      port_in, local_port;
  54471     bcm_trunk_t     local_tgid;
  54472 #ifdef BCM_KATANA_SUPPORT
  54473     int extended_queue_id = 0;
  54474 #endif
  54475 
  54476     local_modid = -1;
  54477     local_port = -1;
  54478     local_id = -1;
  54479     local_tgid = BCM_TRUNK_INVALID;
  54480 
  54481     if (BCM_GPORT_IS_TRUNK(gport)) {
  54482         local_tgid = SOC_GPORT_TRUNK_GET(gport);
  54483     } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) {
  54484         rv = bcm_esw_stk_my_modid_get(unit, &local_modid);
  54485         if (BCM_FAILURE(rv) && !SOC_IS_XGS_FABRIC(unit)) {
  54486             return rv;
  54487         }
  54488         local_port = CMIC_PORT(unit);
  54489     } else if (BCM_GPORT_IS_LOCAL(gport)) {
  54490         BCM_IF_ERROR_RETURN
  54491             (bcm_esw_stk_my_modid_get(unit, &local_modid));
  54492         local_port = SOC_GPORT_LOCAL_GET(gport);
  54493         if (soc_feature(unit, soc_feature_sysport_remap)) {
  54494             BCM_XLATE_SYSPORT_P2S(unit, &local_port);
  54495         }
  54496         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  54497             return BCM_E_PORT;
  54498         }
  54499     } else if (BCM_GPORT_IS_DEVPORT(gport)) {
  54500         rv = bcm_esw_stk_my_modid_get(unit, &local_modid);
  54501         if (BCM_FAILURE(rv)) {
  54502             if (!SOC_IS_XGS_FABRIC(unit)) {
  54503                 return rv;
  54504             }
  54505         }
  54506         if (unit != SOC_GPORT_DEVPORT_DEVID_GET(gport)) {
  54507             return BCM_E_PORT;
  54508         }
  54509         local_port = SOC_GPORT_DEVPORT_PORT_GET(gport);
  54510 
  54511         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  54512             return BCM_E_PORT;
  54513         }
  54514     } else if (BCM_GPORT_IS_MODPORT(gport)) {
  54515         mod_in = SOC_GPORT_MODPORT_MODID_GET(gport);
  54516         port_in = SOC_GPORT_MODPORT_PORT_GET(gport);
  54517 
  54518         if (NUM_MODID(unit) > 1) {
  54519 #if defined(BCM_TOMAHAWK_SUPPORT)
  54520             /* Call asymmetric dual modid unmapping function */
  54521             if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  54522                 BCM_IF_ERROR_RETURN (
  54523                     _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  54524                                 BCM_STK_MODMAP_GET, &mod_in, &port_in));
  54525             } else
  54526 #endif /* BCM_TOMAHAWK_SUPPORT */
  54527             if ((NUM_MODID(unit) > 1) && (port_in > SOC_INFO(unit).modport_max)) {
  54528                 mod_in = mod_in + 1;
  54529                 port_in = port_in - (SOC_INFO(unit).modport_max + 1);
  54530             }
  54531         }
  54532         PORT_DUALMODID_VALID(unit, port_in);
  54533         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  54534                                     mod_in, port_in, &local_modid, &local_port);
  54535 
  54536         if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) {
  54537             return BCM_E_BADID;
  54538         }
  54539         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  54540             return BCM_E_PORT;
  54541         }
  54542     } else if (BCM_GPORT_IS_PROXY(gport)) {
  54543         mod_in = BCM_GPORT_PROXY_MODID_GET(gport);
  54544         port_in = BCM_GPORT_PROXY_PORT_GET(gport);
  54545         PORT_DUALMODID_VALID(unit, port_in);
  54546         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  54547                                     mod_in, port_in, &local_modid, &local_port);
  54548 
  54549         if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) {
  54550             return BCM_E_BADID;
  54551         }
  54552         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  54553             return BCM_E_PORT;
  54554         }
  54555     }
  54556 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  54557     defined(INCLUDE_L3)
  54558     else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  54559         if (SOC_IS_TR_VL(unit)) {
  54560             rv = _bcm_tr_mpls_port_resolve(unit, gport, &local_modid,
  54561                                            &local_port, &local_tgid,
  54562                                            &local_id);
  54563         }
  54564     }
  54565 #endif
  54566 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  54567      && defined(INCLUDE_L3))
  54568     else if (BCM_GPORT_IS_MIM_PORT(gport)) {
  54569         if (soc_feature(unit, soc_feature_mim)) {
  54570             rv = _bcm_tr2_mim_port_resolve(unit, gport, &local_modid,
  54571                                           &local_port, &local_tgid,
  54572                                           &local_id);
  54573         }
  54574     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  54575         if (soc_feature(unit, soc_feature_wlan)) {
  54576 #if defined(BCM_TRIUMPH3_SUPPORT)
  54577             if (SOC_IS_TRIUMPH3(unit)) {
  54578                 rv = _bcm_tr3_wlan_port_resolve(unit, gport, &local_modid,
  54579                                                &local_port, &local_tgid,
  54580                                                &local_id);
  54581             } else
  54582 #endif /* BCM_TRIUMPH3_SUPPORT */
  54583             {
  54584                 rv = _bcm_tr2_wlan_port_resolve(unit, gport, &local_modid,
  54585                                                &local_port, &local_tgid,
  54586                                                &local_id);
  54587             }
  54588         }
  54589     }
  54590 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  54591 #if defined (BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  54592     else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
  54593         if (soc_feature(unit, soc_feature_l2gre)) {
  54594             rv = _bcm_tr3_l2gre_port_resolve(unit, gport, -1, &local_modid,
  54595                                           &local_port, &local_tgid,
  54596                                           &local_id);
  54597         }
  54598     }
  54599 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  54600 #if defined (BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  54601     else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  54602         if (soc_feature(unit, soc_feature_vxlan)) {
  54603             rv = _bcm_td2_vxlan_port_resolve(unit, gport, -1, &local_modid,
  54604                                           &local_port, &local_tgid,
  54605                                           &local_id);
  54606         }
  54607     }
  54608 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  54609 #if defined (BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
  54610     else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  54611         if (soc_feature(unit, soc_feature_vxlan_lite)) {
  54612             rv = bcmi_gh2_vxlan_port_resolve(unit, gport, -1, &local_modid,
  54613                                              &local_port, &local_tgid,
  54614                                              &local_id);
  54615         }
  54616     }
  54617 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
  54618 #if defined (BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3)
  54619     else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
  54620         if (soc_feature(unit, soc_feature_flex_flow)) {
  54621             rv = _bcm_td3_flow_port_resolve(unit, gport, -1, &local_modid,
  54622                                           &local_port, &local_tgid,
  54623                                           &local_id);
  54624         }
  54625     }
  54626 #endif /* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */
  54627 #if defined (BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  54628     else if (BCM_GPORT_IS_TRILL_PORT(gport)) {
  54629         if (soc_feature(unit, soc_feature_trill)) {
  54630             rv = _bcm_td_trill_port_resolve(unit, gport, -1, &local_modid,
  54631                                           &local_port, &local_tgid,
  54632                                           &local_id);
  54633         }
  54634     }
  54635 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  54636 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
  54637     else if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) {
  54638         if (SOC_IS_TRX(unit)) {
  54639 
  54640 #if defined (BCM_HGPROXY_COE_SUPPORT)
  54641 			if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  54642                 soc_feature(unit, soc_feature_channelized_switching)) {
  54643 				rv = _bcmi_xgs5_subport_group_resolve(unit, gport, &local_modid,
  54644 												   &local_port, &local_tgid,
  54645 												   &local_id);
  54646 			} else
  54647 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
  54648 
  54649 #if defined (BCM_KATANA2_SUPPORT)
  54650             if (SOC_IS_KATANA2(unit)) {
  54651                 rv = bcm_kt2_subport_group_resolve(unit, gport, &local_modid,
  54652                                                    &local_port, &local_tgid,
  54653                                                    &local_id);
  54654             } else
  54655 #endif /* defined (BCM_KATANA2_SUPPORT) */
  54656             if (soc_feature(unit, soc_feature_subport_enhanced)) {
  54657 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  54658                 rv = _bcm_tr2_subport_group_resolve(unit, gport, &local_modid,
  54659                                                     &local_port, &local_tgid,
  54660                                                     &local_id);
  54661 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */
  54662             } else if (soc_feature(unit, soc_feature_subport)) {
  54663                 rv = _bcm_tr_subport_group_resolve(unit, gport, &local_modid,
  54664                                                    &local_port, &local_tgid,
  54665                                                    &local_id);
  54666             }
  54667         }
  54668     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
  54669         if (SOC_IS_TRX(unit)) {
  54670 
  54671 #if defined (BCM_HGPROXY_COE_SUPPORT)
  54672             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  54673                 soc_feature(unit, soc_feature_channelized_switching)) {
  54674                 rv = _bcm_xgs5_subport_port_resolve(unit, gport, &local_modid,
  54675                                                    &local_port, &local_tgid,
  54676                                                    &local_id);
  54677             } else
  54678 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
  54679 
  54680 #if defined (BCM_KATANA2_SUPPORT)
  54681             if (SOC_IS_KATANA2(unit)) {
  54682 
  54683                 rv = bcm_kt2_subport_port_resolve(unit, gport, &local_modid,
  54684                                                    &local_port, &local_tgid,
  54685                                                    &local_id);
  54686             } else
  54687 #endif /* defined (BCM_KATANA2_SUPPORT) */
  54688             if (soc_feature(unit, soc_feature_subport_enhanced)) {
  54689 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  54690                 rv = _bcm_tr2_subport_port_resolve(unit, gport, &local_modid,
  54691                                                    &local_port, &local_tgid,
  54692                                                    &local_id);
  54693 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */
  54694             } else if (soc_feature(unit, soc_feature_subport)) {
  54695                 rv = _bcm_tr_subport_port_resolve(unit, gport, &local_modid,
  54696                                                   &local_port, &local_tgid,
  54697                                                   &local_id);
  54698             }
  54699         }
  54700     }
  54701 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  54702 #ifdef BCM_TRIUMPH_SUPPORT
  54703     else if (BCM_GPORT_IS_SCHEDULER(gport)) {
  54704 #if defined (BCM_TOMAHAWK3_SUPPORT)
  54705         if (SOC_IS_TOMAHAWK3(unit)) {
  54706             rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid,
  54707                                            &local_port, &local_tgid,
  54708                                            &local_id, NULL);
  54709         } else
  54710 #endif /* BCM_TOMAHAWK3_SUPPORT */
  54711 #if defined (BCM_TOMAHAWK_SUPPORT)
  54712         if (SOC_IS_TOMAHAWKX(unit)) {
  54713             rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid,
  54714                                            &local_port, &local_tgid,
  54715                                            &local_id, NULL);
  54716         } else
  54717 #endif /* BCM_TOMAHAWK_SUPPORT */
  54718 #ifdef BCM_HURRICANE4_SUPPORT
  54719         if (SOC_IS_HURRICANE4(unit)) {
  54720             rv = _bcm_hr4_cosq_port_resolve(unit, gport, &local_modid,
  54721                                             &local_port, &local_tgid,
  54722                                             &local_id, NULL);
  54723         } else
  54724 #endif /* BCM_HURRICANE4_SUPPORT */
  54725 #ifdef BCM_HELIX5_SUPPORT
  54726         if (SOC_IS_HELIX5(unit)) {
  54727             rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid,
  54728                                             &local_port, &local_tgid,
  54729                                             &local_id, NULL);
  54730         } else
  54731 #endif /* BCM_HELIX5_SUPPORT */
  54732 #if defined (BCM_MONTEREY_SUPPORT)
  54733         if (SOC_IS_MONTEREY(unit)) {
  54734             rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid,
  54735                                            &local_port, &local_tgid,
  54736                                            &local_id, NULL);
  54737         } else
  54738 #endif
  54739 #ifdef BCM_FIREBOLT6_SUPPORT
  54740         if (SOC_IS_FIREBOLT6(unit)) {
  54741             rv = _bcm_fb6_cosq_port_resolve(unit, gport, &local_modid,
  54742                                             &local_port, &local_tgid,
  54743                                             &local_id, NULL);
  54744         } else
  54745 #endif /* BCM_FIREBOLT6_SUPPORT */
  54746 #ifdef BCM_TRIDENT3_SUPPORT
  54747         if (SOC_IS_TRIDENT3X(unit)) {
  54748             rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid,
  54749                                             &local_port, &local_tgid,
  54750                                             &local_id, NULL);
  54751         } else
  54752 #endif /* BCM_TRIDENT3_SUPPORT */
  54753 #if defined (BCM_APACHE_SUPPORT)
  54754         if (SOC_IS_APACHE(unit)) {
  54755             rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid,
  54756                                            &local_port, &local_tgid,
  54757                                            &local_id, NULL);
  54758         } else
  54759 #endif
  54760 #if defined (BCM_TRIDENT2_SUPPORT)
  54761         if (SOC_IS_TD2_TT2(unit)) {
  54762             rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid,
  54763                                            &local_port, &local_tgid,
  54764                                            &local_id, NULL);
  54765         } else
  54766 #endif /* BCM_TRIDENT2_SUPPORT */
  54767 #if defined (BCM_TRIDENT_SUPPORT)
  54768         if (SOC_IS_TD_TT(unit)) {
  54769             rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid,
  54770                                            &local_port, &local_tgid,
  54771                                            &local_id);
  54772         } else
  54773 #endif /* BCM_TRIDENT_SUPPORT */
  54774 #if defined (BCM_TRIUMPH3_SUPPORT)
  54775         if (SOC_IS_TRIUMPH3(unit)) {
  54776             rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid,
  54777                                             &local_port, &local_tgid,
  54778                                             &local_id, NULL);
  54779         } else
  54780 #endif /* BCM_TRIUMPH3_SUPPORT */
  54781 #if defined (BCM_TRIUMPH2_SUPPORT)
  54782         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  54783             SOC_IS_VALKYRIE2(unit)) {
  54784             rv = _bcm_tr2_cosq_port_resolve(unit, gport, &local_modid,
  54785                                             &local_port, &local_tgid,
  54786                                             &local_id);
  54787         } else
  54788 #endif /* BCM_TRIUMPH2_SUPPORT */
  54789 #if defined (BCM_GREYHOUND2_SUPPORT)
  54790         if (SOC_IS_GREYHOUND2(unit)) {
  54791             rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid,
  54792                                             &local_port, &local_tgid,
  54793                                             &local_id);
  54794         } else
  54795 #endif /* BCM_GREYHOUND2_SUPPORT */
  54796         if (SOC_IS_TR_VL(unit)) {
  54797             rv = _bcm_tr_cosq_port_resolve(unit, gport, &local_modid,
  54798                                            &local_port, &local_tgid,
  54799                                            &local_id);
  54800         }
  54801     }
  54802 #endif /* BCM_TRIUMPH_SUPPORT */
  54803 #ifdef BCM_KATANA_SUPPORT
  54804     else if ((SOC_IS_KATANAX(unit)) &&
  54805              ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) ||
  54806               (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) ||
  54807               (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)))) {
  54808         if (soc_feature(unit, soc_feature_extended_queueing)) {
  54809 #if defined(BCM_KATANA2_SUPPORT)
  54810             if (SOC_IS_KATANA2(unit)) {
  54811                  rv = _bcm_kt2_cosq_port_resolve(unit, gport, &local_modid,
  54812                                        &local_port, &local_tgid,
  54813                                        &local_id, &extended_queue_id);
  54814             } else
  54815 #endif
  54816             if (SOC_IS_KATANA(unit)){
  54817                  rv = _bcm_kt_cosq_port_resolve(unit, gport, &local_modid,
  54818                                        &local_port, &local_tgid,
  54819                                        &local_id, &extended_queue_id);
  54820             }
  54821             local_tgid = extended_queue_id;
  54822         }
  54823     }
  54824 #endif /* BCM_KATANA_SUPPORT */
  54825 
  54826 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  54827     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  54828     else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  54829              BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
  54830 #if defined (BCM_TOMAHAWK3_SUPPORT)
  54831         if (SOC_IS_TOMAHAWK3(unit)) {
  54832             rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid,
  54833                                            &local_port, &local_tgid,
  54834                                            &local_id, NULL);
  54835         } else
  54836 #endif /* BCM_TOMAHAWK3_SUPPORT */
  54837 #if defined (BCM_TOMAHAWK_SUPPORT)
  54838         if (SOC_IS_TOMAHAWKX(unit)) {
  54839             rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid,
  54840                                            &local_port, &local_tgid,
  54841                                            &local_id, NULL);
  54842         } else
  54843 #endif /* BCM_TOMAHAWK_SUPPORT */
  54844 #ifdef BCM_HURRICANE4_SUPPORT
  54845         if (SOC_IS_HURRICANE4(unit)) {
  54846             rv = _bcm_hr4_cosq_port_resolve(unit, gport, &local_modid,
  54847                                             &local_port, &local_tgid,
  54848                                             &local_id, NULL);
  54849         } else
  54850 #endif /* BCM_HURRICANE4_SUPPORT */
  54851 #ifdef BCM_HELIX5_SUPPORT
  54852         if (SOC_IS_HELIX5(unit)) {
  54853             rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid,
  54854                                             &local_port, &local_tgid,
  54855                                             &local_id, NULL);
  54856         } else
  54857 #endif /* BCM_HELIX5_SUPPORT */
  54858 #if defined (BCM_MONTEREY_SUPPORT)
  54859         if (SOC_IS_MONTEREY(unit)) {
  54860             rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid,
  54861                                            &local_port, &local_tgid,
  54862                                            &local_id, NULL);
  54863         } else
  54864 #endif
  54865 
  54866 #ifdef BCM_FIREBOLT6_SUPPORT
  54867         if (SOC_IS_FIREBOLT6(unit)) {
  54868             rv = _bcm_fb6_cosq_port_resolve(unit, gport, &local_modid,
  54869                                             &local_port, &local_tgid,
  54870                                             &local_id, NULL);
  54871         } else
  54872 #endif /* BCM_FIREBOLT6_SUPPORT */
  54873 #ifdef BCM_TRIDENT3_SUPPORT
  54874         if (SOC_IS_TRIDENT3X(unit)) {
  54875             rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid,
  54876                                             &local_port, &local_tgid,
  54877                                             &local_id, NULL);
  54878         } else
  54879 #endif /* BCM_TRIDENT3_SUPPORT */
  54880 #if defined(BCM_APACHE_SUPPORT)
  54881         if (SOC_IS_APACHE(unit)) {
  54882             rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid,
  54883                                            &local_port, &local_tgid,
  54884                                            &local_id, NULL);
  54885         } else
  54886 #endif /* BCM_APACHE_SUPPORT */
  54887 #if defined(BCM_TRIDENT2_SUPPORT)
  54888         if (SOC_IS_TD2_TT2(unit)) {
  54889             rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid,
  54890                                            &local_port, &local_tgid,
  54891                                            &local_id, NULL);
  54892         } else
  54893 #endif /* BCM_TRIDENT2_SUPPORT */
  54894 #if defined(BCM_TRIDENT_SUPPORT)
  54895         if (SOC_IS_TD_TT(unit)) {
  54896             rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid,
  54897                                            &local_port, &local_tgid,
  54898                                            &local_id);
  54899         } else
  54900 #endif /* BCM_TRIDENT_SUPPORT */
  54901 #if defined(BCM_TRIUMPH3_SUPPORT)
  54902         if (SOC_IS_TRIUMPH3(unit)) {
  54903             rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid,
  54904                                            &local_port, &local_tgid,
  54905                                            &local_id, NULL);
  54906         } else
  54907 #endif
  54908 #if defined (BCM_GREYHOUND2_SUPPORT)
  54909         if (SOC_IS_GREYHOUND2(unit)) {
  54910             rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid,
  54911                                             &local_port, &local_tgid,
  54912                                             &local_id);
  54913         } else
  54914 #endif /* BCM_GREYHOUND2_SUPPORT */
  54915         {
  54916             return BCM_E_UNAVAIL;
  54917         }
  54918     }
  54919 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT */
  54920 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  54921     else if (BCM_GPORT_IS_VLAN_PORT(gport)) {
  54922         if (soc_feature(unit, soc_feature_vlan_vp)) {
  54923 #if defined(BCM_ENDURO_SUPPORT)
  54924             if (SOC_IS_ENDURO(unit)) {
  54925                 rv = _bcm_enduro_vlan_port_resolve(unit, gport, &local_modid,
  54926                                           &local_port, &local_tgid,
  54927                                           &local_id);
  54928             } else
  54929 #endif /* BCM_ENDURO_SUPPORT */
  54930             {
  54931                 rv = _bcm_tr2_vlan_port_resolve(unit, gport, &local_modid,
  54932                                           &local_port, &local_tgid,
  54933                                           &local_id);
  54934             }
  54935         }
  54936     }
  54937 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  54938 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  54939     else if (BCM_GPORT_IS_NIV_PORT(gport)) {
  54940         if (soc_feature(unit, soc_feature_niv)) {
  54941             rv = _bcm_trident_niv_port_resolve(unit, gport, &local_modid,
  54942                     &local_port, &local_tgid,
  54943                     &local_id);
  54944         }
  54945     }
  54946 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  54947 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  54948     else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
  54949         if (soc_feature(unit, soc_feature_port_extension)) {
  54950             rv = _bcm_tr3_extender_port_resolve(unit, gport, &local_modid,
  54951                     &local_port, &local_tgid,
  54952                     &local_id);
  54953         }
  54954     }
  54955 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  54956     else if (BCM_GPORT_IS_BLACK_HOLE(gport)) {
  54957          local_modid = BCM_MODID_INVALID;
  54958          local_tgid = BCM_TRUNK_INVALID;
  54959          local_port = BCM_GPORT_INVALID;
  54960          local_id = -1;
  54961          rv = BCM_E_NONE;
  54962     }
  54963     else {
  54964          /* BCM_GPORT_INVALID should return an error */
  54965          return BCM_E_PORT;
  54966     }
  54967     *modid = local_modid;
  54968     *port = local_port;
  54969     *trunk_id = local_tgid;
  54970     *id = local_id;
  54971     return (rv);
  54972 }
  54973 
  54974 /*
  54975  * Function    : _bcm_esw_port_is_local_subport
  54976  * Description : Internal function to check whehter a gport or (mod,port)
  54977  *               is local subport.
  54978  * Parameters  : (IN)  unit      - BCM device number
  54979  *               (IN)  gport     - Global port identifier
  54980  *               (IN)  modid     - Module ID
  54981  *               (IN)  port      - Port number
  54982  *               (OUT) is_local_subport     - True/False
  54983  *               (OUT) phy_port             - physical port of subport
  54984  * Returns     : BCM_E_XXX
  54985  * Note: all gport, modid, port parameters are required.
  54986  */
  54987 int
  54988 _bcm_esw_port_is_local_subport(int unit, bcm_gport_t gport,
  54989                                bcm_module_t modid, bcm_port_t port,
  54990                                int *is_local_subport, bcm_port_t *phy_port)
  54991 {
  54992 #if defined(BCM_KATANA2_SUPPORT)
  54993     int pp_port;
  54994     int min_subport = SOC_INFO(unit).pp_port_index_min;
  54995     int max_subport = SOC_INFO(unit).pp_port_index_max;
  54996 #endif
  54997 
  54998     if ((is_local_subport == NULL) || (phy_port == NULL)) {
  54999         return BCM_E_PARAM;
  55000     }
  55001 
  55002     *is_local_subport = FALSE;
  55003 
  55004 #if defined(BCM_HGPROXY_COE_SUPPORT)
  55005     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  55006         soc_feature(unit, soc_feature_channelized_switching)) &&
  55007         BCM_GPORT_IS_SET(gport) &&
  55008         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
  55009 
  55010         if(_bcm_xgs5_subport_coe_gport_local(unit, gport)) {
  55011             *is_local_subport = TRUE;
  55012         }
  55013 
  55014         if (*is_local_subport == FALSE) {
  55015             return BCM_E_PORT;
  55016         }
  55017 
  55018         BCM_IF_ERROR_RETURN(
  55019             _bcmi_coe_subport_physical_port_get(unit, gport, phy_port));
  55020     } else if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  55021                 soc_feature(unit, soc_feature_channelized_switching)) &&
  55022                _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) {
  55023         *is_local_subport = TRUE;
  55024         BCM_IF_ERROR_RETURN(
  55025             _bcmi_coe_subport_mod_port_physical_port_get(
  55026                 unit, modid, port, phy_port));
  55027     } else
  55028 #endif
  55029 
  55030 #if defined(BCM_KATANA2_SUPPORT)
  55031     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  55032         soc_feature(unit, soc_feature_subtag_coe)) {
  55033         if (BCM_GPORT_IS_SET(gport) &&
  55034             _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) {
  55035             pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport);
  55036             if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) ||
  55037                 (soc_feature(unit, soc_feature_general_cascade) &&
  55038                  SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) {
  55039 #if defined BCM_METROLITE_SUPPORT
  55040                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  55041                     if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  55042                         *is_local_subport = TRUE;
  55043                         *phy_port = pp_port;
  55044                     }
  55045                 } else
  55046 #endif
  55047                 {
  55048                     if ((pp_port >= min_subport) &&
  55049                         (pp_port <= max_subport)) {
  55050                         *is_local_subport = TRUE;
  55051                         *phy_port = pp_port;
  55052                     }
  55053                 }
  55054             }
  55055             if (*is_local_subport == FALSE) {
  55056                 return BCM_E_PORT;
  55057             }
  55058         }
  55059     } else
  55060 #endif
  55061     {
  55062         return BCM_E_NONE;
  55063     }
  55064 
  55065     return BCM_E_NONE;
  55066 }
  55067 
  55068 /*
  55069  * Function:
  55070  *      _bcm_esw_port_gport_get_from_modport
  55071  * Purpose:
  55072  *      Get a gport for all port.
  55073  *      For non-COE port, it returns modport gport.
  55074  *      For COE subport, it returns Coe subport gport.
  55075  * Parameters:
  55076  *      unit  - (IN) Unit number.
  55077  *      modid - (IN) Module id.
  55078  *      port  - (IN) Port id.
  55079  * Returns:
  55080  *      gport
  55081  * Notes:
  55082  */
  55083 bcm_gport_t
  55084 _bcm_esw_port_gport_get_from_modport(int unit, bcm_module_t modid, bcm_port_t port)
  55085 {
  55086     bcm_gport_t gport;
  55087 
  55088 #if defined(BCM_HGPROXY_COE_SUPPORT)
  55089     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  55090         soc_feature(unit, soc_feature_channelized_switching)) &&
  55091         _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) {
  55092         _BCM_SUBPORT_COE_PORT_ID_SET(gport, modid, port);
  55093         _BCM_SUBPORT_COE_PORT_TYPE_SET(gport,_BCM_SUBPORT_COE_TYPE_SUBTAG);
  55094     } else
  55095 #endif
  55096     {
  55097         BCM_GPORT_MODPORT_SET(gport, modid, port);
  55098     }
  55099 
  55100     return gport;
  55101 }
  55102 
  55103 /* Check if a given port is a valid controlling port for the Flex-port
  55104    feature.
  55105 */
  55106 
  55107 unsigned
  55108 _bcm_esw_valid_flex_port_controlling_port(int unit, bcm_port_t port)
  55109 {
  55110     uint16 dev_id;
  55111     uint8  rev_id;
  55112 
  55113     if (!SOC_PORT_VALID(unit, port))  return (FALSE);
  55114 
  55115     soc_cm_get_id(unit, &dev_id, &rev_id);
  55116 
  55117     if (dev_id == BCM56636_DEVICE_ID) {
  55118         /* Device is a BCM56636 */
  55119 
  55120         /* Only valid controlling ports are 42 and 50
  55121 	   (ports 30, 34 and 38 come up in gigE, and
  55122 	   therefore are not valid Flex-port controlling ports).
  55123 	*/
  55124 
  55125         if (port != 42 && port != 50)  return (FALSE);
  55126     } else
  55127 #if defined(BCM_METROLITE_SUPPORT)
  55128         if (SOC_IS_METROLITE(unit)) {
  55129             if ((port != 1) && (port != 5) && (port != 9)) {
  55130                 return (FALSE);
  55131             }
  55132         } else
  55133 #endif
  55134 #if defined(BCM_SABER2_SUPPORT)
  55135     if (SOC_IS_SABER2(unit)) {
  55136          if ((port != 1) && (port != 5) && (port != 9)
  55137              && (port != 13) && (port != 17) && (port != 21)
  55138              && (port != 25)) {
  55139              return (FALSE);
  55140          }
  55141     } else
  55142 #endif
  55143 #if defined(BCM_KATANA2_SUPPORT)
  55144      if (SOC_IS_KATANA2(unit)) {
  55145          if ((port != 1) && (port != 5) && (port != 9)
  55146              && (port != 13) && (port != 17) && (port != 21)
  55147              && (port != 25) && (port != 26) && (port != 27)
  55148              && (port != 28)) {
  55149              return (FALSE);
  55150          }
  55151      } else
  55152 #endif
  55153      {
  55154         if ((port != 30) && (port != 34) && (port != 38)
  55155   	         && (port != 42) && (port != 46) && (port != 50)) {
  55156              return (FALSE);
  55157 	    }
  55158     }
  55159     return (TRUE);
  55160 }
  55161 
  55162 
  55163 /*
  55164  * Function:
  55165  *      bcm_port_subsidiary_ports_get
  55166  * Purpose:
  55167  *      Given a controlling port, this API returns the set of ancillary ports
  55168  *      belonging to the group (port block) that can be configured to operate
  55169  *      either as a single high-speed port or multiple GE ports. If the input
  55170  *      port is not a controlling port, BCM_E_PORT error will be returned.
  55171  * Parameters:
  55172  *      unit - (IN) Unit number.
  55173  *      port - (IN) Port
  55174  *      pbmp - (OUT) Ports associated with the hot-swap group
  55175  * Returns:
  55176  *      BCM_E_XXX
  55177  * Notes:
  55178  */
  55179 int
  55180 bcm_esw_port_subsidiary_ports_get(int unit, bcm_port_t port, bcm_pbmp_t *pbmp)
  55181 {
  55182     int rv = BCM_E_UNAVAIL;
  55183 
  55184     /* Make sure port module is initialized. */
  55185     PORT_INIT(unit);
  55186 
  55187     if (!soc_feature(unit, soc_feature_flex_port)) {
  55188         return BCM_E_UNAVAIL;
  55189     }
  55190 
  55191 #if defined(BCM_TRIDENT3_SUPPORT)
  55192     if (SOC_IS_TRIDENT3X(unit)) {
  55193         return (soc_td3_subsidiary_ports_get(unit, port, pbmp));
  55194     }
  55195 #endif
  55196 #if defined(BCM_TOMAHAWK_SUPPORT)
  55197     if (SOC_IS_TOMAHAWKX(unit)) {
  55198         return (soc_th_subsidiary_ports_get(unit, port, pbmp));
  55199     }
  55200 #endif
  55201 #if defined(BCM_MONTEREY_SUPPORT)
  55202     if (SOC_IS_MONTEREY(unit)) {
  55203         return (soc_monterey_subsidiary_ports_get(unit, port, pbmp));
  55204     }
  55205 #endif
  55206 #if defined(BCM_APACHE_SUPPORT)
  55207     if (SOC_IS_APACHE(unit)) {
  55208         return (soc_apache_subsidiary_ports_get(unit, port, pbmp));
  55209     }
  55210 #endif
  55211 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  55212     if (SOC_IS_TRIDENT2PLUS(unit)) {
  55213         return(soc_td2p_subsidiary_ports_get(unit, port, pbmp));
  55214     }
  55215 #endif
  55216 
  55217 #if defined(BCM_TRIDENT2_SUPPORT)
  55218     if (SOC_IS_TD2_TT2(unit)) {
  55219         soc_info_t *si = &SOC_INFO(unit);
  55220         int i, port_num_lanes_max;
  55221         int phy_port, phy_port_base, port_base, lp;
  55222         bcm_pbmp_t pbm;
  55223 
  55224         if (!SOC_PORT_VALID(unit, port)) {
  55225             return BCM_E_PORT;
  55226         }
  55227         /* coverity[overrun-local : FALSE] */
  55228         phy_port = si->port_l2p_mapping[port];
  55229         if (phy_port == -1) {
  55230             return BCM_E_PORT;
  55231         }
  55232 
  55233         phy_port_base = (phy_port & ~0x3) + 1;
  55234         if (phy_port != phy_port_base) {
  55235             return BCM_E_PORT;
  55236         }
  55237 
  55238         port_base = si->port_p2l_mapping[phy_port_base];
  55239 
  55240         if (si->port_speed_max[port_base] > 20000) {
  55241             port_num_lanes_max = 4;
  55242         } else if (si->port_speed_max[port_base] > 10000) {
  55243             port_num_lanes_max = 2;
  55244         } else {
  55245             port_num_lanes_max = 1;
  55246         }
  55247 
  55248         BCM_PBMP_CLEAR(pbm);
  55249         /* Get the subsidiary ports bitmap */
  55250         for (i = 1; i < port_num_lanes_max; i++) {
  55251             lp = si->port_p2l_mapping[phy_port_base + i];
  55252             if (lp != -1
  55253                 && BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  55254                 BCM_PBMP_PORT_ADD(pbm, lp);
  55255             }
  55256         }
  55257 
  55258         if (BCM_PBMP_IS_NULL(pbm)) { /* No Subsidiary ports */
  55259             return BCM_E_PORT;
  55260         }
  55261 
  55262         /* Add base port to subsidiary ports bitmap */
  55263         BCM_PBMP_PORT_ADD(pbm, port_base);
  55264         BCM_PBMP_ASSIGN(*pbmp, pbm);
  55265 
  55266         rv = BCM_E_NONE;
  55267     }
  55268 #endif /* BCM_TRIDENT2_SUPPORT */
  55269 
  55270 #if defined(BCM_TRIUMPH3_SUPPORT)
  55271     if (SOC_IS_TRIUMPH3(unit)) {
  55272         soc_info_t *si = &SOC_INFO(unit);
  55273         int i, phy_port, phy_port_base, lp;
  55274         bcm_pbmp_t pbm;
  55275 
  55276         BCM_PBMP_CLEAR(pbm);
  55277 
  55278         if ( !(IS_XW_PORT(unit,port) || IS_CL_PORT(unit, port) || IS_XT_PORT(unit,port)) ||
  55279              !_bcm_tr3_port_is_control_port(unit, port) || !soc_tr3_port_is_flex_port(unit, port)) {
  55280             return BCM_E_PORT;
  55281         }
  55282         /* coverity[overrun-local : FALSE] */
  55283         phy_port = si->port_l2p_mapping[port];
  55284         if (phy_port == -1) {
  55285             return BCM_E_PORT;
  55286         }
  55287         phy_port_base = (phy_port & ~0x3) + 1;
  55288         if (phy_port != phy_port_base) {
  55289             return BCM_E_PORT;
  55290         }
  55291         BCM_PBMP_CLEAR(pbm);
  55292         for (i = 0; i < _SOC_TR3_LANES_PER_PHY; i++) {
  55293             /* coverity[overrun-local : FALSE] */
  55294             lp = si->port_p2l_mapping[phy_port_base + i];
  55295             if (lp != -1 &&
  55296                 (si->port_speed_max[lp] != 0) &&
  55297                 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  55298                 BCM_PBMP_PORT_ADD(pbm, lp);
  55299             }
  55300         }
  55301 
  55302 
  55303         BCM_PBMP_ASSIGN(*pbmp, pbm);
  55304         return BCM_E_NONE;
  55305     }
  55306 #endif /* BCM_TRIUMPH3_SUPPORT */
  55307 
  55308 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  55309     if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  55310         !SOC_IS_TD_TT(unit)) {
  55311         int i;
  55312 
  55313         if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) {
  55314             return (BCM_E_PORT);
  55315         }
  55316 
  55317         BCM_PBMP_CLEAR(*pbmp);
  55318         if ((SOC_IS_KATANA2(unit)) && (!SOC_IS_SABER2(unit))) {
  55319             if (port == 25) {
  55320                 BCM_PBMP_PORT_ADD(*pbmp, 25);
  55321                 for (i = 0; i < 3; i++) {
  55322                     if(SOC_PORT_VALID(unit, 35 + i)) {
  55323                         BCM_PBMP_PORT_ADD(*pbmp, 35 + i);
  55324                     }
  55325                 }
  55326                 return (BCM_E_NONE);
  55327              } else if (port == 26) {
  55328                  BCM_PBMP_PORT_ADD(*pbmp, 26);
  55329                  for (i = 0; i < 3; i++) {
  55330                       if(SOC_PORT_VALID(unit, 38 + i)) {
  55331                          BCM_PBMP_PORT_ADD(*pbmp, 38 + i);
  55332                       }
  55333                  }
  55334                  return (BCM_E_NONE);
  55335              } else if (port == 27) {
  55336                  BCM_PBMP_PORT_ADD(*pbmp, 27);
  55337                  for (i = 0; i < 3; i++) {
  55338                       if(SOC_PORT_VALID(unit, 32 + i)) {
  55339                          BCM_PBMP_PORT_ADD(*pbmp, 32 + i);
  55340                       }
  55341                  }
  55342                  return (BCM_E_NONE);
  55343              }
  55344         }
  55345 
  55346         for (i = 0; i < 4; i++) {
  55347             /* coverity[overrun-local : FALSE] */
  55348             if (SOC_PORT_VALID(unit, port + i)) {
  55349                 BCM_PBMP_PORT_ADD(*pbmp, port + i);
  55350             }
  55351         }
  55352         rv = BCM_E_NONE;
  55353     }
  55354 #endif
  55355 
  55356     return rv;
  55357 }
  55358 
  55359 /*
  55360  * Function:
  55361  *      _bcm_esw_port_e2ecc_hg_pbm_convert
  55362  * Purpose:
  55363  *      Convert Higig port to E2ECC Higig port bitmap.
  55364  * Parameters:
  55365  *      port - (IN) Higig port number.
  55366  *      converted_hg_pbm - (OUT) Converted Higig port bitmap.
  55367  * Returns:
  55368  *      BCM_E_xxx
  55369  */
  55370 STATIC int
  55371 _bcm_esw_port_e2ecc_hg_pbm_convert(bcm_port_t port, uint32 *converted_hg_pbm)
  55372 {
  55373     int    hg_pbm_index;
  55374 
  55375     /* In Triumph2, the mapping between HG_PBM[9:0] and physical port number is:
  55376      *
  55377      * HG_PBM index:  |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
  55378      * Physical Port: | 50 | 46 | 42 | 38 | 34 | 30 | 29 | 28 | 27 | 26 |
  55379      */
  55380     switch (port)
  55381     {
  55382         case 26:
  55383         case 27:
  55384         case 28:
  55385         case 29:
  55386         case 30:
  55387             hg_pbm_index = port - 26;
  55388             break;
  55389         case 34:
  55390         case 38:
  55391         case 42:
  55392         case 46:
  55393         case 50:
  55394             hg_pbm_index = 5 + (port - 34) / 4;
  55395             break;
  55396         default:
  55397             LOG_ERROR(BSL_LS_BCM_PORT,
  55398                       (BSL_META("Error: Port %d is an invalid Higig port"), port));
  55399             return BCM_E_PARAM;
  55400     }
  55401 
  55402     *converted_hg_pbm = (1 << hg_pbm_index);
  55403 
  55404     return BCM_E_NONE;
  55405 }
  55406 
  55407 STATIC int
  55408 _bcm_esw_port_drop_status_enable_set(int unit, bcm_port_t port, int enable)
  55409 {
  55410     uint32 rval;
  55411     int idx;
  55412 
  55413 #if defined(BCM_MONTEREY_SUPPORT)
  55414     if (SOC_IS_MONTEREY(unit)) {
  55415         return bcm_mn_cosq_drop_status_enable_set(unit, port, enable);
  55416     }
  55417 #endif /* BCM_TRIDENT2_SUPPORT */
  55418 #if defined(BCM_APACHE_SUPPORT)
  55419     if (SOC_IS_APACHE(unit)) {
  55420         return bcm_ap_cosq_drop_status_enable_set(unit, port, enable);
  55421     }
  55422 #endif /* BCM_TRIDENT2_SUPPORT */
  55423 #if defined(BCM_TRIDENT2_SUPPORT)
  55424     if (SOC_IS_TD2_TT2(unit)) {
  55425         return bcm_td2_cosq_drop_status_enable_set(unit, port, enable);
  55426     }
  55427 #endif /* BCM_TRIDENT2_SUPPORT */
  55428 
  55429 #if defined(BCM_TRIDENT_SUPPORT)
  55430     if (SOC_IS_TD_TT(unit)) {
  55431         return bcm_td_cosq_drop_status_enable_set(unit, port, enable);
  55432     }
  55433 #endif /* BCM_TRIDENT_SUPPORT */
  55434 
  55435 #if defined(BCM_TRIUMPH3_SUPPORT)
  55436     if (SOC_IS_TRIUMPH3(unit)) {
  55437         return bcm_tr3_cosq_drop_status_enable_set(unit, port, enable);
  55438     }
  55439 #endif /* BCM_TRIUMPH3_SUPPORT */
  55440 
  55441 #if defined(BCM_KATANA_SUPPORT)
  55442     if (SOC_IS_KATANA(unit)) {
  55443         return bcm_kt_cosq_drop_status_enable_set(unit, port, enable);
  55444     }
  55445 #endif /* BCM_KATANA_SUPPORT */
  55446 #if defined(BCM_KATANA2_SUPPORT)
  55447     if (SOC_IS_KATANA2(unit)) {
  55448         return bcm_kt2_cosq_drop_status_enable_set(unit, port, enable);
  55449     }
  55450 #endif /* BCM_KATANA2_SUPPORT */
  55451 #if defined(BCM_HURRICANE3_SUPPORT)
  55452     if (SOC_IS_HURRICANE3(unit)) {
  55453         return bcm_hr3_cosq_drop_status_enable_set(unit, port, enable);
  55454     }
  55455 #endif /* BCM_HURRICANE3_SUPPORT */
  55456 #if defined(BCM_GREYHOUND2_SUPPORT)
  55457     if (SOC_IS_GREYHOUND2(unit)) {
  55458         return bcmi_gh2_cosq_drop_status_enable_set(unit, port, enable);
  55459     }
  55460 #endif /* BCM_GREYHOUND2_SUPPORT */
  55461 
  55462     for (idx = 0; idx < 8; idx++) {
  55463         if (SOC_IS_SC_CQ(unit)) {
  55464             SOC_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIGr(unit, port, idx, &rval));
  55465             soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval,
  55466                               Q_E2E_DS_ENABLEf, enable ? 1 : 0);
  55467             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIGr(unit, port, idx, rval));
  55468         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  55469                    SOC_IS_VALKYRIE2(unit)) {
  55470             SOC_IF_ERROR_RETURN
  55471                 (READ_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, &rval));
  55472             soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
  55473                               Q_E2E_DS_EN_CELLf, enable ? 1 : 0);
  55474             SOC_IF_ERROR_RETURN
  55475                 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval));
  55476 
  55477             SOC_IF_ERROR_RETURN
  55478                 (READ_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, &rval));
  55479             soc_reg_field_set(unit, OP_QUEUE_CONFIG1_PACKETr, &rval,
  55480                               Q_E2E_DS_EN_PACKETf, enable ? 1 : 0);
  55481             SOC_IF_ERROR_RETURN
  55482                 (WRITE_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, rval));
  55483         }
  55484     }
  55485 
  55486     SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &rval));
  55487     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, EARLY_E2E_SELECTf,
  55488                       enable ? 1 : 0);
  55489     SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval));
  55490 
  55491     return BCM_E_NONE;
  55492 }
  55493 
  55494 /*
  55495  * Function:
  55496  *     _bcm_esw_port_e2e_tx_enable_set
  55497  * Purpose:
  55498  *      Set E2E Tx Enable
  55499  * Parameters:
  55500  *      unit - (IN) SOC unit number.
  55501  *      port - (IN) Port number.
  55502  *      enable - (IN) Whether to enable or disable
  55503  * Returns:
  55504  *      BCM_E_xxx
  55505  */
  55506 STATIC int
  55507 _bcm_esw_port_e2e_tx_enable_set(int unit, bcm_port_t port, int enable)
  55508 {
  55509     uint64 rval64;
  55510 
  55511     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  55512         return bcmi_esw_portctrl_e2e_tx_enable_set(unit, port, enable);
  55513     }
  55514 
  55515     if (IS_CL_PORT(unit, port)) {
  55516         SOC_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &rval64));
  55517         soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, &rval64,
  55518                 E2E_ENABLEf, enable);
  55519         SOC_IF_ERROR_RETURN(WRITE_CLMAC_E2E_CTRLr(unit, port, rval64));
  55520     } else {
  55521         SOC_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &rval64));
  55522         soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, &rval64,
  55523                 E2E_ENABLEf, enable);
  55524         SOC_IF_ERROR_RETURN(WRITE_XLMAC_E2E_CTRLr(unit, port, rval64));
  55525     }
  55526     return BCM_E_NONE;
  55527 }
  55528 
  55529 /*
  55530  * Function:
  55531  *      _bcm_esw_port_e2ecc_tx
  55532  * Purpose:
  55533  *      Configure E2ECC message transmission.
  55534  * Parameters:
  55535  *      unit - (IN) Unit number.
  55536  *      port - (IN) Local port number.
  55537  *      config - (IN) Congestion configuration.
  55538  * Returns:
  55539  *      BCM_E_xxx
  55540  */
  55541 STATIC int
  55542 _bcm_esw_port_e2ecc_tx(int unit, bcm_port_t port,
  55543                        bcm_port_congestion_config_t *config)
  55544 {
  55545     uint32 regval;
  55546     uint32 hg_pbm, converted_hg_pbm, new_hg_pbm;
  55547     int    value_a, value_b;
  55548     int    time_unit_sel, time_units;
  55549     int    src_modid, src_pid;
  55550     soc_higig_e2ecc_hdr_t e2ecc_hdr;
  55551     int blk, blk_num = -1, bindex = 0;
  55552     if (config->flags & BCM_PORT_CONGESTION_CONFIG_TX) {
  55553         /* If BCM_PORT_CONGESTION_CONFIG_TX flag is set, enable E2ECC transmission. */
  55554 
  55555         /* Set chip-wide E2ECC enable bit */
  55556         if (SOC_IS_SC_CQ(unit)) {
  55557             SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, &regval));
  55558             if (soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf) == 0) {
  55559                 soc_reg_field_set(unit, E2E_HOL_ENr, &regval, ENf, 1);
  55560                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_ENr(unit, regval));
  55561             }
  55562         } else {
  55563             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, &regval));
  55564             if (soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf) == 0) {
  55565                 soc_reg_field_set(unit, E2ECC_HOL_ENr, &regval, ENf, 1);
  55566                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_ENr(unit, regval));
  55567             }
  55568         }
  55569 
  55570 
  55571         /* In Trident E2E_HOL_ENf is not present. MMY E2ECC_HOL_EN is used */
  55572         /* (Checked with Architecture) */
  55573         if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
  55574             /* Set per-port E2ECC TX enable bit */
  55575             SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
  55576             if (soc_reg_field_get(unit, XPORT_CONFIGr,
  55577                                   regval, E2E_HOL_ENf) == 0) {
  55578                 soc_reg_field_set(unit, XPORT_CONFIGr, &regval,
  55579                                   E2E_HOL_ENf, 1);
  55580                 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval));
  55581             }
  55582         }
  55583 
  55584         if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) {
  55585             /* Set per-port E2ECC TX enable bit */
  55586             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &regval));
  55587             if (soc_reg_field_get(unit, XPORT_MODE_REGr,
  55588                                   regval, E2E_HOL_ENf) == 0) {
  55589                 soc_reg_field_set(unit, XPORT_MODE_REGr, &regval,
  55590                                   E2E_HOL_ENf, 1);
  55591                 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval));
  55592             }
  55593         }
  55594 
  55595         /* Set per-queue E2ECC enable bits */
  55596         BCM_IF_ERROR_RETURN
  55597             (_bcm_esw_port_drop_status_enable_set(unit, port, TRUE));
  55598 
  55599         /* Set the Higig port bitmap used to transmit E2ECC messages */
  55600         if (SOC_IS_SC_CQ(unit)) {
  55601             SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, &regval));
  55602             hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf);
  55603 
  55604             converted_hg_pbm = 1 << port;
  55605 
  55606             if (!(hg_pbm & converted_hg_pbm)) {
  55607                 new_hg_pbm = hg_pbm | converted_hg_pbm;
  55608                 soc_reg_field_set(unit, E2E_HOL_PBMr, &regval, PORT_BITMAPf, new_hg_pbm);
  55609                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval));
  55610             }
  55611         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  55612                    SOC_IS_VALKYRIE2(unit)) {
  55613             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, &regval));
  55614             hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf);
  55615 
  55616             SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm));
  55617 
  55618             if (!(hg_pbm & converted_hg_pbm)) {
  55619                 new_hg_pbm = hg_pbm | converted_hg_pbm;
  55620                 soc_reg_field_set(unit, E2ECC_HOL_PBMr, &regval, HG_PBMf, new_hg_pbm);
  55621                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval));
  55622             }
  55623         } else { /* TD_TT, KATANAX, TR3 */
  55624             if (soc_feature(unit, soc_feature_logical_port_num)) {
  55625                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  55626                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  55627             } else{
  55628                 blk = SOC_PORT_BLOCK(unit, port);
  55629                 bindex = SOC_PORT_BINDEX(unit, port);
  55630             }
  55631 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  55632             if (SOC_IS_TRIDENT2X(unit)) {
  55633                 blk_num = SOC_INFO(unit).port_serdes[port];
  55634             } else
  55635 #endif
  55636             {
  55637                 blk_num = SOC_BLOCK_INFO(unit, blk).number;
  55638             }
  55639             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  55640             if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  55641                 if (SOC_IS_TRIUMPH3(unit)) {
  55642                     if (IS_CL_PORT(unit, port)) {
  55643                         blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  55644                         bindex = bindex%4;
  55645                     } else {
  55646                         blk_num = 3;
  55647                     }
  55648                 }
  55649 #if defined(BCM_KATANA2_SUPPORT)
  55650                 if (SOC_IS_KATANA2(unit)) {
  55651                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  55652                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  55653                 }
  55654 #endif
  55655                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  55656                                                               &regval));
  55657                 if (!(regval & (1 << bindex))) {
  55658                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  55659                                                    TX_ENABLE_BMPf);
  55660                     /* new_hg_pbm &= ~(1 << bindex); */
  55661                     new_hg_pbm |= (1 << bindex);
  55662                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  55663                                       TX_ENABLE_BMPf, new_hg_pbm);
  55664                     SOC_IF_ERROR_RETURN
  55665                         (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval));
  55666                 }
  55667             }
  55668 
  55669 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  55670             if (SOC_IS_TD2_TT2(unit)) {
  55671                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  55672 
  55673                 /* DMVOQ congestion bytes max length is 64 bytes,
  55674                                As a result
  55675                  DMVOQ feature can support upto 64 ports*/
  55676                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, &regval));
  55677                 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, &regval,
  55678                         TX_PORTS_NUMf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  55679                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval));
  55680 
  55681                 /* By default congestion states of 4 cos values are transmitted
  55682                    inorder to transmit the congestion state for all the
  55683                    8 cos values
  55684                    if num_coq > 8 following configuration is done */
  55685                 if (!SOC_IS_TRIUMPH3(unit) && !SOC_IS_MONTEREY(unit) && NUM_COS(unit) >= 8) {
  55686                     uint64 rval64 ;
  55687                     uint64  fval64;
  55688                     COMPILER_64_ZERO(fval64);
  55689                     COMPILER_64_SET(fval64, 0xffffffff, 0xffffffff);
  55690                     soc_reg64_field_set(unit, OOBFC_ENG_PORT_QSEL0_64r ,
  55691                             &rval64,
  55692                             ENG_PORT_QSELf, fval64);
  55693                     SOC_IF_ERROR_RETURN(WRITE_OOBFC_ENG_PORT_QSEL0_64r(unit,
  55694                                 rval64));
  55695                 }
  55696             }
  55697 #endif
  55698 #if defined(BCM_HURRICANE3_SUPPORT)
  55699             if (SOC_IS_FIRELIGHT(unit)) {
  55700                 /* When in Chassis mode, _soc_firelight_mmu_init_helper_chassis()
  55701                 *  would set E2ECC_TX_PORTS_NUM the correct value. Leave it alone
  55702                 *  for firelight.
  55703                 */
  55704                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  55705             } else if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  55706                 uint32 max_bitmap;
  55707                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, &regval));
  55708                 /* max Congestion bitmap number of E2ECC message */
  55709                 if (SOC_IS_HURRICANE3(unit)) {
  55710                     max_bitmap = 36;
  55711                 } else { /* GREYHOUND2 */
  55712                     max_bitmap = 64;
  55713                 }
  55714                 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, &regval,
  55715                         TX_PORTS_NUMf, max_bitmap);
  55716                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval));
  55717 
  55718                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  55719             }
  55720 #endif
  55721 
  55722             if (SOC_IS_KATANAX(unit)) {
  55723                 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &regval));
  55724                 soc_reg_field_set(unit, OP_THR_CONFIGr, &regval, E2ECC_HOL_ENf, 1);
  55725                 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, regval));
  55726                 if (SOC_IS_SABER2(unit)) {
  55727                     SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  55728                 }
  55729             }
  55730         }
  55731 
  55732         /* Configuring the E2ECC min timer so that during congestion, back-to-back
  55733          * E2ECC messages are generated as fast as hardware allows.
  55734          */
  55735         if (SOC_IS_SC_CQ(unit)) {
  55736 
  55737             SOC_IF_ERROR_RETURN(READ_E2E_MIN_TX_TIMERr(unit, &regval));
  55738             if (soc_reg_field_get(unit, E2E_MIN_TX_TIMERr, regval, TIMERf) != 0) {
  55739                 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, &regval, TIMERf, 0);
  55740                 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, &regval, LGf, 0);
  55741                 SOC_IF_ERROR_RETURN(WRITE_E2E_MIN_TX_TIMERr(unit, regval));
  55742             }
  55743         } else {
  55744             SOC_IF_ERROR_RETURN(READ_E2ECC_MIN_TX_TIMERr(unit, &regval));
  55745             if (soc_reg_field_get(unit, E2ECC_MIN_TX_TIMERr, regval, TIMERf) != 0) {
  55746                 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, &regval, TIMERf, 0);
  55747                 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, &regval, LGf, 0);
  55748                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MIN_TX_TIMERr(unit, regval));
  55749             }
  55750         }
  55751 
  55752         /* In the absence of congestion, an E2ECC message is still generated to refresh
  55753          * congestion status when the E2ECC max timer expires. This timer is specified
  55754          * in units of 250ns or 25us, and up to 1023 time units can be specified.
  55755          * The selection of time unit and the number of time units is computed as follows:
  55756          *
  55757          * Let E2ECC message refresh rate = N messages/sec, and N != 0,
  55758          * then A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N,
  55759          * and B = # of 25us time units = 1 sec / N / 25us = 40000 / N = A / 100.
  55760          *
  55761          * If A < 1, configure the minimum allowed timer value: time unit = 250ns,
  55762          * # of time units = 1.
  55763          *
  55764          * If A is between 1 and 1023, configure the timer as: time unit = 250ns,
  55765          * # of time units = A.
  55766          *
  55767          * If A > 1023 and B <= 1023, configure the timer as: time unit = 25us,
  55768          * # of time units = B.
  55769          *
  55770          * If B > 1023, configure the maximum allowed timer value: time unit = 25us,
  55771          * # of time units = 1023.
  55772          *
  55773          * Note: If N = 0, # of time units will be set to 0, and E2ECC message refresh
  55774          *       is effectively disabled. E2ECC message will be generated only when
  55775          *       there is a change in congestion status.
  55776          */
  55777 
  55778         if (config->packets_per_sec == 0) {
  55779             time_unit_sel = 0;
  55780             time_units = 0;
  55781         } else {
  55782             value_a = 4000000 / config->packets_per_sec;
  55783             value_b = value_a / 100;
  55784             if (value_a < 1) {
  55785                 time_unit_sel = 0;
  55786                 time_units = 1;
  55787             } else if (value_a <= 1023) {
  55788                 time_unit_sel = 0;
  55789                 time_units = value_a;
  55790             } else if ((value_a > 1023) && (value_b <= 1023)) {
  55791                 time_unit_sel = 1;
  55792                 time_units = value_b;
  55793             } else { /* value_b > 1023 */
  55794                 time_unit_sel = 1;
  55795                 time_units = 1023;
  55796             }
  55797         }
  55798 
  55799         if (SOC_IS_SC_CQ(unit)) {
  55800             SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, &regval));
  55801             soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, &regval, LGf,
  55802                               time_unit_sel);
  55803             soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, &regval, TIMERf,
  55804                               time_units);
  55805             SOC_IF_ERROR_RETURN(WRITE_E2E_MAX_TX_TIMERr(unit, regval));
  55806         } else {
  55807             SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, &regval));
  55808             soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, &regval, LGf,
  55809                               time_unit_sel);
  55810             soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, &regval, TIMERf,
  55811                               time_units);
  55812             SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval));
  55813         }
  55814 
  55815         /* Configure per-port E2ECC message header */
  55816 #ifdef BCM_FIRELIGHT_SUPPORT
  55817         if (SOC_IS_FIRELIGHT(unit) && (!IS_HG_PORT(unit, port))) {
  55818             uint64 rval;
  55819 
  55820             if (!IS_CL_PORT(unit, port) && !IS_XL_PORT(unit, port)) {
  55821                 return BCM_E_UNAVAIL;
  55822             }
  55823 
  55824             if (IS_CL_PORT(unit, port)) {
  55825                 SOC_IF_ERROR_RETURN(READ_CLMAC_MODEr(unit, port, &rval));
  55826             } else {
  55827                 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval));
  55828             }
  55829             if (soc_reg64_field32_get(unit, CLMAC_MODEr, rval, HDR_MODEf)
  55830                 !=SOC_ENCAP_IEEE) {
  55831                 LOG_ERROR(BSL_LS_BCM_PORT,
  55832                              (BSL_META_U(unit,
  55833                           "Error: unit %d port %d is not a Higig port. "
  55834                           "HDR_MODE of XL or CL port should be configured "
  55835                           "with IEEE Ethernet format.\n"),
  55836                           unit, port));
  55837                 return BCM_E_UNAVAIL;
  55838             }
  55839 
  55840             sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
  55841 
  55842             e2ecc_hdr.overlay1.words[0] =
  55843                         (config->dest_mac[0] << 24) |                  /* MAC-DA[47:40] */
  55844                         (config->dest_mac[1] << 16) |                  /* MAC-DA[39:32] */
  55845                         (config->dest_mac[2] << 8) |                   /* MAC-DA[31:24] */
  55846                         (config->dest_mac[3]);                         /* MAC-DA[23:16] */
  55847 
  55848             e2ecc_hdr.overlay1.words[1] =
  55849                         (config->dest_mac[4] << 24) |                  /* MAC-DA[15:8] */
  55850                         (config->dest_mac[5] << 16) |                  /* MAC-DA[7:0] */
  55851                         (config->src_mac[0] << 8) |                    /* MAC-SA[47:40] */
  55852                         (config->src_mac[1]);                          /* MAC-SA[39:32] */
  55853 
  55854             e2ecc_hdr.overlay1.words[2] =
  55855                         (config->src_mac[2] << 24) |                   /* MAC-SA[31:24] */
  55856                         (config->src_mac[3] << 16) |                   /* MAC-SA[23:16] */
  55857                         (config->src_mac[4] << 8) |                    /* MAC-SA[15:8] */
  55858                         (config->src_mac[5]);                          /* MAC-SA[7:0] */
  55859 
  55860             /* SVTAG for E2ECC on ethernet port is fixed to be 0xff0008ff
  55861              * SVTAG Signature = 0xFF
  55862              * MACSEC Error Code = 0x00
  55863              * PRI = 0
  55864              * CPU = 0            ,CPU = 0 should be set for all control packets
  55865              * PKT_TYPE = 2b10    ,control packet
  55866              * RSVD = 0
  55867              * Channel # = 0xFF
  55868              */
  55869             e2ecc_hdr.overlay1.words[3] = 0xff0008ff;
  55870             e2ecc_hdr.overlay1.words[4] =
  55871                 ((config->ethertype & 0xFFFF) << 16) |      /* Ethertype[15:0] */
  55872                 (config->opcode & 0xFFFF);                  /* Opcode[7:0] */
  55873             e2ecc_hdr.overlay1.words[5] = 0;
  55874             e2ecc_hdr.overlay1.words[6] = 0;
  55875             e2ecc_hdr.overlay1.words[7] = 0;
  55876         } else
  55877 #endif /* BCM_FIRELIGHT_SUPPORT */
  55878         {
  55879             if (BCM_GPORT_IS_MODPORT(config->src_port)) {
  55880                 src_modid = BCM_GPORT_MODPORT_MODID_GET(config->src_port);
  55881                 src_pid = BCM_GPORT_MODPORT_PORT_GET(config->src_port);
  55882             } else {
  55883                 LOG_ERROR(BSL_LS_BCM_PORT,
  55884                           (BSL_META_U(unit,
  55885                                       "Error: src_port %d is not of type modid:port.\n"), config->src_port));
  55886                 return BCM_E_PARAM;
  55887             }
  55888 
  55889             sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
  55890 
  55891             e2ecc_hdr.overlay1.words[0] =
  55892                         (SOC_HIGIG_START << 24) |                              /* K.SOP[7:0] */
  55893                         (((1 << 4) | (config->traffic_class & 0x0F)) << 16) |  /* MC and TC[3:0] */
  55894                         (config->multicast_id & 0xFFFF);                       /* MGID[15:0] */
  55895 
  55896             e2ecc_hdr.overlay1.words[1] =
  55897                         ((src_modid & 0xFF) << 24) |                           /* SRC_MODID[7:0] */
  55898                         ((src_pid & 0xFF) << 16) |                             /* SRC_PID[7:0] */
  55899                         ((config->color & 0x03) << 6);                         /* DP[1:0] */
  55900 
  55901             /* e2ecc_hdr.overlay1.words[2] is all zeroes. */
  55902 
  55903             if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) {
  55904                 /* In case of DMVOQ, we are sending opcode as Multicast
  55905                    so that packet is accepted at different modules */
  55906                 e2ecc_hdr.overlay1.words[3] =
  55907                     ((config->pri & 0x07) << 29) |   /* VID_HIGH[7:5] */
  55908                     ((config->cfi & 0x01) << 28) |   /* VID_HIGH[4] */
  55909                     ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */
  55910                     ((SOC_HIGIG_OP_MC & 0x07) << 8);  /* OPCODE[2:0] */
  55911             } else {
  55912                 e2ecc_hdr.overlay1.words[3] =
  55913                     ((config->pri & 0x07) << 29) |   /* VID_HIGH[7:5] */
  55914                     ((config->cfi & 0x01) << 28) |   /* VID_HIGH[4] */
  55915                     ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */
  55916                     ((SOC_HIGIG_OP_BC & 0x07) << 8);  /* OPCODE[2:0] */
  55917             }
  55918 
  55919             e2ecc_hdr.overlay1.words[4] =
  55920                         (config->dest_mac[0] << 24) |                          /* MAC-DA[47:40] */
  55921                         (config->dest_mac[1] << 16) |                          /* MAC-DA[39:32] */
  55922                         (config->dest_mac[2] << 8) |                           /* MAC-DA[31:24] */
  55923                         (config->dest_mac[3]);                                 /* MAC-DA[23:16] */
  55924 
  55925             e2ecc_hdr.overlay1.words[5] =
  55926                         (config->dest_mac[4] << 24) |                          /* MAC-DA[15:8] */
  55927                         (config->dest_mac[5] << 16) |                          /* MAC-DA[7:0] */
  55928                         (config->src_mac[0] << 8) |                            /* MAC-SA[47:40] */
  55929                         (config->src_mac[1]);                                  /* MAC-SA[39:32] */
  55930 
  55931             e2ecc_hdr.overlay1.words[6] =
  55932                         (config->src_mac[2] << 24) |                           /* MAC-SA[31:24] */
  55933                         (config->src_mac[3] << 16) |                           /* MAC-SA[23:16] */
  55934                         (config->src_mac[4] << 8) |                            /* MAC-SA[15:8] */
  55935                         (config->src_mac[5]);                                  /* MAC-SA[7:0] */
  55936 
  55937             e2ecc_hdr.overlay1.words[7] =
  55938                         ((config->ethertype & 0xFFFF) << 16) |                 /* Ethertype[15:0] */
  55939                         (config->opcode & 0xFFFF);                             /* Opcode[7:0] */
  55940         }
  55941 
  55942         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr));
  55943 
  55944         /* Enable QE interop mode */
  55945         if (SOC_IS_SC_CQ(unit)) {
  55946             SOC_IF_ERROR_RETURN(READ_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, &regval));
  55947             if (soc_reg_field_get(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, regval,
  55948                                   GLOBAL_SHARED_FILL_STATE_ENf) == 0) {
  55949                 soc_reg_field_set(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, &regval,
  55950                                   GLOBAL_SHARED_FILL_STATE_ENf, 1);
  55951                 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, regval));
  55952             }
  55953         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) {
  55954             SOC_IF_ERROR_RETURN(READ_QE_INTEROP_CONFIGr(unit, &regval));
  55955             if (soc_reg_field_get(unit, QE_INTEROP_CONFIGr, regval, QE_INTEROP_ENf) == 0) {
  55956                 soc_reg_field_set(unit, QE_INTEROP_CONFIGr, &regval, QE_INTEROP_ENf, 1);
  55957                 SOC_IF_ERROR_RETURN(WRITE_QE_INTEROP_CONFIGr(unit, regval));
  55958             }
  55959         } else if (SOC_IS_TD2_TT2(unit)) {
  55960             SOC_IF_ERROR_RETURN
  55961                 (soc_reg_field32_modify(unit,
  55962                                         INTFO_E2ECC_POOL_STATE_REPORT_ENABLEr,
  55963                                         REG_PORT_ANY, ENf, 1));
  55964         } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  55965             SOC_IF_ERROR_RETURN(READ_THDO_INTEROP_CONFIGr(unit, &regval));
  55966             if (soc_reg_field_get(unit, THDO_INTEROP_CONFIGr, regval,
  55967                                   GLOBAL_CNG_STATE_REPORT_ENABLEf) == 0) {
  55968                 soc_reg_field_set(unit, THDO_INTEROP_CONFIGr, &regval,
  55969                                   GLOBAL_CNG_STATE_REPORT_ENABLEf, 1);
  55970                 SOC_IF_ERROR_RETURN(WRITE_THDO_INTEROP_CONFIGr(unit, regval));
  55971             }
  55972         }
  55973 
  55974     } else {
  55975         /* If BCM_PORT_CONGESTION_CONFIG_TX flag is not set, disable E2ECC transmission. */
  55976 
  55977         if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
  55978             /* Clear per-port E2ECC TX enable bit */
  55979             SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
  55980             if (soc_reg_field_get(unit, XPORT_CONFIGr, regval, E2E_HOL_ENf) == 1) {
  55981                 soc_reg_field_set(unit, XPORT_CONFIGr, &regval, E2E_HOL_ENf, 0);
  55982                 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval));
  55983             }
  55984         }
  55985 
  55986         if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) {
  55987             /* Clear per-port E2ECC TX enable bit */
  55988             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &regval));
  55989             if (soc_reg_field_get(unit, XPORT_MODE_REGr, regval, E2E_HOL_ENf) == 1) {
  55990                 soc_reg_field_set(unit, XPORT_MODE_REGr, &regval, E2E_HOL_ENf, 0);
  55991                 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval));
  55992             }
  55993         }
  55994 
  55995         /* Clear per-queue E2ECC enable bits */
  55996         BCM_IF_ERROR_RETURN
  55997             (_bcm_esw_port_drop_status_enable_set(unit, port, FALSE));
  55998 
  55999         /* Clear the bit corresponding to the given Higig port in the Higig port bitmap
  56000          * used to transmit E2ECC messages
  56001          */
  56002         if (SOC_IS_SC_CQ(unit)) {
  56003             SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, &regval));
  56004             hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf);
  56005 
  56006             converted_hg_pbm = 1 << port;
  56007 
  56008             if (hg_pbm & converted_hg_pbm) {
  56009                 new_hg_pbm = hg_pbm & ~converted_hg_pbm;
  56010                 soc_reg_field_set(unit, E2E_HOL_PBMr, &regval, PORT_BITMAPf, new_hg_pbm);
  56011                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval));
  56012             }
  56013         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) {
  56014             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, &regval));
  56015             hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf);
  56016 
  56017             SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm));
  56018 
  56019             if (hg_pbm & converted_hg_pbm) {
  56020                 new_hg_pbm = hg_pbm & ~converted_hg_pbm;
  56021                 soc_reg_field_set(unit, E2ECC_HOL_PBMr, &regval, HG_PBMf, new_hg_pbm);
  56022                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval));
  56023             }
  56024         } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  56025                    SOC_IS_TRIUMPH3(unit) || SOC_IS_HURRICANE3(unit) ||
  56026                    SOC_IS_GREYHOUND2(unit)) {
  56027             if (soc_feature(unit, soc_feature_logical_port_num)) {
  56028                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  56029                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  56030             } else{
  56031                 blk = SOC_PORT_BLOCK(unit, port);
  56032                 bindex = SOC_PORT_BINDEX(unit, port);
  56033             }
  56034 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  56035            if (SOC_IS_TRIDENT2X(unit)) {
  56036                blk_num = SOC_INFO(unit).port_serdes[port];
  56037             } else
  56038 #endif
  56039             {
  56040               blk_num = SOC_BLOCK_INFO(unit, blk).number;
  56041             }
  56042             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  56043             if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  56044                 if (SOC_IS_TRIUMPH3(unit)) {
  56045                     if (IS_CL_PORT(unit, port)) {
  56046                         blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  56047                         bindex = bindex%4;
  56048                     } else {
  56049                         blk_num = 3;
  56050                     }
  56051                 }
  56052 #if defined(BCM_KATANA2_SUPPORT)
  56053                 if (SOC_IS_KATANA2(unit)) {
  56054                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  56055                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  56056                     if (SOC_IS_SABER2(unit)) {
  56057                         SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0));
  56058                     }
  56059                 }
  56060 #endif
  56061                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  56062                                                               &regval));
  56063                 if (regval & (1 << bindex)) {
  56064                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  56065                                                    TX_ENABLE_BMPf);
  56066                     new_hg_pbm &= ~(1 << bindex);
  56067                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  56068                                       TX_ENABLE_BMPf, new_hg_pbm);
  56069                     SOC_IF_ERROR_RETURN
  56070                         (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval));
  56071                 }
  56072             }
  56073 
  56074             if (SOC_IS_TD2_TT2(unit) || SOC_IS_HURRICANE3(unit) ||
  56075                 SOC_IS_GREYHOUND2(unit)) {
  56076                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0));
  56077             }
  56078         }
  56079 
  56080         /* Clear per-port registers holding the E2ECC message header */
  56081         sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
  56082         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr));
  56083     }
  56084 
  56085     return BCM_E_NONE;
  56086 }
  56087 
  56088 /*
  56089  * Function:
  56090  *      _bcm_esw_port_e2ecc_rx
  56091  * Purpose:
  56092  *      Configure E2ECC message reception.
  56093  * Parameters:
  56094  *      unit - (IN) Unit number.
  56095  *      port - (IN) Local port number.
  56096  *      config - (IN) Congestion configuration.
  56097  * Returns:
  56098  *      BCM_E_xxx
  56099  */
  56100 STATIC int
  56101 _bcm_esw_port_e2ecc_rx(int unit, bcm_port_t port,
  56102                        bcm_port_congestion_config_t *config)
  56103 {
  56104     uint32 regval;
  56105     uint64 regval64;
  56106     uint32 field_val;
  56107 
  56108     if (config->flags & BCM_PORT_CONGESTION_CONFIG_RX) {
  56109         /* If BCM_PORT_CONGESTION_CONFIG_RX flag is set, enable E2ECC reception. */
  56110 
  56111         /* Make sure chip-wide E2ECC reception disable bit is cleared */
  56112         SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &regval64));
  56113         if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
  56114                                   DISABLE_E2E_HOL_CHECKf) == 1) {
  56115             soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
  56116                                   DISABLE_E2E_HOL_CHECKf, 0);
  56117             SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, regval64));
  56118         }
  56119 
  56120         /* Set per-port E2ECC RX enable bit */
  56121         SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56122         if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  56123                               HOL_ENABLEf) == 0) {
  56124             soc_reg_field_set(unit, IE2E_CONTROLr, &regval, HOL_ENABLEf, 1);
  56125             SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56126         }
  56127 
  56128         /* Configure E2ECC receive MAC-DA, Length/Type, and Opcode */
  56129 
  56130         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  56131                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  56132         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, &regval));
  56133         soc_reg_field_set(unit, E2E_HOL_RX_DA_MSr, &regval, DAf, field_val);
  56134         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_MSr(unit, regval));
  56135 
  56136         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  56137                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  56138                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  56139                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  56140         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, &regval));
  56141         soc_reg_field_set(unit, E2E_HOL_RX_DA_LSr, &regval, DAf, field_val);
  56142         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_LSr(unit, regval));
  56143 
  56144         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_LENGTH_TYPEr(unit, &regval));
  56145         soc_reg_field_set(unit, E2E_HOL_RX_LENGTH_TYPEr, &regval, LENGTH_TYPEf, config->ethertype);
  56146         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_LENGTH_TYPEr(unit, regval));
  56147 
  56148         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_OPCODEr(unit, &regval));
  56149         soc_reg_field_set(unit, E2E_HOL_RX_OPCODEr, &regval, OPCODEf, config->opcode);
  56150         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_OPCODEr(unit, regval));
  56151 
  56152     } else {
  56153         /* If BCM_PORT_CONGESTION_CONFIG_RX flag is not set, disable E2ECC reception. */
  56154 
  56155         /* Clear per-port E2ECC RX enable bit */
  56156         SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56157         if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf) == 1) {
  56158             soc_reg_field_set(unit, IE2E_CONTROLr, &regval, HOL_ENABLEf, 0);
  56159             SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56160         }
  56161     }
  56162 
  56163     return BCM_E_NONE;
  56164 }
  56165 
  56166 STATIC int
  56167 _bcm_tr3_port_hcfc(int unit, bcm_port_t port,
  56168                    bcm_port_congestion_config_t *config)
  56169 {
  56170 #if defined(BCM_TRIUMPH3_SUPPORT)
  56171     soc_reg_t reg;
  56172     int enable;
  56173     uint32 rval;
  56174     uint64 rval64, fval64, tmp;
  56175 
  56176     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  56177     BCM_IF_ERROR_RETURN
  56178         (_bcm_esw_port_drop_status_enable_set(unit, port, enable));
  56179 
  56180     /* Configure egress status reporting */
  56181     reg = OOBFC_ENG_PORT_EN_64r;
  56182     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  56183     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
  56184     COMPILER_64_SET(tmp, 0, 1);
  56185     COMPILER_64_SHL(tmp, port);
  56186     COMPILER_64_AND(fval64, tmp);
  56187     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  56188 
  56189     SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval));
  56190     soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0);
  56191     SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval));
  56192 
  56193     return BCM_E_NONE;
  56194 #else
  56195     return BCM_E_UNAVAIL;
  56196 #endif
  56197 }
  56198 
  56199 
  56200 /*
  56201  * Function:
  56202  *      _bcm_esw_port_hcfc_tx
  56203  * Purpose:
  56204  *      configure the port hcfc egress status to enable
  56205  * Parameters:
  56206  *      unit - (IN) Unit number.
  56207  *      port - (IN) Port number
  56208  *      config - (IN) Configuration
  56209  * Returns:
  56210  *      BCM_E_xxx
  56211  * Notes:
  56212  */
  56213 STATIC int
  56214 _bcm_esw_port_hcfc_tx(int unit, bcm_port_t port,
  56215                    bcm_port_congestion_config_t *config)
  56216 {
  56217     soc_reg_t reg, reg0, reg1;
  56218     int enable, len;
  56219     uint64 rval64, fval64;
  56220     uint32 fval_hi, fval_lo;
  56221 
  56222     if (!SOC_PORT_VALID(unit, port)) {
  56223         return BCM_E_PORT;
  56224     }
  56225 
  56226     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
  56227         reg0 = OOBFC_ENG_PORT_EN0_64r;
  56228         reg1 = OOBFC_ENG_PORT_EN1_64r;
  56229     } else {
  56230         reg0 = OOBFC_ENG_PORT_EN_0_64r;
  56231         reg1 = OOBFC_ENG_PORT_EN_1_64r;
  56232     }
  56233     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
  56234         return BCM_E_PORT;
  56235     }
  56236 
  56237     /* Configure egress status reporting */
  56238     len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf);
  56239     if (len < 1) {
  56240         return BCM_E_PORT;
  56241     }
  56242     if (port < len) { /* First half of logical ports (not mmu port) */
  56243         reg = reg0;
  56244     } else {          /* Second half of logical ports (not mmu port) */
  56245         reg = reg1;
  56246     }
  56247     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  56248     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
  56249     fval_hi = COMPILER_64_HI(fval64);
  56250     fval_lo = COMPILER_64_LO(fval64);
  56251     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  56252     if (enable) {
  56253         if (port < len) {
  56254             if (port < 32) {
  56255                 fval_lo |= (1 << port);
  56256             } else {
  56257                 /* coverity[large_shift : FALSE] */
  56258                 fval_hi |= (1 << (port - 32));
  56259             }
  56260         } else {
  56261             int port_offset = port - len;
  56262             if ( port_offset < 32 ) {
  56263                 fval_lo |= (1 << port_offset);
  56264             } else {
  56265                 fval_hi |= (1 << (port_offset - 32));
  56266             }
  56267         }
  56268     } else {
  56269         if (port < len) {
  56270             if (port < 32) {
  56271                 fval_lo &= ~(1 << port);
  56272             } else {
  56273                 /* coverity[large_shift : FALSE] */
  56274                 fval_hi &= ~(1 << (port - 32));
  56275             }
  56276         } else {
  56277             int port_offset = port - len;
  56278             if ( port_offset < 32 ) {
  56279                 fval_lo &= ~(1 << port_offset);
  56280             } else {
  56281                 fval_hi &= ~(1 << (port_offset - 32));
  56282             }
  56283         }
  56284     }
  56285     COMPILER_64_SET(fval64, fval_hi, fval_lo);
  56286     soc_reg64_field_set(unit, reg, &rval64, ENG_PORT_ENf, fval64);
  56287     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  56288 
  56289     return BCM_E_NONE;
  56290 }
  56291 
  56292 /*
  56293  * Function:
  56294  *      _bcm_esw_port_hcfc_rx
  56295  * Purpose:
  56296  *      configure the port hcfc ingress status to enable
  56297  * Parameters:
  56298  *      unit - (IN) Unit number.
  56299  *      port - (IN) Port number
  56300  *      config - (IN) Configuration
  56301  * Returns:
  56302  *      BCM_E_xxx
  56303  * Notes:
  56304  */
  56305 STATIC int
  56306 _bcm_esw_port_hcfc_rx(int unit, bcm_port_t port,
  56307                    bcm_port_congestion_config_t *config)
  56308 {
  56309     soc_reg_t reg, reg0, reg1;
  56310     int enable, len;
  56311     uint64 rval64, fval64;
  56312     uint32 fval_hi, fval_lo;
  56313 
  56314     if (!SOC_PORT_VALID(unit, port)) {
  56315         return BCM_E_PORT;
  56316     }
  56317 
  56318     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
  56319         reg0 = OOBFC_ING_PORT_EN0_64r;
  56320         reg1 = OOBFC_ING_PORT_EN1_64r;
  56321     } else {
  56322         reg0 = OOBFC_ING_PORT_EN_0_64r;
  56323         reg1 = OOBFC_ING_PORT_EN_1_64r;
  56324     }
  56325     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
  56326         return BCM_E_PORT;
  56327     }
  56328 
  56329     /* Configure ingress status reporting */
  56330     len = soc_reg_field_length(unit, reg0, ING_PORT_ENf);
  56331     if (len < 1) {
  56332         return BCM_E_PORT;
  56333     }
  56334     if (port < len) { /* First half of logical ports (not mmu port) */
  56335         reg = reg0;
  56336     } else {          /* Second half of logical ports (not mmu port) */
  56337         reg = reg1;
  56338     }
  56339     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  56340     fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf);
  56341     fval_hi = COMPILER_64_HI(fval64);
  56342     fval_lo = COMPILER_64_LO(fval64);
  56343 
  56344     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  56345     if (enable) {
  56346         if (port < len) {
  56347             if (port < 32) {
  56348                 fval_lo |= (1 << port);
  56349             } else {
  56350                 /* coverity[large_shift : FALSE] */
  56351                 fval_hi |= (1 << (port - 32));
  56352             }
  56353         } else {
  56354             int port_offset = port - len;
  56355             if ( port_offset < 32 ) {
  56356                 fval_lo |= (1 << port_offset);
  56357             } else {
  56358                 fval_hi |= (1 << (port_offset - 32));
  56359             }
  56360         }
  56361     } else {
  56362         if (port < len) {
  56363             if (port < 32) {
  56364                 fval_lo &= ~(1 << port);
  56365             } else {
  56366                 /* coverity[large_shift : FALSE] */
  56367                 fval_hi &= ~(1 << (port - 32));
  56368             }
  56369         } else {
  56370             int port_offset = port - len;
  56371             if ( port_offset < 32 ) {
  56372                 fval_lo &= ~(1 << port_offset);
  56373             } else {
  56374                 fval_hi &= ~(1 << (port_offset - 32));
  56375             }
  56376         }
  56377     }
  56378     COMPILER_64_SET(fval64, fval_hi, fval_lo);
  56379     soc_reg64_field_set(unit, reg, &rval64, ING_PORT_ENf, fval64);
  56380     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  56381 
  56382     return BCM_E_NONE;
  56383 }
  56384 
  56385 
  56386 STATIC int
  56387 _bcm_esw_port_hcfc(int unit, bcm_port_t port,
  56388                    bcm_port_congestion_config_t *config)
  56389 {
  56390     int enable;
  56391     uint32 rval;
  56392 
  56393     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  56394     BCM_IF_ERROR_RETURN
  56395         (_bcm_esw_port_drop_status_enable_set(unit, port, enable));
  56396 
  56397     BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_tx(unit, port, config));
  56398 
  56399     BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_rx(unit, port, config));
  56400 
  56401     SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval));
  56402     soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0);
  56403     SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval));
  56404 
  56405     return BCM_E_NONE;
  56406 }
  56407 
  56408 #ifdef BCM_KATANA2_SUPPORT
  56409 STATIC int
  56410 _bcm_esw_port_coe_e2ecc(int unit, bcm_port_t port,
  56411                        bcm_port_congestion_config_t *config)
  56412 {
  56413 
  56414     uint32 regval = 0;
  56415     int en;
  56416     int e2ecc_strict = -1;
  56417     uint32 field_val;
  56418     int index;
  56419     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  56420     uint16      dev_id;
  56421     uint8       rev_id;
  56422 
  56423     soc_cm_get_id(unit, &dev_id, &rev_id);
  56424 
  56425     en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  56426 
  56427     if ((config->flags &
  56428          BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)) {
  56429         e2ecc_strict = 0;
  56430     } else if (config->flags &
  56431                BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) {
  56432         e2ecc_strict = 1;
  56433     } else {
  56434         return BCM_E_PARAM;
  56435     }
  56436     if ((rev_id == BCM56450_A0_REV_ID) && (!SOC_IS_SABER2(unit))) {
  56437        if (e2ecc_strict) {
  56438            /* E2ECC STRICT mode only valid for BCM56450_B0 onwards
  56439             */
  56440            return BCM_E_UNAVAIL;
  56441        }
  56442     } else if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  56443         /* setting of strict/flex mode is valid only when flow control is
  56444          * enabled
  56445          */
  56446         e2ecc_strict = (en ? e2ecc_strict : 0);
  56447         SOC_IF_ERROR_RETURN(
  56448                    READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  56449         /* Enable the Flow control and E2ECC mode
  56450          * 1. When there is enable request
  56451          * 2. When flow control is already enabled
  56452          *    and there is change in E2ECC_mode from
  56453          *    strict to flex or vice versa
  56454          */
  56455         if ((en != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  56456                   regval, FLOW_CONTROL_FORMATf)) ||
  56457               (en && (soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  56458                   regval, FLOW_CONTROL_FORMATf) == 1) &&
  56459                (e2ecc_strict != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  56460                regval, E2ECC_MODEf)))) {
  56461             soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, &regval,
  56462                         FLOW_CONTROL_FORMATf, en);
  56463             soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, &regval,
  56464                         E2ECC_MODEf, e2ecc_strict);
  56465             SOC_IF_ERROR_RETURN(
  56466               WRITE_COE_FLOW_CONTROL_CONFIGr (unit, port, regval));
  56467         }
  56468     }
  56469 
  56470     if (en) {
  56471         /* Configure E2ECC-FC receive MAC-DA, Length/Type, and Opcode */
  56472         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  56473                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  56474         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  56475         soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, &regval, DAf, field_val);
  56476         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval));
  56477 
  56478         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  56479                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  56480                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  56481                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  56482 
  56483         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  56484         soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, &regval, DAf, field_val);
  56485         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval));
  56486 
  56487 
  56488         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  56489         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  56490                           LENGTH_TYPEf, config->ethertype);
  56491 
  56492         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  56493                            OPCODEf, config->opcode);
  56494         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval));
  56495 
  56496         /*
  56497          * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the
  56498          * congestion data is written as it is
  56499          * in FC_ST_TABLE
  56500          */
  56501 
  56502         for (index=0 ; index < soc_mem_index_count(unit,
  56503                     MMU_INTFI_ST_TRANS_TBLm); index++) {
  56504             SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  56505                         unit, MEM_BLOCK_ALL,index,
  56506                         &st_trans_entry));
  56507             soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  56508                     &st_trans_entry, FC_ST_XLATEf,index%256);
  56509             SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  56510                         unit, MEM_BLOCK_ALL, index,
  56511                         &st_trans_entry));
  56512         }
  56513 
  56514         /*
  56515          * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time
  56516          */
  56517         SOC_IF_ERROR_RETURN
  56518             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56519                                     FC_WIDTHf, 3));
  56520         /*
  56521          * In case of COE E2ECC merger block should be disabled
  56522          */
  56523 
  56524         SOC_IF_ERROR_RETURN
  56525             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56526                                     MERGE_ENf, 0));
  56527         /*
  56528          * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR,
  56529          * so that state machine reads
  56530          * all the L1,L2,L3 Nodes in a cycle
  56531          */
  56532 
  56533 
  56534         SOC_IF_ERROR_RETURN
  56535             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56536                                     FC_MAP_TBL_ADDR_ENf, 0));
  56537         SOC_IF_ERROR_RETURN
  56538             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56539                                     FC_MAP_TBL_START_ADDRf, 0));
  56540         if (SOC_IS_SABER2(unit)) {
  56541     #ifdef BCM_METROLITE_SUPPORT
  56542             if (SOC_IS_METROLITE(unit))  {
  56543                 SOC_IF_ERROR_RETURN
  56544                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56545                                         FC_MAP_TBL_END_ADDRf, 0x1f));
  56546             } else
  56547     #endif
  56548             SOC_IF_ERROR_RETURN
  56549                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56550                                        FC_MAP_TBL_END_ADDRf, 0x3f));
  56551         } else {
  56552             SOC_IF_ERROR_RETURN
  56553                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56554                                        FC_MAP_TBL_END_ADDRf, 0xff));
  56555         }
  56556         SOC_IF_ERROR_RETURN
  56557             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56558                                     FC_MAP_TBL_ADDR_ENf, 0));
  56559         SOC_IF_ERROR_RETURN
  56560             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56561                                     FC_MAP_TBL_START_ADDRf, 0));
  56562         if (SOC_IS_SABER2(unit)) {
  56563     #ifdef BCM_METROLITE_SUPPORT
  56564             if (SOC_IS_METROLITE(unit))  {
  56565                 SOC_IF_ERROR_RETURN
  56566                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56567                                         FC_MAP_TBL_END_ADDRf, 0x7));
  56568             } else
  56569     #endif
  56570             SOC_IF_ERROR_RETURN
  56571                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56572                                         FC_MAP_TBL_END_ADDRf, 0xf));
  56573         } else {
  56574             SOC_IF_ERROR_RETURN
  56575                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56576                                         FC_MAP_TBL_END_ADDRf, 0x3f));
  56577         }
  56578         SOC_IF_ERROR_RETURN
  56579             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56580                                     FC_MAP_TBL_ADDR_ENf, 0));
  56581         SOC_IF_ERROR_RETURN
  56582             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56583                                     FC_MAP_TBL_START_ADDRf, 0));
  56584         if (SOC_IS_SABER2(unit)) {
  56585     #ifdef BCM_METROLITE_SUPPORT
  56586             if (SOC_IS_METROLITE(unit))  {
  56587                 SOC_IF_ERROR_RETURN
  56588                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56589                                         FC_MAP_TBL_END_ADDRf, 0x3));
  56590             } else
  56591     #endif
  56592             SOC_IF_ERROR_RETURN
  56593                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56594                                         FC_MAP_TBL_END_ADDRf, 0x7));
  56595         } else {
  56596             SOC_IF_ERROR_RETURN
  56597                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56598                                         FC_MAP_TBL_END_ADDRf, 0x1f));
  56599         }
  56600 
  56601         if (e2ecc_strict == 0) {
  56602             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56603             if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  56604                                 VOQFC_ENABLEf)) {
  56605                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  56606                                   VOQFC_ENABLEf, en);
  56607                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56608             }
  56609         } else {
  56610             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56611             if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  56612                                 VOQFC_ENABLEf)) {
  56613                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  56614                                   VOQFC_ENABLEf, 0);
  56615                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56616             }
  56617         }
  56618     } else {
  56619         if (e2ecc_strict == 0) {
  56620             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56621             if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  56622                                 VOQFC_ENABLEf)) {
  56623                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  56624                                   VOQFC_ENABLEf, 0);
  56625                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56626             }
  56627         }
  56628     }
  56629 
  56630     return BCM_E_NONE;
  56631 }
  56632 #endif
  56633 
  56634 /*
  56635  * Function:
  56636  *      _bcm_esw_port_dmvoqfc_rx
  56637  * Purpose:
  56638  *      Configure VOQFC message reception.
  56639  * Parameters:
  56640  *      unit - (IN) Unit number.
  56641  *      port - (IN) Local port number.
  56642  *      config - (IN) Congestion configuration.
  56643  * Returns:
  56644  *      BCM_E_xxx
  56645  */
  56646 STATIC int
  56647 _bcm_esw_port_dmvoqfc_rx(int unit, bcm_port_t port,
  56648                        bcm_port_congestion_config_t *config)
  56649 {
  56650     uint32 regval;
  56651     uint32 field_val;
  56652     int     en, cos_mode;
  56653 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
  56654     defined(BCM_TRIUMPH3_SUPPORT)
  56655     int index;
  56656 #endif
  56657 #if defined(BCM_TRIDENT2_SUPPORT)
  56658     uint64 rval;
  56659 #endif
  56660 #if defined(BCM_TRIUMPH3_SUPPORT)
  56661     uint32 rval1;
  56662     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  56663 #endif
  56664 
  56665     en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  56666     cos_mode = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  56667     SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  56668     if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  56669                                 VOQFC_ENABLEf)) {
  56670         soc_reg_field_set(unit, IE2E_CONTROLr, &regval, VOQFC_ENABLEf, en);
  56671         SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  56672     }
  56673 #ifdef BCM_TRIDENT2_SUPPORT
  56674     if (SOC_IS_TD2_TT2(unit)) {
  56675         SOC_IF_ERROR_RETURN(READ_ING_COS_MODE_64r(unit, port, &rval));
  56676         if (cos_mode != soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval,
  56677                     QUEUE_MODEf)) {
  56678             soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, QUEUE_MODEf, cos_mode);
  56679             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODE_64r(unit, port, rval));
  56680         }
  56681         /*
  56682          *  FC_WIDTH is set to 2 so that 4 bits of i
  56683          * congestion data is read on each cycle
  56684          */
  56685         SOC_IF_ERROR_RETURN
  56686             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56687                                     FC_WIDTHf, 2));
  56688         /*
  56689          * MERGE_EN is set to 1, to merge the congestion state
  56690          * received from different ports of the same module
  56691          */
  56692 
  56693         SOC_IF_ERROR_RETURN
  56694             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56695                                     MERGE_ENf, 1));
  56696         /* MODE_SEL is set to 1 to specify the message is of type
  56697          *  DMVOQ
  56698          */
  56699         SOC_IF_ERROR_RETURN
  56700             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56701                                     MODE_SELf, 1));
  56702 #ifdef BCM_APACHE_SUPPORT
  56703         if (SOC_IS_APACHE(unit)) {
  56704             if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) {
  56705                 /*
  56706                 * MERGE_EN is set to 0, in case of DPVOQ.
  56707                 */
  56708 
  56709                 SOC_IF_ERROR_RETURN
  56710                     (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56711                                             MERGE_ENf, 0));
  56712                 /* MODE_SEL is set to 0 to specify the message is of type
  56713                 *  DPVOQ
  56714                 */
  56715                 SOC_IF_ERROR_RETURN
  56716                     (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56717                                             MODE_SELf, 0));
  56718             }
  56719         }
  56720 #endif
  56721         /* DMVOQ congestion bytes max length is 64 bytes,
  56722          * as a result
  56723          * DMVOQ feature can support upto 64 ports
  56724          */
  56725 
  56726         for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  56727                 ; index++) {
  56728             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  56729                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  56730             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  56731                         index, regval));
  56732         }
  56733 
  56734     } else
  56735 #endif
  56736 #ifdef BCM_KATANA2_SUPPORT
  56737      if (SOC_IS_KATANA2(unit)) {
  56738         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &regval));
  56739         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval,
  56740                     COS_MODEf)) {
  56741             soc_reg_field_set(unit, ING_COS_MODEr, &regval, COS_MODEf, cos_mode);
  56742             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval));
  56743         }
  56744 
  56745         /*
  56746          * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time
  56747          */
  56748         SOC_IF_ERROR_RETURN
  56749             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56750                                     FC_WIDTHf, 3));
  56751         if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) {
  56752         /*
  56753          * In case of DMVOQ we need to merge all the congestion bytes
  56754          * of the ports so enabling MERGE_EN
  56755          */
  56756 
  56757         SOC_IF_ERROR_RETURN
  56758             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56759                                     MERGE_ENf, 1));
  56760         }
  56761         /*
  56762          * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR,
  56763          * so that state machine reads
  56764          * all the L1,L2,L3 Nodes in a cycle
  56765          */
  56766 
  56767         SOC_IF_ERROR_RETURN
  56768             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56769                                     FC_MAP_TBL_ADDR_ENf, 0));
  56770         SOC_IF_ERROR_RETURN
  56771             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56772                                     FC_MAP_TBL_START_ADDRf, 0));
  56773         SOC_IF_ERROR_RETURN
  56774             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  56775                                    FC_MAP_TBL_END_ADDRf,
  56776                                    ((soc_mem_index_count(unit, LLS_L2_PARENTm)) / 16) - 1));
  56777         SOC_IF_ERROR_RETURN
  56778             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56779                                     FC_MAP_TBL_ADDR_ENf, 0));
  56780         SOC_IF_ERROR_RETURN
  56781             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56782                                     FC_MAP_TBL_START_ADDRf, 0));
  56783         SOC_IF_ERROR_RETURN
  56784             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  56785                                     FC_MAP_TBL_END_ADDRf,
  56786                                    ((soc_mem_index_count(unit, LLS_L1_PARENTm)) / 16) - 1 ));
  56787         SOC_IF_ERROR_RETURN
  56788             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56789                                     FC_MAP_TBL_ADDR_ENf, 0));
  56790         SOC_IF_ERROR_RETURN
  56791             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56792                                     FC_MAP_TBL_START_ADDRf, 0));
  56793         SOC_IF_ERROR_RETURN
  56794             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  56795                                     FC_MAP_TBL_END_ADDRf,
  56796                                    ((soc_mem_index_count(unit, LLS_L0_PARENTm)) /
  56797                                     (SOC_IS_METROLITE(unit) ? 32: 16)) - 1));
  56798 
  56799         /* Though the number of ports supported in KT2 is 41, we're setting the
  56800            max to 64 to support stacked systems. */
  56801         for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  56802                 ; index++) {
  56803             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  56804                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  56805             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  56806                         index, regval));
  56807         }
  56808 
  56809     } else
  56810 #endif
  56811 #ifdef BCM_TRIUMPH3_SUPPORT
  56812     if (SOC_IS_TRIUMPH3(unit)) {
  56813         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval1));
  56814         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, rval1,
  56815                     QUEUE_MODEf)) {
  56816             soc_reg_field_set(unit, ING_COS_MODEr, &rval1, QUEUE_MODEf, cos_mode);
  56817             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval1));
  56818         }
  56819         /*
  56820          * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the
  56821          * congestion data is written as it is
  56822          * in FC_ST_TABLE, This we are doing so that
  56823          * congestion data is updated as it is how
  56824          * it recevied
  56825          */
  56826 
  56827         for (index=0 ; index < soc_mem_index_count(unit,
  56828                     MMU_INTFI_ST_TRANS_TBLm); index++) {
  56829             SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  56830                         unit, MEM_BLOCK_ALL,index,
  56831                         &st_trans_entry));
  56832             soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  56833                     &st_trans_entry, FC_ST_XLATEf,index%16);
  56834             SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  56835                         unit, MEM_BLOCK_ALL, index,
  56836                         &st_trans_entry));
  56837         }
  56838         /*
  56839          *  FC_WIDTH is set to 2 so that 4 bits of i
  56840          * congestion data is read on each cycle
  56841          */
  56842         SOC_IF_ERROR_RETURN
  56843             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56844                                     FC_WIDTHf, 2));
  56845         /*
  56846          * MERGE_EN is set to 1, to merge the congestion state
  56847          * received from different ports of the same module
  56848          */
  56849 
  56850         SOC_IF_ERROR_RETURN
  56851             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  56852                                     MERGE_ENf, 1));
  56853         /* DMVOQ congestion bytes max length is 64 bytes,
  56854          * as a result
  56855          * DMVOQ feature can support upto 64 ports
  56856          */
  56857 
  56858         for (index = 0; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  56859                 ; index++) {
  56860             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  56861                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  56862             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  56863                         index, regval));
  56864         }
  56865 
  56866     } else
  56867 #endif
  56868     {
  56869         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &regval));
  56870         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval,
  56871                     QUEUE_MODEf)) {
  56872             soc_reg_field_set(unit, ING_COS_MODEr, &regval, QUEUE_MODEf, cos_mode);
  56873             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval));
  56874         }
  56875     }
  56876 
  56877     if (en) {
  56878         /* Configure DMVOQFC receive MAC-DA, Length/Type, and Opcode */
  56879         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  56880                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  56881         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  56882         soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, &regval, DAf, field_val);
  56883         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval));
  56884 
  56885         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  56886                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  56887                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  56888                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  56889 
  56890         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  56891         soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, &regval, DAf, field_val);
  56892         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval));
  56893 
  56894 
  56895         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  56896         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  56897                           LENGTH_TYPEf, config->ethertype);
  56898 
  56899         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval, OPCODEf, config->opcode);
  56900         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval));
  56901     }
  56902 
  56903     return BCM_E_NONE;
  56904 }
  56905 /*
  56906  * Function:
  56907  *      _bcm_esw_port_dmvoqfc_tx
  56908  * Purpose:
  56909  *      Configure VOQFC message reception.
  56910  * Parameters:
  56911  *      unit - (IN) Unit number.
  56912  *      port - (IN) Local port number.
  56913  *      config - (IN) Congestion configuration.
  56914  * Returns:
  56915  *      BCM_E_xxx
  56916  */
  56917 STATIC int
  56918 _bcm_esw_port_dmvoqfc_tx(int unit, bcm_port_t port,
  56919                        bcm_port_congestion_config_t *config)
  56920 {
  56921     /*
  56922      * Trident/Titan VOQFC message generation is same as E2ECC, except for
  56923      * ethertype and opcode.
  56924      */
  56925     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANA2(unit)
  56926             || SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit)) {
  56927         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_tx(unit, port, config));
  56928         return BCM_E_NONE;
  56929     }
  56930 
  56931     return BCM_E_UNAVAIL;
  56932 }
  56933 
  56934 /*
  56935  * Function:
  56936  *      bcm_port_congestion_config_set
  56937  * Purpose:
  56938  *      Set end-to-end congestion control.
  56939  * Parameters:
  56940  *      unit - (IN) Unit number.
  56941  *      port - (IN) Gport number.
  56942  *      config - (IN) Structure containing the congestion configuration.
  56943  * Returns:
  56944  *      BCM_E_xxx
  56945  */
  56946 int
  56947 bcm_esw_port_congestion_config_set(int unit, bcm_gport_t port,
  56948                                    bcm_port_congestion_config_t *config)
  56949 {
  56950     bcm_port_t local_port;
  56951 
  56952     /* Make sure port module is initialized. */
  56953     PORT_INIT(unit);
  56954 
  56955     if (soc_feature(unit, soc_feature_e2ecc)) {
  56956         /* Check for parameters */
  56957 
  56958         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
  56959 
  56960         if (!IS_HG_PORT(unit, local_port)) {
  56961             if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  56962                 SOC_IS_APACHE(unit) ) {
  56963                if ((config->flags &
  56964                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  56965                     (config->flags &
  56966                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ||
  56967                     (config->flags &
  56968                      BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE))
  56969                          {
  56970                     if (!IS_SUBTAG_PORT(unit, local_port)) {
  56971                         LOG_ERROR(BSL_LS_BCM_PORT,
  56972                                   (BSL_META_U(unit,
  56973                                 "E2ECC COE is applicable on subports only."
  56974                                 "Port %d is not a subport.\n"),
  56975                                 local_port));
  56976                         return BCM_E_PORT;
  56977                     }
  56978                 } else if ((config->flags &
  56979                             BCM_PORT_CONGESTION_CONFIG_TX) &&
  56980                            (config->flags &
  56981                            BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) {
  56982                     if ((IS_GE_PORT(unit, local_port)) ||
  56983                         (IS_XE_PORT(unit, local_port)))  {
  56984                         /* Set per-queue E2ECC enable bits */
  56985                         BCM_IF_ERROR_RETURN
  56986                             (_bcm_esw_port_drop_status_enable_set(unit,
  56987                                                        port, TRUE));
  56988                         /* Make sure port module is initialized. */
  56989                         PORT_INIT(unit);
  56990 
  56991                         /* Lock is needed to modify bcm_port_info */
  56992                         PORT_LOCK(unit);
  56993 
  56994                         /* Allocate per-port congestion configuration state on demand */
  56995                         if (PORT(unit, local_port).e2ecc_config == NULL) {
  56996                             PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t),
  56997                                     "bcm_port_congestion_config");
  56998                             if (PORT(unit, local_port).e2ecc_config == NULL) {
  56999                                 LOG_ERROR(BSL_LS_BCM_PORT,
  57000                                         (BSL_META_U(unit,
  57001                                                     "Error: unable to allocate memory for bcm_port_congestion_config.\n")));
  57002                                 PORT_UNLOCK(unit);
  57003                                 return BCM_E_MEMORY;
  57004                             }
  57005                         }
  57006 
  57007                         /* Store E2ECC configuration */
  57008                         *(PORT(unit, local_port).e2ecc_config) = *(config);
  57009 
  57010                         PORT_UNLOCK(unit);
  57011                         return BCM_E_NONE;
  57012                     }
  57013                     LOG_ERROR(BSL_LS_BCM_PORT,
  57014                               (BSL_META_U(unit,
  57015                                "Applicable on Ge/Xe only "
  57016                                "for enabling dmvoq transmitting only.\n ")));
  57017                     return BCM_E_PARAM;
  57018                 } else {
  57019                     if (((SOC_IS_TRIDENT2PLUS(unit)) || SOC_IS_APACHE(unit)) &&
  57020                           (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) {
  57021                         LOG_ERROR(BSL_LS_BCM_PORT,
  57022                              (BSL_META_U(unit,
  57023                           "Error: unit %d port %d is not a Higig port. "
  57024                           "E2ECC messages can only be transmitted to "
  57025                           "or received from Higig ports.\n"),
  57026                           unit, local_port));
  57027                         return BCM_E_PARAM;
  57028                     }
  57029                 }
  57030             } else {
  57031 #ifdef BCM_FIRELIGHT_SUPPORT
  57032                 if (SOC_IS_FIRELIGHT(unit) &&
  57033                     (IS_XL_PORT(unit, local_port) || IS_CL_PORT(unit, local_port)) ) {
  57034                     LOG_DEBUG(BSL_LS_BCM_PORT,
  57035                          (BSL_META_U(unit,
  57036                       "unit %d port %d is not a Higig port. "
  57037                       "E2ECC messages can be transmitted to "
  57038                       "Higig/ethernet(XL/CL) ports.\n"), unit, local_port));
  57039                 } else
  57040 #endif /* BCM_FIRELIGHT_SUPPORT */
  57041                 {
  57042                     LOG_ERROR(BSL_LS_BCM_PORT,
  57043                          (BSL_META_U(unit,
  57044                       "Error: unit %d port %d is not a Higig port. "
  57045                       "E2ECC messages can only be transmitted to or received from "
  57046                       "Higig ports.\n"), unit, local_port));
  57047                     return BCM_E_PARAM;
  57048                 }
  57049             }
  57050         }
  57051 
  57052         if (config == NULL) {
  57053             return BCM_E_PARAM;
  57054         }
  57055 
  57056         if (!((config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ||
  57057             (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC) ||
  57058             (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) ||
  57059             (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) ||
  57060             (config->flags & BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4) ||
  57061             (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  57062             (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)   ||
  57063             (config->flags & BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE))) {
  57064             return BCM_E_PARAM;
  57065         }
  57066 
  57067         if (config->packets_per_sec < 0) {
  57068             return BCM_E_PARAM;
  57069         }
  57070 
  57071         switch (config->flags &
  57072                 (BCM_PORT_CONGESTION_CONFIG_E2ECC |
  57073                  BCM_PORT_CONGESTION_CONFIG_HCFC |
  57074                  BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL |
  57075                  BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL |
  57076                  BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4 |
  57077                  BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE |
  57078                  BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE   |
  57079                  BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) {
  57080         case BCM_PORT_CONGESTION_CONFIG_E2ECC:
  57081         case BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4:
  57082             /* Handle E2ECC message transmission */
  57083             BCM_IF_ERROR_RETURN
  57084                 (_bcm_esw_port_e2ecc_tx(unit, local_port, config));
  57085 
  57086             /* Handle E2ECC message reception */
  57087             BCM_IF_ERROR_RETURN
  57088                 (_bcm_esw_port_e2ecc_rx(unit, local_port, config));
  57089             break;
  57090 
  57091         case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE:
  57092         case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE:
  57093         case BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE:
  57094              /* COE flow control using E2ECC messages
  57095               * KT2 supports E2E-CC message reception on
  57096               * COE ports.
  57097               */
  57098 #ifdef BCM_KATANA2_SUPPORT
  57099              if (SOC_IS_KATANA2(unit)) {
  57100                  BCM_IF_ERROR_RETURN
  57101                          (_bcm_esw_port_coe_e2ecc(unit, local_port, config));
  57102 
  57103              }
  57104 #endif
  57105 
  57106              
  57107 
  57108              /* COE flow control using E2ECC messages
  57109               * TD2+ supports E2E-CC message reception on
  57110               * COE ports, only in STRICT mode.
  57111               */
  57112 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  57113              if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  57114                  if (((config->flags &
  57115                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  57116                     (config->flags &
  57117                     BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) &&
  57118                     (config->flags &
  57119                             BCM_PORT_CONGESTION_CONFIG_RX))
  57120                  {
  57121                      BCM_IF_ERROR_RETURN
  57122                           (bcm_td2p_port_coe_e2ecc(unit, local_port, config));
  57123                  } else {
  57124                     return BCM_E_PARAM;
  57125                  }
  57126 
  57127              }
  57128 #endif
  57129        break;
  57130 
  57131         case BCM_PORT_CONGESTION_CONFIG_HCFC:
  57132             if (SOC_IS_TRIUMPH3(unit)) {
  57133                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_hcfc(unit, local_port, config));
  57134             } else {
  57135                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc(unit, local_port, config));
  57136             }
  57137             break;
  57138 
  57139         case BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL:
  57140             if ((!SOC_IS_TD_TT(unit)) && (!SOC_IS_KATANA2(unit)) &&
  57141                     (!SOC_IS_TD2_TT2(unit)) && (!SOC_IS_TRIUMPH3(unit))) {
  57142                 return BCM_E_PARAM;
  57143             }
  57144 
  57145             /* Handle VOQFC message reception */
  57146             BCM_IF_ERROR_RETURN
  57147                 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config));
  57148 
  57149             /* Handle E2ECC message transmission */
  57150             BCM_IF_ERROR_RETURN
  57151                 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config));
  57152             break;
  57153         case BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL:
  57154             if (!SOC_IS_KATANA2(unit) && !(SOC_IS_APACHE(unit))) {
  57155                 return BCM_E_PARAM;
  57156             }
  57157 
  57158             /* Handle VOQFC message reception */
  57159             BCM_IF_ERROR_RETURN
  57160                 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config));
  57161 
  57162             /* Handle E2ECC message transmission */
  57163             BCM_IF_ERROR_RETURN
  57164                 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config));
  57165             break;
  57166         default:
  57167             return BCM_E_PARAM;
  57168         }
  57169         /* Make sure port module is initialized. */
  57170         PORT_INIT(unit);
  57171 
  57172         /* Lock is needed to modify bcm_port_info */
  57173         PORT_LOCK(unit);
  57174 
  57175         /* Allocate per-port congestion configuration state on demand */
  57176         if (PORT(unit, local_port).e2ecc_config == NULL) {
  57177             PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t),
  57178                     "bcm_port_congestion_config");
  57179             if (PORT(unit, local_port).e2ecc_config == NULL) {
  57180                 LOG_ERROR(BSL_LS_BCM_PORT,
  57181                         (BSL_META_U(unit,
  57182                                     "Error: unable to allocate memory for bcm_port_congestion_config.\n")));
  57183                 PORT_UNLOCK(unit);
  57184                 return BCM_E_MEMORY;
  57185             }
  57186         }
  57187 
  57188         /* Store E2ECC configuration */
  57189         *(PORT(unit, local_port).e2ecc_config) = *(config);
  57190 
  57191         PORT_UNLOCK(unit);
  57192 
  57193 
  57194         return BCM_E_NONE;
  57195     } else {
  57196         return BCM_E_UNAVAIL;
  57197     }
  57198 
  57199 }
  57200 
  57201 /*
  57202  * Function:
  57203  *      bcm_port_congestion_config_get
  57204  * Purpose:
  57205  *      Get end-to-end congestion control configuration.
  57206  * Parameters:
  57207  *      unit - (IN) Unit number.
  57208  *      port - (IN) Gport number.
  57209  *      config - (OUT) Structure containing the congestion configuration.
  57210  * Returns:
  57211  *      BCM_E_xxx
  57212  */
  57213 
  57214 int
  57215 bcm_esw_port_congestion_config_get(int unit, bcm_gport_t port,
  57216                                    bcm_port_congestion_config_t *config)
  57217 {
  57218     bcm_port_t local_port;
  57219 
  57220     /* Make sure port module is initialized. */
  57221     PORT_INIT(unit);
  57222 
  57223     if (soc_feature(unit, soc_feature_e2ecc)) {
  57224         /* Check for parameters */
  57225 
  57226         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
  57227         if (!IS_HG_PORT(unit, local_port)) {
  57228             if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  57229                 SOC_IS_APACHE(unit)) {
  57230                 if ((config->flags &
  57231                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  57232                     (config->flags &
  57233                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)   ||
  57234                     (config->flags &
  57235                      BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) {
  57236                     if (!IS_SUBTAG_PORT(unit, local_port)) {
  57237                         LOG_ERROR(
  57238                             BSL_LS_BCM_PORT,
  57239                             (BSL_META_U(unit,
  57240                                         "Error: unit %d port %d is not a Higig "
  57241                                         "port or Subtag port. E2ECC messages "
  57242                                         "can be transmitted to or received from "
  57243                                         "Higig ports or can be received on "
  57244                                         "Subtag port.\n"),
  57245                              unit, local_port));
  57246                         return BCM_E_PORT;
  57247                      }
  57248                      if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  57249                            ((config->flags &
  57250                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE))) {
  57251                             return BCM_E_PARAM;
  57252 
  57253                      } else  if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  57254                            ((config->flags &
  57255                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  57256                            (config->flags &
  57257                              BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) &&
  57258                             (config->flags &
  57259                             BCM_PORT_CONGESTION_CONFIG_TX)) {
  57260                             return BCM_E_PARAM;
  57261                      }
  57262                 } else if ((config->flags &
  57263                             BCM_PORT_CONGESTION_CONFIG_TX) &&
  57264                            (config->flags &
  57265                             BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) {
  57266                     if (!(IS_GE_PORT(unit, local_port)) &&
  57267                         !(IS_XE_PORT(unit, local_port)))  {
  57268                         LOG_ERROR(
  57269                             BSL_LS_BCM_PORT,
  57270                             (BSL_META_U(unit,
  57271                                         "Applicable on Ge/Xe only for enabling "
  57272                                         "dmvoq transmitting only.\n ")));
  57273                         return BCM_E_PARAM;
  57274                     }
  57275                 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  57276                            (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) {
  57277                     LOG_ERROR(
  57278                         BSL_LS_BCM_PORT,
  57279                         (BSL_META_U(unit,
  57280                                     "Error: unit %d port %d is not a Higig port. "
  57281                                     "E2ECC messages can only be transmitted to "
  57282                                     "or received from Higig ports.\n"),
  57283                          unit, local_port));
  57284                        return BCM_E_PARAM;
  57285                 }
  57286             } else {
  57287 #ifdef BCM_FIRELIGHT_SUPPORT
  57288                 if (SOC_IS_FIRELIGHT(unit) &&
  57289                     (IS_XL_PORT(unit, local_port) || IS_CL_PORT(unit, local_port)) ) {
  57290                     LOG_DEBUG(BSL_LS_BCM_PORT,
  57291                          (BSL_META_U(unit,
  57292                               "unit %d port %d is not a Higig port. "
  57293                               "E2ECC messages can be transmitted to "
  57294                               "Higig/ethernet(XL/CL) ports.\n"), unit, local_port));
  57295                 } else
  57296 #endif /* BCM_FIRELIGHT_SUPPORT */
  57297                 {
  57298                     LOG_ERROR(
  57299                         BSL_LS_BCM_PORT,
  57300                             (BSL_META_U(unit,
  57301                                     "Error: unit %d port %d is not a Higig port. "
  57302                                     "E2ECC messages can only be transmitted to "
  57303                                     "or received from Higig ports.\n"),
  57304                          unit, local_port));
  57305                     return BCM_E_PARAM;
  57306                 }
  57307             }
  57308         }
  57309         if (config == NULL) {
  57310             return BCM_E_PARAM;
  57311         }
  57312 
  57313         /* Make sure port module is initialized. */
  57314         PORT_INIT(unit);
  57315 
  57316         if (PORT(unit, local_port).e2ecc_config == NULL) {
  57317             LOG_ERROR(BSL_LS_BCM_PORT,
  57318                       (BSL_META_U(unit,
  57319                                   "Error: Port %d bcm_port_congestion_config was not set.\n"),
  57320                                   local_port));
  57321             return BCM_E_NOT_FOUND;
  57322         }
  57323 
  57324         /* Retrieve E2ECC configuration */
  57325         *config = *(PORT(unit, local_port).e2ecc_config);
  57326 
  57327         return BCM_E_NONE;
  57328 
  57329     } else {
  57330         return BCM_E_UNAVAIL;
  57331     }
  57332 }
  57333 
  57334 /*
  57335  * Function:
  57336  *      bcm_port_match_add
  57337  * Purpose:
  57338  *      Add a match to an existing port
  57339  * Parameters:
  57340  *      unit - (IN) Unit number.
  57341  *      port - (IN) Port or gport
  57342  *      match - (IN) Match criteria
  57343  * Returns:
  57344  *      BCM_E_xxx
  57345  * Notes:
  57346  */
  57347 int
  57348 bcm_esw_port_match_add(
  57349     int unit,
  57350     bcm_gport_t port,
  57351     bcm_port_match_info_t *match)
  57352 {
  57353 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  57354     int vp=0, rv = BCM_E_NONE;
  57355     bcm_gport_t gp = 0;
  57356 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT)
  57357     _bcm_vp_info_t vp_info;
  57358 #endif
  57359 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  57360     bcm_vxlan_port_t vxlan_port;
  57361     bcm_l2gre_port_t l2gre_port;
  57362 #endif
  57363     int existing_updated = 0;
  57364 #if defined(BCM_TRIDENT3_SUPPORT)
  57365     bcm_mirror_destination_t mirror_dest;
  57366     uint32 cancun_ver;
  57367 #endif /* BCM_TRIDENT3_SUPPORT */
  57368 #if defined(BCM_TRX_SUPPORT)
  57369     bcm_vlan_match_info_t vlan_match_info;
  57370 #endif
  57371     if (match == NULL) {
  57372         return BCM_E_PARAM;
  57373     }
  57374 
  57375     /* Make sure port module is initialized. */
  57376     PORT_INIT(unit);
  57377 
  57378     if (BCM_GPORT_IS_MIM_PORT(port)) {
  57379 #if defined(BCM_TRIUMPH2_SUPPORT)
  57380         if (!soc_feature(unit, soc_feature_mim)) {
  57381             return BCM_E_UNAVAIL;
  57382         }
  57383         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  57384         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  57385             return BCM_E_NOT_FOUND;
  57386         }
  57387         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  57388         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57389             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  57390         }
  57391 #endif
  57392     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  57393         if (!soc_feature(unit, soc_feature_mpls)) {
  57394             return BCM_E_UNAVAIL;
  57395         }
  57396         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  57397         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  57398             return BCM_E_NOT_FOUND;
  57399         }
  57400 #if defined(BCM_MPLS_SUPPORT)
  57401         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  57402         if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57403             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  57404                 return BCM_E_UNAVAIL;
  57405             }
  57406         } else {
  57407             BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  57408         }
  57409 #endif
  57410     } else
  57411 #if defined(BCM_TRIDENT2_SUPPORT)
  57412     if (BCM_GPORT_IS_TRUNK(port)) {
  57413         if (!soc_feature(unit, soc_feature_vp_lag)) {
  57414             return BCM_E_UNAVAIL;
  57415         }
  57416         BCM_IF_ERROR_RETURN(
  57417             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  57418                                             &vp));
  57419         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  57420             return BCM_E_NOT_FOUND;
  57421         }
  57422         if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID &&
  57423             match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) {
  57424             return BCM_E_PARAM;
  57425         }
  57426     } else
  57427 #endif /* BCM_TRIDENT2_SUPPORT */
  57428 #if defined(BCM_TRIDENT2_SUPPORT)
  57429     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57430         if (!soc_feature(unit, soc_feature_vxlan)) {
  57431             return BCM_E_UNAVAIL;
  57432         }
  57433         if (match->match == BCM_PORT_MATCH_PORT
  57434             || match->match == BCM_PORT_MATCH_MAC_PORT
  57435             || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE
  57436             || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE
  57437             || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE
  57438             ) {
  57439             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  57440             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  57441                 return BCM_E_NOT_FOUND;
  57442             }
  57443         } else {
  57444             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  57445                 return BCM_E_UNAVAIL;
  57446             }
  57447 
  57448             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  57449             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  57450 
  57451             if (vp_info.vp_type != _bcmVpTypeVxlan) {
  57452                 return BCM_E_PARAM;
  57453             }
  57454             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57455                 return BCM_E_PARAM;
  57456             }
  57457 
  57458             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, match->vpn));
  57459         }
  57460     } else
  57461 #endif
  57462 #if defined(BCM_TRIDENT2_SUPPORT)
  57463     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57464         if (!soc_feature(unit, soc_feature_l2gre)) {
  57465             return BCM_E_UNAVAIL;
  57466         }
  57467         if (match->match == BCM_PORT_MATCH_PORT) {
  57468             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  57469             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) {
  57470                 return BCM_E_NOT_FOUND;
  57471             }
  57472         } else {
  57473             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  57474                 return BCM_E_UNAVAIL;
  57475             }
  57476 
  57477             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  57478             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  57479 
  57480             if (vp_info.vp_type != _bcmVpTypeL2Gre) {
  57481                 return BCM_E_PARAM;
  57482             }
  57483             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57484                 return BCM_E_PARAM;
  57485             }
  57486 
  57487             BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_vpn_is_valid(unit, match->vpn));
  57488         }
  57489     } else
  57490 #endif
  57491 
  57492 
  57493 #if defined(BCM_TRIUMPH2_SUPPORT)
  57494     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  57495         if ((!soc_feature(unit, soc_feature_lltag)) &&
  57496             (!soc_feature(unit, soc_feature_vlan_vp))) {
  57497             return BCM_E_UNAVAIL;
  57498         }
  57499         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  57500         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  57501             return BCM_E_NOT_FOUND;
  57502         }
  57503         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  57504     } else
  57505 #endif
  57506 #if defined(BCM_TRIDENT_SUPPORT)
  57507     if (BCM_GPORT_IS_NIV_PORT(port)) {
  57508         if (!soc_feature(unit, soc_feature_niv)) {
  57509             return BCM_E_UNAVAIL;
  57510         }
  57511         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  57512         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) {
  57513             return BCM_E_PARAM;
  57514         }
  57515     } else
  57516 #endif /* BCM_TRIDENT_SUPPORT */
  57517 #if defined(BCM_TRIDENT3_SUPPORT)
  57518     if (BCM_GPORT_IS_MIRROR(port)) {
  57519         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  57520             return BCM_E_UNAVAIL;
  57521         }
  57522         if ((match->match == BCM_PORT_MATCH_PORT_VLAN) ||
  57523             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  57524             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  57525 
  57526             SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
  57527             if (SOC_IS_TRIDENT3(unit) &&
  57528                 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
  57529                 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  57530                     (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  57531                     LOG_ERROR(BSL_LS_BCM_PORT,
  57532                               (BSL_META_U(unit,
  57533                           "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \
  57534                            not supported in Cancun 5.1.8 release\n")));
  57535                     return BCM_E_UNAVAIL;
  57536                 }
  57537             } else {
  57538                 if (match->match == BCM_PORT_MATCH_PORT_VLAN) {
  57539                     LOG_ERROR(BSL_LS_BCM_PORT,
  57540                               (BSL_META_U(unit,
  57541                           "BCM_PORT_MATCH_PORT_VLAN match criteria \
  57542                            not supported after Cancun 5.1.8 release\n")));
  57543                     return BCM_E_UNAVAIL;
  57544                 }
  57545 
  57546                 /* check if max I2E class_id */
  57547                 if (match->match_vlan > _BCM_I2E_CLASS_ID_MAX) {
  57548                     LOG_ERROR(BSL_LS_BCM_PORT,
  57549                         (BSL_META_U(unit, " %d exceeds I2E class_id max %d\n"),
  57550                          match->match_vlan,_BCM_I2E_CLASS_ID_MAX));
  57551                     return BCM_E_PARAM;
  57552                 }
  57553             }
  57554 
  57555             bcm_mirror_destination_t_init(&mirror_dest);
  57556             BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port,
  57557                                 &mirror_dest));
  57558             if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) {
  57559                 return BCM_E_PARAM;
  57560             }
  57561         } else {
  57562             return BCM_E_PARAM;
  57563         }
  57564     } else
  57565 #endif /* BCM_TRIDENT3_SUPPORT */
  57566     {
  57567         return BCM_E_PORT;
  57568     }
  57569 
  57570     switch (match->match) {
  57571     case BCM_PORT_MATCH_NONE:
  57572         rv = BCM_E_NONE;
  57573         break;
  57574 #if defined(BCM_TRIDENT2_SUPPORT)
  57575     case BCM_PORT_MATCH_PORT:
  57576         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57577             bcm_vxlan_port_t_init(&vxlan_port);
  57578             vxlan_port.criteria      = BCM_VXLAN_PORT_MATCH_PORT;
  57579             vxlan_port.vxlan_port_id = port;
  57580             vxlan_port.match_port    = match->port;
  57581             BCM_IF_ERROR_RETURN(
  57582                 _bcm_td2_vxlan_match_add(unit, &vxlan_port, vp, 0));
  57583         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57584             bcm_l2gre_port_t_init(&l2gre_port);
  57585             l2gre_port.criteria       = BCM_L2GRE_PORT_MATCH_PORT;
  57586             l2gre_port.l2gre_port_id   = port;
  57587             l2gre_port.match_port           = match->port;
  57588             BCM_IF_ERROR_RETURN(
  57589                 bcm_td2_l2gre_match_add(unit, &l2gre_port, vp, 0));
  57590         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  57591             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57592             bcm_mim_port_t mim_port;
  57593             bcm_mim_port_t_init(&mim_port);
  57594             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT;
  57595             mim_port.mim_port_id = port;
  57596             mim_port.port = match->port;
  57597             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit,
  57598                                  &mim_port, vp, match->vpn));
  57599         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57600 #if defined(BCM_MPLS_SUPPORT)
  57601             bcm_mpls_port_t mpls_port;
  57602             bcm_mpls_port_t_init(&mpls_port);
  57603             mpls_port.criteria       = BCM_MPLS_PORT_MATCH_PORT;
  57604             mpls_port.mpls_port_id   = port;
  57605             mpls_port.port           = match->port;
  57606             BCM_IF_ERROR_RETURN(
  57607                 _bcm_tr_mpls_match_add(unit, &mpls_port, vp, 0, TRUE));
  57608 #endif
  57609         } else if (BCM_GPORT_IS_VLAN_PORT(port)) {
  57610             bcm_vlan_port_t vlan_port;
  57611             bcm_vlan_port_t_init(&vlan_port);
  57612             vlan_port.criteria       = BCM_VLAN_PORT_MATCH_PORT;
  57613             vlan_port.port           = match->port;
  57614             BCM_IF_ERROR_RETURN(
  57615                 bcm_tr2_vlan_vp_match_add(unit, &vlan_port, vp));
  57616 
  57617         } else {
  57618             rv = BCM_E_PARAM;
  57619         }
  57620         break;
  57621 #endif
  57622 
  57623     case BCM_PORT_MATCH_PORT_I2E_CLASS:
  57624     case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE:
  57625 #if defined(BCM_TRIDENT3_SUPPORT)
  57626         if (BCM_GPORT_IS_MIRROR(port)) {
  57627             rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port,
  57628                                             match->match_vlan, match->match);
  57629         } else
  57630 #endif
  57631         {
  57632             rv = BCM_E_UNAVAIL;
  57633         }
  57634         break;
  57635 
  57636     case BCM_PORT_MATCH_PORT_VLAN:
  57637 #if defined(BCM_TRIDENT3_SUPPORT)
  57638         if (BCM_GPORT_IS_MIRROR(port)) {
  57639             rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port,
  57640                                             match->match_vlan, match->match);
  57641             break;
  57642         } else
  57643 #endif /* BCM_TRIDENT3_SUPPORT */
  57644 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57645         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57646             /* match_info translation to vxlan_port */
  57647             bcm_vxlan_port_t_init(&vxlan_port);
  57648             VLAN_CHK_ID(unit, match->match_vlan);
  57649             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN;
  57650             vxlan_port.match_vlan = match->match_vlan;
  57651             vxlan_port.vxlan_port_id = port;
  57652             vxlan_port.match_port = match->port;
  57653 
  57654             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  57655                                             &vxlan_port, vp, match->vpn));
  57656             break;
  57657         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  57658             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57659             bcm_mim_port_t mim_port;
  57660             bcm_mim_port_t_init(&mim_port);
  57661             VLAN_CHK_ID(unit, match->match_vlan);
  57662             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN;
  57663             mim_port.match_vlan = match->match_vlan;
  57664             mim_port.mim_port_id = port;
  57665             mim_port.port = match->port;
  57666             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit,
  57667                                  &mim_port, vp, match->vpn));
  57668             break;
  57669         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  57670             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57671             bcm_mpls_port_t mpls_port;
  57672             bcm_mpls_port_t_init(&mpls_port);
  57673             VLAN_CHK_ID(unit, match->match_vlan);
  57674             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN;
  57675             mpls_port.match_vlan = match->match_vlan;
  57676             mpls_port.mpls_port_id = port;
  57677             mpls_port.port = match->port;
  57678             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  57679                                  &mpls_port, vp, match->vpn, TRUE));
  57680             break;
  57681         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57682             /* match_info translation to L2GRE_port */
  57683             bcm_l2gre_port_t_init(&l2gre_port);
  57684             VLAN_CHK_ID(unit, match->match_vlan);
  57685             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN;
  57686             l2gre_port.match_vlan = match->match_vlan;
  57687             l2gre_port.l2gre_port_id = port;
  57688             l2gre_port.match_port = match->port;
  57689             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  57690                                             &l2gre_port, vp, match->vpn));
  57691             break;
  57692         }
  57693 #endif
  57694 
  57695         /* Add an entry in the VLAN_XLATE table */
  57696         /* Tag actions need to be adjusted by calling the
  57697            bcm_vlan_translate_action_add API for the entry we are creating */
  57698         VLAN_CHK_ID(unit, match->match_vlan);
  57699         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57700             BCM_GPORT_IS_TRUNK(match->port)) {
  57701             /* Use the port from bcm_port_match_info_t instead of the physical
  57702                port from the VP */
  57703             gp = match->port;
  57704         }
  57705 
  57706         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  57707                                             bcmVlanTranslateKeyPortOuter,
  57708                                             match->match_vlan,
  57709                                             BCM_VLAN_INVALID,
  57710                                             vp, match->action,
  57711                                             &existing_updated);
  57712         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57713 #if defined(BCM_TRIUMPH2_SUPPORT)
  57714            _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  57715 #endif
  57716         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  57717 #if defined(BCM_MPLS_SUPPORT)
  57718            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  57719 #endif
  57720         }
  57721         break;
  57722 
  57723     case BCM_PORT_MATCH_PORT_INNER_VLAN:
  57724 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57725         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57726             bcm_vxlan_port_t_init(&vxlan_port);
  57727             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57728             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN;
  57729             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  57730             vxlan_port.vxlan_port_id = port;
  57731             vxlan_port.match_port = match->port;
  57732 
  57733             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  57734                                             &vxlan_port, vp, match->vpn));
  57735             break;
  57736         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  57737             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57738             bcm_mpls_port_t mpls_port;
  57739             bcm_mpls_port_t_init(&mpls_port);
  57740             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57741             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN;
  57742             mpls_port.match_inner_vlan = match->match_inner_vlan;
  57743             mpls_port.mpls_port_id = port;
  57744             mpls_port.port = match->port;
  57745             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  57746                                  &mpls_port, vp, match->vpn, TRUE));
  57747             break;
  57748         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57749             /* match_info translation to L2GRE_port */
  57750             bcm_l2gre_port_t_init(&l2gre_port);
  57751             VLAN_CHK_ID(unit, match->match_vlan);
  57752             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN;
  57753             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  57754             l2gre_port.l2gre_port_id = port;
  57755             l2gre_port.match_port = match->port;
  57756             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  57757                                             &l2gre_port, vp, match->vpn));
  57758             break;
  57759         }
  57760 #endif
  57761         /* Add an entry in the VLAN_XLATE table */
  57762         /* Tag actions need to be adjusted by calling the
  57763          * bcm_vlan_translate_action_add API for the entry we are creating */
  57764         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57765         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57766             BCM_GPORT_IS_TRUNK(match->port)) {
  57767             /* Use the port from bcm_port_match_info_t instead of the physical
  57768                port from the VP */
  57769             gp = match->port;
  57770         }
  57771 
  57772         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  57773                                             bcmVlanTranslateKeyPortInner,
  57774                                             BCM_VLAN_INVALID,
  57775                                             match->match_inner_vlan,
  57776                                             vp, match->action,
  57777                                             &existing_updated);
  57778         break;
  57779 
  57780     case BCM_PORT_MATCH_PORT_VLAN16:
  57781 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57782         if (BCM_GPORT_IS_VXLAN_PORT(port) &&
  57783             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  57784             bcm_vxlan_port_t_init(&vxlan_port);
  57785             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  57786             vxlan_port.match_vlan = match->match_vlan;
  57787             vxlan_port.vxlan_port_id = port;
  57788             vxlan_port.match_port = match->port;
  57789 
  57790             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  57791                                             &vxlan_port, vp, match->vpn));
  57792             break;
  57793         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  57794             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) &&
  57795              ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  57796             bcm_mpls_port_t mpls_port;
  57797             bcm_mpls_port_t_init(&mpls_port);
  57798             mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI;
  57799             mpls_port.match_vlan = match->match_vlan;
  57800             mpls_port.mpls_port_id = port;
  57801             mpls_port.port = match->port;
  57802             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  57803                                  &mpls_port, vp, match->vpn, TRUE));
  57804             break;
  57805         } else if (BCM_GPORT_IS_L2GRE_PORT(port) &&
  57806             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  57807             /* match_info translation to L2GRE_port */
  57808             bcm_l2gre_port_t_init(&l2gre_port);
  57809             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI;
  57810             l2gre_port.match_vlan = match->match_vlan;
  57811             l2gre_port.l2gre_port_id = port;
  57812             l2gre_port.match_port = match->port;
  57813             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  57814                                             &l2gre_port, vp, match->vpn));
  57815             break;
  57816         }
  57817 #endif
  57818         /* Add an entry in the VLAN_XLATE table */
  57819         /* Tag actions need to be adjusted by calling the
  57820            bcm_vlan_translate_action_add API for the entry we are creating */
  57821         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57822             BCM_GPORT_IS_TRUNK(match->port)) {
  57823             /* Use the port from bcm_port_match_info_t instead of the physical
  57824                port from the VP */
  57825             gp = match->port;
  57826         }
  57827 
  57828         /* allow 16 bit VLAN id */
  57829         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  57830                                             bcmVlanTranslateKeyPortOuterTag,
  57831                                             match->match_vlan,
  57832                                             BCM_VLAN_INVALID,
  57833                                             vp, match->action,
  57834                                             &existing_updated);
  57835         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57836 #if defined(BCM_TRIUMPH2_SUPPORT)
  57837            _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  57838 #endif
  57839         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  57840 #if defined(BCM_MPLS_SUPPORT)
  57841            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  57842 #endif
  57843         }
  57844         break;
  57845 
  57846 
  57847     case BCM_PORT_MATCH_PORT_VLAN_STACKED:
  57848 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57849         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57850             /* match_info translation to vxlan_port */
  57851             bcm_vxlan_port_t_init(&vxlan_port);
  57852             VLAN_CHK_ID(unit, match->match_vlan);
  57853             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57854             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED;
  57855             vxlan_port.match_vlan = match->match_vlan;
  57856             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  57857             vxlan_port.vxlan_port_id = port;
  57858             vxlan_port.match_port = match->port;
  57859 
  57860             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  57861                                             &vxlan_port, vp, match->vpn));
  57862             break;
  57863         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  57864             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57865             bcm_mim_port_t mim_port;
  57866             bcm_mim_port_t_init(&mim_port);
  57867             VLAN_CHK_ID(unit, match->match_vlan);
  57868             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57869             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED;
  57870             mim_port.match_vlan = match->match_vlan;
  57871             mim_port.match_inner_vlan = match->match_inner_vlan;
  57872             mim_port.mim_port_id = port;
  57873             mim_port.port = match->port;
  57874             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit,
  57875                                  &mim_port, vp, match->vpn));
  57876             break;
  57877         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  57878             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57879             bcm_mpls_port_t mpls_port;
  57880             bcm_mpls_port_t_init(&mpls_port);
  57881             VLAN_CHK_ID(unit, match->match_vlan);
  57882             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57883             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED;
  57884             mpls_port.match_vlan = match->match_vlan;
  57885             mpls_port.match_inner_vlan = match->match_inner_vlan;
  57886             mpls_port.mpls_port_id = port;
  57887             mpls_port.port = match->port;
  57888             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  57889                                  &mpls_port, vp, match->vpn, TRUE));
  57890             break;
  57891         }  else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57892             /* match_info translation to L2GRE_port */
  57893             bcm_l2gre_port_t_init(&l2gre_port);
  57894             VLAN_CHK_ID(unit, match->match_vlan);
  57895             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57896             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED;
  57897             l2gre_port.match_vlan = match->match_vlan;
  57898             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  57899             l2gre_port.l2gre_port_id = port;
  57900             l2gre_port.match_port = match->port;
  57901             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  57902                                             &l2gre_port, vp, match->vpn));
  57903             break;
  57904         }
  57905 #endif
  57906 
  57907         /* Add an entry in the VLAN_XLATE table */
  57908         /* Tag actions need to be adjusted by calling the
  57909            bcm_vlan_translate_action_add API for the entry we are creating */
  57910         VLAN_CHK_ID(unit, match->match_vlan);
  57911         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57912         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57913             BCM_GPORT_IS_TRUNK(match->port)) {
  57914             /* Use the port from bcm_port_match_info_t instead of the physical
  57915                port from the VP */
  57916             gp = match->port;
  57917         }
  57918         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  57919                                             bcmVlanTranslateKeyPortDouble,
  57920                                             match->match_vlan,
  57921                                             match->match_inner_vlan,
  57922                                             vp, match->action,
  57923                                             &existing_updated);
  57924         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57925 #if defined(BCM_TRIUMPH2_SUPPORT)
  57926         _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  57927 #endif
  57928         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  57929 #if defined(BCM_MPLS_SUPPORT)
  57930            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  57931 #endif
  57932         }
  57933         break;
  57934     case BCM_PORT_MATCH_PORT_VLAN_RANGE:
  57935 #if defined(BCM_TRIUMPH2_SUPPORT)
  57936         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  57937         /* Tag actions need to be adjusted by calling the
  57938            bcm_vlan_translate_action_add API for the entry we are creating */
  57939         VLAN_CHK_ID(unit, match->match_vlan);
  57940         VLAN_CHK_ID(unit, match->match_vlan_max);
  57941         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57942             BCM_GPORT_IS_TRUNK(match->port)) {
  57943             /* Use the port from bcm_port_match_info_t instead of the physical
  57944                port from the VP */
  57945             gp = match->port;
  57946         }
  57947 
  57948         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  57949                                                   match->match_vlan,
  57950                                                   match->match_vlan_max,
  57951                                                   BCM_VLAN_INVALID,
  57952                                                   BCM_VLAN_INVALID,
  57953                                                   vp, match->action);
  57954         if (BCM_SUCCESS(rv)) {
  57955         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57956             _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  57957         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57958 #if defined(BCM_MPLS_SUPPORT)
  57959             bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  57960 #endif
  57961         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57962 #if defined(BCM_TRIDENT2_SUPPORT)
  57963             bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1);
  57964 #endif
  57965         }
  57966         }
  57967 #endif
  57968         break;
  57969     case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE:
  57970 #if defined(BCM_TRIUMPH2_SUPPORT)
  57971         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  57972             return BCM_E_UNAVAIL;
  57973         }
  57974         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  57975         /* Tag actions need to be adjusted by calling the
  57976            bcm_vlan_translate_action_add API for the entry we are creating */
  57977         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57978         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  57979         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57980             BCM_GPORT_IS_TRUNK(match->port)) {
  57981             /* Use the port from bcm_port_match_info_t instead of the physical
  57982                port from the VP */
  57983             gp = match->port;
  57984         }
  57985 
  57986         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  57987                                                   BCM_VLAN_INVALID,
  57988                                                   BCM_VLAN_INVALID,
  57989                                                   match->match_inner_vlan,
  57990                                                   match->match_inner_vlan_max,
  57991                                                   vp, match->action);
  57992         if (BCM_SUCCESS(rv)) {
  57993         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57994             _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  57995         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57996 #if defined(BCM_MPLS_SUPPORT)
  57997             bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  57998 #endif
  57999         }
  58000         }
  58001 #endif
  58002         break;
  58003     case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE:
  58004 #if defined(BCM_TRIUMPH2_SUPPORT)
  58005         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  58006             return BCM_E_UNAVAIL;
  58007         }
  58008         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  58009         /* Tag actions need to be adjusted by calling the
  58010            bcm_vlan_translate_action_add API for the entry we are creating */
  58011         VLAN_CHK_ID(unit, match->match_vlan);
  58012         VLAN_CHK_ID(unit, match->match_vlan_max);
  58013         VLAN_CHK_ID(unit, match->match_inner_vlan);
  58014         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  58015         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58016             BCM_GPORT_IS_TRUNK(match->port)) {
  58017             /* Use the port from bcm_port_match_info_t instead of the physical
  58018                port from the VP */
  58019             gp = match->port;
  58020         }
  58021 
  58022         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  58023                                                   match->match_vlan,
  58024                                                   match->match_vlan_max,
  58025                                                   match->match_inner_vlan,
  58026                                                   match->match_inner_vlan_max,
  58027                                                   vp, match->action);
  58028         if (BCM_SUCCESS(rv)) {
  58029         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58030             _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  58031         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58032 #if defined(BCM_MPLS_SUPPORT)
  58033             bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  58034 #endif
  58035         }  else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58036 #if defined(BCM_TRIDENT2_SUPPORT)
  58037             bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1);
  58038 #endif
  58039         }
  58040         }
  58041 #endif
  58042         break;
  58043 
  58044 #if defined(BCM_TRIUMPH3_SUPPORT)
  58045     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID:
  58046     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN:
  58047         rv = _bcm_esw_extender_port_match_add(unit, match->port,
  58048                                               match->extended_port_vid,
  58049                                               match->match_vlan, vp);
  58050         break;
  58051 #endif
  58052 
  58053 #ifdef BCM_TRIUMPH2_SUPPORT
  58054     case BCM_PORT_MATCH_PORT_PON_TUNNEL:
  58055     case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN:
  58056     case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN:
  58057         if (!BCM_GPORT_IS_VLAN_PORT(port)) {
  58058             return BCM_E_UNAVAIL;
  58059         }
  58060         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58061             BCM_GPORT_IS_TRUNK(match->port)) {
  58062             if (match->port != gp) {
  58063                 return BCM_E_PORT;
  58064             }
  58065         } else if (BCM_GPORT_IS_LOCAL(match->port)) {
  58066             bcm_module_t modid;
  58067             bcm_trunk_t trunk_id;
  58068             bcm_port_t port_num;
  58069             bcm_gport_t modport;
  58070             int id;
  58071 
  58072             BCM_IF_ERROR_RETURN (_bcm_esw_gport_resolve(unit,
  58073                                                match->port, &modid, &port_num, &trunk_id, &id));
  58074             if (trunk_id != BCM_TRUNK_INVALID) {
  58075                 BCM_GPORT_TRUNK_SET(modport, trunk_id);
  58076             } else {
  58077                 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit,
  58078                                                 BCM_STK_MODMAP_GET, modid, port_num, &modid, &port_num));
  58079                 BCM_GPORT_MODPORT_SET(modport, modid, port_num);
  58080             }
  58081 
  58082             if (modport != gp) {
  58083                 return BCM_E_PORT;
  58084             }
  58085         }else {
  58086             return BCM_E_PORT;
  58087         }
  58088 
  58089         VLAN_CHK_ID(unit, match->match_pon_tunnel);
  58090         if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) {
  58091             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnel,
  58092                                               match->match_pon_tunnel,
  58093                                               BCM_VLAN_INVALID,
  58094                                               vp,
  58095                                               match->action);
  58096         } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) {
  58097             VLAN_CHK_ID(unit, match->match_vlan);
  58098             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter,
  58099                                               match->match_pon_tunnel,
  58100                                               match->match_vlan,
  58101                                               vp,
  58102                                               match->action);
  58103         } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) {
  58104             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58105             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner,
  58106                                               match->match_pon_tunnel,
  58107                                               match->match_inner_vlan,
  58108                                               vp,
  58109                                               match->action);
  58110         }
  58111 
  58112         if (BCM_FAILURE(rv)) {
  58113             return rv;
  58114         }
  58115 
  58116         bcm_tr2_vlan_port_match_count_adjust(unit, vp, 1);
  58117         break;
  58118 #endif
  58119 #if defined(BCM_TRIDENT_SUPPORT)
  58120     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF:
  58121     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN:
  58122         rv = _bcm_trident_niv_match_add(unit, match->port,
  58123                                         match->niv_port_vif,
  58124                                         match->match_vlan, vp);
  58125         break;
  58126 #endif /* BCM_TRIDENT_SUPPORT */
  58127 #if defined(BCM_TRX_SUPPORT)
  58128     case BCM_PORT_MATCH_MAC_PORT:
  58129     case BCM_PORT_MATCH_MAC_PORT_CLASS:
  58130         bcm_vlan_match_info_t_init(&vlan_match_info);
  58131         if (match->match == BCM_PORT_MATCH_MAC_PORT) {
  58132             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT;
  58133             vlan_match_info.port = match->port;
  58134         } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) {
  58135             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS;
  58136             vlan_match_info.port_class = match->port_class;
  58137         }
  58138         sal_memcpy(vlan_match_info.src_mac,
  58139                 match->src_mac, sizeof (bcm_mac_t));
  58140         rv = _bcm_trx_vlan_match_action_add(unit, 0,
  58141                 port, &vlan_match_info, match->action);
  58142         break;
  58143 #endif
  58144     default:
  58145         rv = BCM_E_PARAM;
  58146         break;
  58147     }
  58148     return rv;
  58149 #else
  58150     return BCM_E_UNAVAIL;
  58151 #endif
  58152 }
  58153 
  58154 /*
  58155  * Function:
  58156  *      bcm_port_match_delete
  58157  * Purpose:
  58158  *      Remove a match from an existing port
  58159  * Parameters:
  58160  *      unit - (IN) Unit number.
  58161  *      port - (IN) Port or gport
  58162  *      match - (IN) Match criteria
  58163  * Returns:
  58164  *      BCM_E_xxx
  58165  * Notes:
  58166  */
  58167 int
  58168 bcm_esw_port_match_delete(
  58169     int unit,
  58170     bcm_gport_t port,
  58171     bcm_port_match_info_t *match)
  58172 {
  58173 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  58174     int vp=0, rv = BCM_E_NONE;
  58175     bcm_gport_t gp = 0;
  58176 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT)
  58177     _bcm_vp_info_t vp_info;
  58178 #endif
  58179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  58180     bcm_vxlan_port_t vxlan_port;
  58181     bcm_l2gre_port_t l2gre_port;
  58182 #endif
  58183 #if defined(BCM_TRIDENT3_SUPPORT)
  58184     bcm_mirror_destination_t mirror_dest;
  58185     uint32 cancun_ver;
  58186 #endif /* BCM_TRIDENT3_SUPPORT */
  58187 #if defined(BCM_TRX_SUPPORT)
  58188     bcm_vlan_match_info_t vlan_match_info;
  58189 #endif
  58190 
  58191     if (match == NULL) {
  58192         return BCM_E_PARAM;
  58193     }
  58194     /* Make sure port module is initialized. */
  58195     PORT_INIT(unit);
  58196 
  58197     if (BCM_GPORT_IS_MIM_PORT(port)) {
  58198 #if defined(BCM_TRIUMPH2_SUPPORT)
  58199         if (!soc_feature(unit, soc_feature_mim)) {
  58200             return BCM_E_UNAVAIL;
  58201         }
  58202         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  58203         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  58204             return BCM_E_NOT_FOUND;
  58205         }
  58206         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  58207         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58208             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  58209         }
  58210 #endif
  58211     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  58212         if (!soc_feature(unit, soc_feature_mpls)) {
  58213             return BCM_E_UNAVAIL;
  58214         }
  58215         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  58216         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  58217             return BCM_E_NOT_FOUND;
  58218         }
  58219 #if defined(BCM_MPLS_SUPPORT)
  58220         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  58221         if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58222             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  58223                 return BCM_E_UNAVAIL;
  58224             }
  58225         } else {
  58226             BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  58227         }
  58228 #endif
  58229     } else
  58230 #if defined(BCM_TRIDENT2_SUPPORT)
  58231     if (BCM_GPORT_IS_TRUNK(port)) {
  58232         if (!soc_feature(unit, soc_feature_vp_lag)) {
  58233             return BCM_E_UNAVAIL;
  58234         }
  58235         BCM_IF_ERROR_RETURN(
  58236             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  58237                                             &vp));
  58238         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  58239             return BCM_E_NOT_FOUND;
  58240         }
  58241         if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID &&
  58242             match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) {
  58243             return BCM_E_PARAM;
  58244         }
  58245     } else
  58246 #endif /* BCM_TRIDENT2_SUPPORT */
  58247 #if defined(BCM_TRIDENT2_SUPPORT)
  58248     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58249         if (!soc_feature(unit, soc_feature_vxlan)) {
  58250             return BCM_E_UNAVAIL;
  58251         }
  58252         if (match->match == BCM_PORT_MATCH_PORT
  58253             || match->match == BCM_PORT_MATCH_MAC_PORT
  58254             || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE
  58255             || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE
  58256             || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE
  58257             ) {
  58258             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  58259             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  58260                 return BCM_E_NOT_FOUND;
  58261             }
  58262         } else {
  58263             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  58264                 return BCM_E_UNAVAIL;
  58265             }
  58266 
  58267             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  58268             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  58269             if (vp_info.vp_type != _bcmVpTypeVxlan) {
  58270                 return BCM_E_PARAM;
  58271             }
  58272             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58273                 return BCM_E_PARAM;
  58274             }
  58275         }
  58276     } else
  58277 #endif
  58278 #if defined(BCM_TRIDENT2_SUPPORT)
  58279     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58280         if (!soc_feature(unit, soc_feature_l2gre)) {
  58281             return BCM_E_UNAVAIL;
  58282         }
  58283         if (match->match == BCM_PORT_MATCH_PORT) {
  58284             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  58285             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) {
  58286                 return BCM_E_NOT_FOUND;
  58287             }
  58288         } else {
  58289             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  58290                 return BCM_E_UNAVAIL;
  58291             }
  58292 
  58293             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  58294             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  58295 
  58296             if (vp_info.vp_type != _bcmVpTypeL2Gre) {
  58297                 return BCM_E_PARAM;
  58298             }
  58299             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58300                 return BCM_E_PARAM;
  58301             }
  58302         }
  58303     } else
  58304 #endif
  58305 
  58306 #if defined(BCM_TRIUMPH2_SUPPORT)
  58307     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  58308         if ((!soc_feature(unit, soc_feature_lltag)) &&
  58309             (!soc_feature(unit, soc_feature_vlan_vp))) {
  58310             return BCM_E_UNAVAIL;
  58311         }
  58312         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  58313         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  58314             return BCM_E_NOT_FOUND;
  58315         }
  58316         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  58317     } else
  58318 #endif
  58319 #if defined(BCM_TRIDENT_SUPPORT)
  58320     if (BCM_GPORT_IS_NIV_PORT(port)) {
  58321         if (!soc_feature(unit, soc_feature_niv)) {
  58322             return BCM_E_UNAVAIL;
  58323         }
  58324         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  58325         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) {
  58326             return BCM_E_PARAM;
  58327         }
  58328     } else
  58329 #endif /* BCM_TRIDENT_SUPPORT */
  58330 #if defined(BCM_TRIDENT3_SUPPORT)
  58331     if (BCM_GPORT_IS_MIRROR(port)) {
  58332         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  58333             return BCM_E_UNAVAIL;
  58334         }
  58335         if ((match->match == BCM_PORT_MATCH_PORT_VLAN) ||
  58336             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  58337             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  58338 
  58339             SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
  58340             if (SOC_IS_TRIDENT3(unit) &&
  58341                 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
  58342                 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  58343                     (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  58344                     LOG_ERROR(BSL_LS_BCM_PORT,
  58345                               (BSL_META_U(unit,
  58346                           "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \
  58347                            not supported in Cancun 5.1.8 release\n")));
  58348                     return BCM_E_UNAVAIL;
  58349                 }
  58350             } else {
  58351                 if (match->match == BCM_PORT_MATCH_PORT_VLAN) {
  58352                     LOG_ERROR(BSL_LS_BCM_PORT,
  58353                               (BSL_META_U(unit,
  58354                           "BCM_PORT_MATCH_PORT_VLAN match criteria \
  58355                            not supported after Cancun 5.1.8 release\n")));
  58356                     return BCM_E_UNAVAIL;
  58357                 }
  58358             }
  58359 
  58360             bcm_mirror_destination_t_init(&mirror_dest);
  58361             BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port,
  58362                                 &mirror_dest));
  58363             if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) {
  58364                 return BCM_E_PARAM;
  58365             }
  58366         } else {
  58367             return BCM_E_PARAM;
  58368         }
  58369     } else
  58370 #endif /* BCM_TRIDENT3_SUPPORT */
  58371     {
  58372         return BCM_E_PORT;
  58373     }
  58374 
  58375     switch (match->match) {
  58376     case BCM_PORT_MATCH_NONE:
  58377         rv = BCM_E_NONE;
  58378         break;
  58379 #if defined(BCM_TRIDENT2_SUPPORT)
  58380     case BCM_PORT_MATCH_PORT:
  58381         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58382             bcm_vxlan_port_t_init(&vxlan_port);
  58383             vxlan_port.criteria      = BCM_VXLAN_PORT_MATCH_PORT;
  58384             vxlan_port.vxlan_port_id = port;
  58385             vxlan_port.match_port    = match->port;
  58386             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58387         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58388 #if defined(BCM_MPLS_SUPPORT)
  58389             bcm_mpls_port_t mpls_port;
  58390             bcm_mpls_port_t_init(&mpls_port);
  58391             mpls_port.criteria       = BCM_MPLS_PORT_MATCH_PORT;
  58392             mpls_port.mpls_port_id   = port;
  58393             mpls_port.port           = match->port;
  58394             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, vp, &mpls_port, TRUE));
  58395 #endif
  58396         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58397             bcm_l2gre_port_t_init(&l2gre_port);
  58398             l2gre_port.criteria       = BCM_L2GRE_PORT_MATCH_PORT;
  58399             l2gre_port.l2gre_port_id   = port;
  58400             l2gre_port.match_port           = match->port;
  58401             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, &l2gre_port));
  58402         } else if (BCM_GPORT_IS_VLAN_PORT(port)) {
  58403             bcm_vlan_port_t vlan_port;
  58404             bcm_vlan_port_t_init(&vlan_port);
  58405             vlan_port.criteria       = BCM_VLAN_PORT_MATCH_PORT;
  58406             vlan_port.port           = match->port;
  58407             BCM_IF_ERROR_RETURN(
  58408                 bcm_tr2_vlan_vp_match_delete(unit, &vlan_port, vp));
  58409         } else {
  58410             rv = BCM_E_PARAM;
  58411         }
  58412         break;
  58413 #endif
  58414 
  58415     case BCM_PORT_MATCH_PORT_I2E_CLASS:
  58416     case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE:
  58417 #if defined(BCM_TRIDENT3_SUPPORT)
  58418         if (BCM_GPORT_IS_MIRROR(port)) {
  58419             rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port,
  58420                                             match->match_vlan, match->match);
  58421         } else
  58422 #endif
  58423         {
  58424             rv = BCM_E_UNAVAIL;
  58425         }
  58426         break;
  58427 
  58428     case BCM_PORT_MATCH_PORT_VLAN:
  58429 #if defined(BCM_TRIDENT3_SUPPORT)
  58430         if (BCM_GPORT_IS_MIRROR(port)) {
  58431             rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port,
  58432                                                match->match_vlan, match->match);
  58433             break;
  58434         } else
  58435 #endif /* BCM_TRIDENT3_SUPPORT */
  58436 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58437         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58438             /* match_info translation to vxlan_port */
  58439             bcm_vxlan_port_t_init(&vxlan_port);
  58440             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN;
  58441             vxlan_port.match_vlan = match->match_vlan;
  58442             vxlan_port.vxlan_port_id = port;
  58443             vxlan_port.match_port = match->port;
  58444             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58445             break;
  58446         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  58447             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58448             bcm_mim_port_t mim_port;
  58449             bcm_mim_port_t_init(&mim_port);
  58450             VLAN_CHK_ID(unit, match->match_vlan);
  58451             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN;
  58452             mim_port.match_vlan = match->match_vlan;
  58453             mim_port.mim_port_id = port;
  58454             mim_port.port = match->port;
  58455             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit,
  58456                                  vp, mim_port));
  58457             break;
  58458         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  58459             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58460             bcm_mpls_port_t mpls_port;
  58461             bcm_mpls_port_t_init(&mpls_port);
  58462             VLAN_CHK_ID(unit, match->match_vlan);
  58463             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN;
  58464             mpls_port.match_vlan = match->match_vlan;
  58465             mpls_port.mpls_port_id = port;
  58466             mpls_port.port = match->port;
  58467             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  58468                                  vp, &mpls_port, 0));
  58469             break;
  58470         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58471             /* match_info translation to L2GRE_port */
  58472             bcm_l2gre_port_t_init(&l2gre_port);
  58473             VLAN_CHK_ID(unit, match->match_vlan);
  58474             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN;
  58475             l2gre_port.match_vlan = match->match_vlan;
  58476             l2gre_port.l2gre_port_id = port;
  58477             l2gre_port.match_port = match->port;
  58478             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit,vp,
  58479                                             &l2gre_port));
  58480             break;
  58481         }
  58482 #endif
  58483 
  58484         /* Add an entry in the VLAN_XLATE table */
  58485         /* Tag actions need to be adjusted by calling the
  58486            bcm_vlan_translate_action_add API for the entry we are creating */
  58487         VLAN_CHK_ID(unit, match->match_vlan);
  58488         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58489             BCM_GPORT_IS_TRUNK(match->port)) {
  58490             /* Use the port from bcm_port_match_info_t instead of the physical
  58491                port from the VP */
  58492             gp = match->port;
  58493         }
  58494         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  58495                                                bcmVlanTranslateKeyPortOuter,
  58496                                                match->match_vlan,
  58497                                                BCM_VLAN_INVALID,
  58498                                                vp);
  58499 
  58500         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58501 #if defined(BCM_TRIUMPH2_SUPPORT)
  58502            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58503 #endif
  58504         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58505 #if defined(BCM_MPLS_SUPPORT)
  58506            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58507 #endif
  58508         }
  58509         break;
  58510 
  58511     case BCM_PORT_MATCH_PORT_INNER_VLAN:
  58512 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58513         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58514             bcm_vxlan_port_t_init(&vxlan_port);
  58515             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58516             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN;
  58517             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  58518             vxlan_port.vxlan_port_id = port;
  58519             vxlan_port.match_port = match->port;
  58520 
  58521             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58522             break;
  58523         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  58524             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58525             bcm_mpls_port_t mpls_port;
  58526             bcm_mpls_port_t_init(&mpls_port);
  58527             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58528             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN;
  58529             mpls_port.match_inner_vlan = match->match_inner_vlan;
  58530             mpls_port.mpls_port_id = port;
  58531             mpls_port.port = match->port;
  58532             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  58533                                  vp, &mpls_port, 0));
  58534             break;
  58535         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58536             /* match_info translation to L2GRE_port */
  58537             bcm_l2gre_port_t_init(&l2gre_port);
  58538             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58539             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN;
  58540             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  58541             l2gre_port.l2gre_port_id = port;
  58542             l2gre_port.match_port = match->port;
  58543             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  58544                                             &l2gre_port));
  58545             break;
  58546         }
  58547 #endif
  58548         /* Add an entry in the VLAN_XLATE table */
  58549         /* Tag actions need to be adjusted by calling the
  58550          * bcm_vlan_translate_action_add API for the entry we are creating */
  58551         VLAN_CHK_ID(unit, match->match_inner_vlan);
  58552         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58553             BCM_GPORT_IS_TRUNK(match->port)) {
  58554             /* Use the port from bcm_port_match_info_t instead of the physical
  58555                port from the VP */
  58556             gp = match->port;
  58557         }
  58558 
  58559         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  58560                                                bcmVlanTranslateKeyPortInner,
  58561                                                BCM_VLAN_INVALID,
  58562                                                match->match_inner_vlan,
  58563                                                vp);
  58564         break;
  58565 
  58566     case BCM_PORT_MATCH_PORT_VLAN16:
  58567 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58568         if (BCM_GPORT_IS_VXLAN_PORT(port) &&
  58569             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  58570             bcm_vxlan_port_t_init(&vxlan_port);
  58571             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  58572             vxlan_port.match_vlan = match->match_vlan;
  58573             vxlan_port.vxlan_port_id = port;
  58574             vxlan_port.match_port = match->port;
  58575 
  58576             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58577             break;
  58578         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  58579             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58580             bcm_mpls_port_t mpls_port;
  58581             bcm_mpls_port_t_init(&mpls_port);
  58582             mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI;
  58583             mpls_port.match_vlan = match->match_vlan;
  58584             mpls_port.mpls_port_id = port;
  58585             mpls_port.port = match->port;
  58586             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  58587                                  vp, &mpls_port, 0));
  58588             break;
  58589         }  else if (BCM_GPORT_IS_L2GRE_PORT(port) &&
  58590             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  58591             /* match_info translation to L2GRE_port */
  58592             bcm_l2gre_port_t_init(&l2gre_port);
  58593             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI;
  58594             l2gre_port.match_vlan = match->match_vlan;
  58595             l2gre_port.l2gre_port_id = port;
  58596             l2gre_port.match_port = match->port;
  58597             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  58598                                             &l2gre_port));
  58599             break;
  58600         }
  58601 #endif
  58602         /* Add an entry in the VLAN_XLATE table */
  58603         /* Tag actions need to be adjusted by calling the
  58604            bcm_vlan_translate_action_add API for the entry we are creating */
  58605         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58606             BCM_GPORT_IS_TRUNK(match->port)) {
  58607             /* Use the port from bcm_port_match_info_t instead of the physical
  58608                port from the VP */
  58609             gp = match->port;
  58610         }
  58611         /* allow 16 bit VLAN id */
  58612         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  58613                                                bcmVlanTranslateKeyPortOuterTag,
  58614                                                match->match_vlan,
  58615                                                BCM_VLAN_INVALID,
  58616                                                vp);
  58617 
  58618         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58619 #if defined(BCM_TRIUMPH2_SUPPORT)
  58620            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58621 #endif
  58622         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58623 #if defined(BCM_MPLS_SUPPORT)
  58624            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58625 #endif
  58626         }
  58627         break;
  58628     case BCM_PORT_MATCH_PORT_VLAN_STACKED:
  58629 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58630         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58631             /* match_info translation to vxlan_port */
  58632             bcm_vxlan_port_t_init(&vxlan_port);
  58633             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED;
  58634             vxlan_port.match_vlan = match->match_vlan;
  58635             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  58636             vxlan_port.vxlan_port_id = port;
  58637             vxlan_port.match_port = match->port;
  58638             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58639             break;
  58640         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  58641             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58642             bcm_mim_port_t mim_port;
  58643             bcm_mim_port_t_init(&mim_port);
  58644             VLAN_CHK_ID(unit, match->match_vlan);
  58645             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58646             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED;
  58647             mim_port.match_vlan = match->match_vlan;
  58648             mim_port.match_inner_vlan = match->match_inner_vlan;
  58649             mim_port.mim_port_id = port;
  58650             mim_port.port = match->port;
  58651             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit,
  58652                                  vp, mim_port));
  58653             break;
  58654         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  58655             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  58656             bcm_mpls_port_t mpls_port;
  58657             bcm_mpls_port_t_init(&mpls_port);
  58658             VLAN_CHK_ID(unit, match->match_vlan);
  58659             VLAN_CHK_ID(unit, match->match_inner_vlan);
  58660             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED;
  58661             mpls_port.match_vlan = match->match_vlan;
  58662             mpls_port.match_inner_vlan = match->match_inner_vlan;
  58663             mpls_port.mpls_port_id = port;
  58664             mpls_port.port = match->port;
  58665             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  58666                                  vp, &mpls_port, 0));
  58667             break;
  58668         }else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58669             /* match_info translation to L2GRE_port */
  58670             bcm_l2gre_port_t_init(&l2gre_port);
  58671             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED;
  58672             l2gre_port.match_vlan = match->match_vlan;
  58673             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  58674             l2gre_port.l2gre_port_id = port;
  58675             l2gre_port.match_port = match->port;
  58676             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  58677                                             &l2gre_port));
  58678             break;
  58679         }
  58680 #endif
  58681         /* Add an entry in the VLAN_XLATE table */
  58682         /* Tag actions need to be adjusted by calling the
  58683            bcm_vlan_translate_action_add API for the entry we are creating */
  58684         VLAN_CHK_ID(unit, match->match_vlan);
  58685         VLAN_CHK_ID(unit, match->match_inner_vlan);
  58686         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58687             BCM_GPORT_IS_TRUNK(match->port)) {
  58688             /* Use the port from bcm_port_match_info_t instead of the physical
  58689                port from the VP */
  58690             gp = match->port;
  58691         }
  58692         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  58693                                                bcmVlanTranslateKeyPortDouble,
  58694                                                match->match_vlan,
  58695                                                match->match_inner_vlan,
  58696                                                vp);
  58697 
  58698         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58699 #if defined(BCM_TRIUMPH2_SUPPORT)
  58700            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58701 #endif
  58702         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58703 #if defined(BCM_MPLS_SUPPORT)
  58704            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58705 #endif
  58706         }
  58707         break;
  58708     case BCM_PORT_MATCH_PORT_VLAN_RANGE:
  58709 #if defined(BCM_TRIUMPH2_SUPPORT)
  58710         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  58711         /* Tag actions need to be adjusted by calling the
  58712            bcm_vlan_translate_action_add API for the entry we are creating */
  58713         VLAN_CHK_ID(unit, match->match_vlan);
  58714         VLAN_CHK_ID(unit, match->match_vlan_max);
  58715         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58716             BCM_GPORT_IS_TRUNK(match->port)) {
  58717             /* Use the port from bcm_port_match_info_t instead of the physical
  58718                port from the VP */
  58719             gp = match->port;
  58720         }
  58721         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  58722                                                      match->match_vlan,
  58723                                                      match->match_vlan_max,
  58724                                                      BCM_VLAN_INVALID,
  58725                                                      BCM_VLAN_INVALID,
  58726                                                      vp);
  58727         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58728             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58729         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58730 #if defined(BCM_MPLS_SUPPORT)
  58731             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58732 #endif
  58733         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58734 #if defined(BCM_TRIDENT2_SUPPORT)
  58735             bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1);
  58736 #endif
  58737         }
  58738 #endif
  58739         break;
  58740     case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE:
  58741 #if defined(BCM_TRIUMPH2_SUPPORT)
  58742         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  58743             return BCM_E_UNAVAIL;
  58744         }
  58745         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  58746         /* Tag actions need to be adjusted by calling the
  58747            bcm_vlan_translate_action_add API for the entry we are creating */
  58748         VLAN_CHK_ID(unit, match->match_inner_vlan);
  58749         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  58750         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58751             BCM_GPORT_IS_TRUNK(match->port)) {
  58752             /* Use the port from bcm_port_match_info_t instead of the physical
  58753                port from the VP */
  58754             gp = match->port;
  58755         }
  58756         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  58757                                                      BCM_VLAN_INVALID,
  58758                                                      BCM_VLAN_INVALID,
  58759                                                      match->match_inner_vlan,
  58760                                                      match->match_inner_vlan_max,
  58761                                                      vp);
  58762         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58763             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58764         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58765 #if defined(BCM_MPLS_SUPPORT)
  58766             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58767 #endif
  58768         }
  58769 #endif
  58770         break;
  58771     case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE:
  58772 #if defined(BCM_TRIUMPH2_SUPPORT)
  58773         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  58774             return BCM_E_UNAVAIL;
  58775         }
  58776         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  58777         /* Tag actions need to be adjusted by calling the
  58778            bcm_vlan_translate_action_add API for the entry we are creating */
  58779         VLAN_CHK_ID(unit, match->match_vlan);
  58780         VLAN_CHK_ID(unit, match->match_vlan_max);
  58781         VLAN_CHK_ID(unit, match->match_inner_vlan);
  58782         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  58783         if (BCM_GPORT_IS_MODPORT(match->port) ||
  58784             BCM_GPORT_IS_TRUNK(match->port)) {
  58785             /* Use the port from bcm_port_match_info_t instead of the physical
  58786                port from the VP */
  58787             gp = match->port;
  58788         }
  58789         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  58790                                                      match->match_vlan,
  58791                                                      match->match_vlan_max,
  58792                                                      match->match_inner_vlan,
  58793                                                      match->match_inner_vlan_max,
  58794                                                      vp);
  58795         if (BCM_GPORT_IS_MIM_PORT(port)) {
  58796             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  58797         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58798 #if defined(BCM_MPLS_SUPPORT)
  58799             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  58800 #endif
  58801         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58802 #if defined(BCM_TRIDENT2_SUPPORT)
  58803             bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1);
  58804 #endif
  58805         }
  58806 #endif
  58807         break;
  58808 
  58809 #if defined(BCM_TRIUMPH3_SUPPORT)
  58810     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID:
  58811     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN:
  58812         rv = _bcm_esw_extender_port_match_delete(unit, match->port,
  58813                                                  match->extended_port_vid,
  58814                                                  match->match_vlan, vp);
  58815         break;
  58816 #endif
  58817 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58818     case BCM_PORT_MATCH_PORT_PCP_VLAN:
  58819         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58820             /* match_info translation to vxlan_port */
  58821             bcm_vxlan_port_t_init(&vxlan_port);
  58822             VLAN_CHK_ID(unit, match->match_vlan);
  58823             if ((match->match_vlan & 0x0fff) != 0) {
  58824                 return BCM_E_UNAVAIL;
  58825             }
  58826             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  58827             vxlan_port.match_vlan = (match->match_vlan & 0xf000);
  58828             vxlan_port.vxlan_port_id = port;
  58829             vxlan_port.match_port = match->port;
  58830             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  58831             break;
  58832         } else {
  58833             rv = BCM_E_PARAM;
  58834         }
  58835         break;
  58836 #endif
  58837 #ifdef BCM_TRIUMPH2_SUPPORT
  58838         case BCM_PORT_MATCH_PORT_PON_TUNNEL:
  58839         case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN:
  58840         case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN:
  58841             if (!BCM_GPORT_IS_VLAN_PORT(port)) {
  58842                 return BCM_E_UNAVAIL;
  58843             }
  58844             if (match->port != gp) {
  58845                 return BCM_E_PORT;
  58846             }
  58847 
  58848             VLAN_CHK_ID(unit, match->match_pon_tunnel);
  58849             if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) {
  58850                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnel,
  58851                                                   match->match_pon_tunnel,
  58852                                                   BCM_VLAN_INVALID,
  58853                                                   vp);
  58854             } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) {
  58855                 VLAN_CHK_ID(unit, match->match_vlan);
  58856                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter,
  58857                                                   match->match_pon_tunnel,
  58858                                                   match->match_vlan,
  58859                                                   vp);
  58860             } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) {
  58861                 VLAN_CHK_ID(unit, match->match_pon_tunnel);
  58862                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner,
  58863                                                   match->match_pon_tunnel,
  58864                                                   match->match_inner_vlan,
  58865                                                   vp);
  58866             }
  58867 
  58868             if (BCM_FAILURE(rv)) {
  58869                 return rv;
  58870             }
  58871 
  58872             bcm_tr2_vlan_port_match_count_adjust(unit, vp, -1);
  58873             break;
  58874 #endif
  58875 #if defined(BCM_TRIDENT_SUPPORT)
  58876     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF:
  58877     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN:
  58878         rv = _bcm_trident_niv_match_delete(unit, match->port,
  58879                                            match->niv_port_vif,
  58880                                            match->match_vlan, NULL);
  58881     break;
  58882 #endif /* BCM_TRIDENT_SUPPORT */
  58883 #if defined(BCM_TRX_SUPPORT)
  58884     case BCM_PORT_MATCH_MAC_PORT:
  58885     case BCM_PORT_MATCH_MAC_PORT_CLASS:
  58886         bcm_vlan_match_info_t_init(&vlan_match_info);
  58887         if (match->match == BCM_PORT_MATCH_MAC_PORT) {
  58888             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT;
  58889             vlan_match_info.port = match->port;
  58890         } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) {
  58891             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS;
  58892             vlan_match_info.port_class = match->port_class;
  58893         }
  58894         sal_memcpy(vlan_match_info.src_mac,
  58895                 match->src_mac, sizeof (bcm_mac_t));
  58896         rv = _bcm_trx_vlan_match_action_delete(unit,
  58897                 port, &vlan_match_info);
  58898         break;
  58899 #endif
  58900     default:
  58901         rv = BCM_E_PARAM;
  58902         break;
  58903     }
  58904     return rv;
  58905 #else
  58906     return BCM_E_UNAVAIL;
  58907 #endif
  58908 }
  58909 
  58910 /*
  58911  * Function:
  58912  *      bcm_port_match_replace
  58913  * Purpose:
  58914  *      Replace an old match with a new one for an existing port
  58915  * Parameters:
  58916  *      unit - (IN) Unit number.
  58917  *      port - (IN) Port or gport
  58918  *      old_match - (IN) Old match criteria
  58919  *      new_match - (IN) New match criteria
  58920  * Returns:
  58921  *      BCM_E_xxx
  58922  * Notes:
  58923  */
  58924 int
  58925 bcm_esw_port_match_replace(
  58926     int unit,
  58927     bcm_gport_t port,
  58928     bcm_port_match_info_t *old_match,
  58929     bcm_port_match_info_t *new_match)
  58930 {
  58931 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  58932     int rv = BCM_E_NONE;
  58933     /* Make sure port module is initialized. */
  58934     PORT_INIT(unit);
  58935     rv = bcm_esw_port_match_delete(unit, port, old_match);
  58936     if (BCM_SUCCESS(rv)) {
  58937         rv = bcm_esw_port_match_add(unit, port, new_match);
  58938     }
  58939     return rv;
  58940 #else
  58941     return BCM_E_UNAVAIL;
  58942 #endif
  58943 }
  58944 
  58945 extern void
  58946 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan,
  58947                                      bcm_vlan_t *max_vlan, uint32 index);
  58948 
  58949 int _bcm_esw_port_vp_gport_check(bcm_gport_t port,
  58950     int vp)
  58951 {
  58952     int matched = 0;
  58953     if (BCM_GPORT_IS_MIM_PORT(port)) {
  58954             if (vp == BCM_GPORT_MIM_PORT_ID_GET(port)) {
  58955                 matched = 1;
  58956             }
  58957         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  58958             if (vp == BCM_GPORT_MPLS_PORT_ID_GET(port)) {
  58959                 matched = 1;
  58960             }
  58961         }
  58962 #if defined(BCM_TRIDENT2_SUPPORT)
  58963         else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  58964             if (vp == BCM_GPORT_VXLAN_PORT_ID_GET(port)) {
  58965                 matched = 1;
  58966             }
  58967         }
  58968 #endif
  58969 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  58970         else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  58971             if (vp == BCM_GPORT_L2GRE_PORT_ID_GET(port)) {
  58972                 matched = 1;
  58973             }
  58974         }
  58975 #endif
  58976 #if defined(BCM_TRIUMPH2_SUPPORT)
  58977         else if(BCM_GPORT_IS_VLAN_PORT(port)) {
  58978             if (vp == BCM_GPORT_VLAN_PORT_ID_GET(port)) {
  58979                 matched = 1;
  58980             }
  58981         }
  58982 #endif
  58983     return matched;
  58984 }
  58985 /*
  58986  * Function:
  58987  *      bcm_port_match_multi_get
  58988  * Purpose:
  58989  *      Get all the matches for an existing port
  58990  * Parameters:
  58991  *      unit - (IN) Unit number.
  58992  *      port - (IN) Port or gport
  58993  *      size - (IN) Number of elements in match array
  58994  *      match_array - (OUT) Match array
  58995  *      count - (OUT) Match count
  58996  * Returns:
  58997  *      BCM_E_xxx
  58998  * Notes:
  58999  */
  59000 int
  59001 bcm_esw_port_match_multi_get(
  59002     int unit,
  59003     bcm_gport_t port,
  59004     int size,
  59005     bcm_port_match_info_t *match_array,
  59006     int *count)
  59007 {
  59008 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  59009     int id, vp, prof_idx, i, j, index_min, index_max, ctr, rv = BCM_E_NONE;
  59010     int stm_idx = 0;
  59011     int key_type_value = 0, key_type = 0;
  59012     uint32 matched;
  59013     uint8 *vlan_xlate_buf = NULL; /* VLAN_XLATE DMA buffer */
  59014     uint8 *source_trunk_map_buf = NULL; /* SOURCE_TRUNK_MAP DMA buffer */
  59015     source_trunk_map_table_entry_t *source_trunk_map;
  59016     bcm_gport_t gp;
  59017     bcm_vlan_t min_vlan[8], max_vlan[8];
  59018     bcm_module_t mod_out, mod_in;
  59019     bcm_port_t port_out, port_in;
  59020     bcm_trunk_t trunk_id;
  59021     int mpls_action;
  59022     soc_mem_t mem;
  59023 #if defined(BCM_TRIUMPH3_SUPPORT)
  59024     vlan_xlate_entry_t vent;
  59025 #endif
  59026     bcm_vlan_action_set_t *action;
  59027     int profile_idx;
  59028     void *entry;
  59029 
  59030     bcm_trunk_member_t *member_array = NULL;
  59031 
  59032     /* Parameter checks */
  59033     if ((size < 0) || (count == NULL)) {
  59034         return BCM_E_PARAM;
  59035     }
  59036     if ((size > 0) && (match_array == NULL)) {
  59037         return BCM_E_PARAM;
  59038     }
  59039 
  59040     /* Make sure port module is initialized. */
  59041     PORT_INIT(unit);
  59042 
  59043     if (BCM_GPORT_IS_MIM_PORT(port)) {
  59044         if (!soc_feature(unit, soc_feature_mim)) {
  59045             return BCM_E_UNAVAIL;
  59046         }
  59047         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  59048         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  59049             return BCM_E_NOT_FOUND;
  59050         }
  59051         BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  59052     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  59053         if (!soc_feature(unit, soc_feature_mpls)) {
  59054             return BCM_E_UNAVAIL;
  59055         }
  59056         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  59057         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  59058             return BCM_E_NOT_FOUND;
  59059         }
  59060 #if defined(BCM_MPLS_SUPPORT)
  59061         BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  59062 #endif
  59063 
  59064     } else
  59065 #if defined(BCM_TRIDENT2_SUPPORT)
  59066     if (BCM_GPORT_IS_TRUNK(port)) {
  59067         if (!soc_feature(unit, soc_feature_vp_lag)) {
  59068             return BCM_E_UNAVAIL;
  59069         }
  59070         return _bcm_esw_trunk_match_multi_get(unit, BCM_GPORT_TRUNK_GET(port),
  59071                                               size, match_array, count);
  59072     } else
  59073 #endif /* BCM_TRIDENT2_SUPPORT */
  59074 #if defined(BCM_TRIDENT2_SUPPORT)
  59075     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  59076 
  59077         vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  59078         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  59079             return BCM_E_NOT_FOUND;
  59080         }
  59081 
  59082         BCM_GPORT_VXLAN_PORT_ID_SET(gp,vp);
  59083     } else
  59084 #endif
  59085 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  59086     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  59087         _bcm_vp_info_t vp_info;
  59088 
  59089         if (!soc_feature(unit, soc_feature_vp_sharing)) {
  59090             return BCM_E_UNAVAIL;
  59091         }
  59092         vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  59093 
  59094         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  59095         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  59096             return BCM_E_NOT_FOUND;
  59097         }
  59098 
  59099         BCM_GPORT_L2GRE_PORT_ID_SET(gp,vp);
  59100     } else
  59101 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  59102 #if defined(BCM_TRIUMPH2_SUPPORT)
  59103     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  59104         if (!soc_feature(unit, soc_feature_lltag)) {
  59105             return BCM_E_UNAVAIL;
  59106         }
  59107         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  59108         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
  59109             return BCM_E_NOT_FOUND;
  59110         }
  59111         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  59112     } else
  59113 #endif
  59114 #if defined(BCM_TRIDENT_SUPPORT)
  59115     if (BCM_GPORT_IS_NIV_PORT(port)) {
  59116         if (!soc_feature(unit, soc_feature_niv)) {
  59117             return BCM_E_UNAVAIL;
  59118         }
  59119         return _bcm_td_port_vif_match_multi_get(unit, port,
  59120                                                 size, match_array, count);
  59121     } else
  59122 #endif /* BCM_TRIDENT_SUPPORT */
  59123 #if defined(BCM_TRIDENT3_SUPPORT)
  59124     if (BCM_GPORT_IS_MIRROR(port)) {
  59125         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  59126             return BCM_E_UNAVAIL;
  59127         }
  59128         return _bcm_mirror_port_match_multi_get(unit, port, size, match_array,
  59129                                                 count);
  59130     } else
  59131 #endif /* BCM_TRIDENT3_SUPPORT */
  59132     {
  59133         return BCM_E_PORT;
  59134     }
  59135 
  59136     rv = _bcm_esw_gport_resolve(unit, gp, &mod_out, &port_out, &trunk_id, &id);
  59137     if (BCM_FAILURE(rv)) {
  59138         goto cleanup;
  59139     }
  59140 #if defined(BCM_TRIUMPH3_SUPPORT)
  59141     if (SOC_IS_TRIUMPH3(unit)) {
  59142         mem = VLAN_XLATE_EXTDm;
  59143     } else
  59144 #endif
  59145 #if defined(BCM_TRIDENT3_SUPPORT)
  59146     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  59147         mem = VLAN_XLATE_1_DOUBLEm;
  59148     } else
  59149 #endif
  59150     {
  59151         mem = VLAN_XLATEm;
  59152     }
  59153 
  59154     /* DMA the relevant tables for traversal */
  59155     vlan_xlate_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
  59156                               "VLAN_XLATE buffer");
  59157     if (NULL == vlan_xlate_buf) {
  59158         rv = BCM_E_MEMORY;
  59159         goto cleanup;
  59160     }
  59161 
  59162     index_min = soc_mem_index_min(unit, mem);
  59163     index_max = soc_mem_index_max(unit, mem);
  59164     if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
  59165                                  index_min, index_max,
  59166                                  vlan_xlate_buf)) < 0 ) {
  59167         goto cleanup;
  59168     }
  59169     source_trunk_map_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES
  59170                                  (unit, SOURCE_TRUNK_MAP_TABLEm),
  59171                                  "SOURCE_TRUNK_MAP_TABLE buffer");
  59172     if (NULL == source_trunk_map_buf) {
  59173         rv = BCM_E_MEMORY;
  59174         goto cleanup;
  59175     }
  59176     index_min = soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm);
  59177     index_max = soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm);
  59178     if ((rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY,
  59179                                  index_min, index_max,
  59180                                  source_trunk_map_buf)) < 0 ) {
  59181         goto cleanup;
  59182     }
  59183 
  59184     ctr = 0;
  59185     /* Get all VLAN_XLATE matches */
  59186     index_min = soc_mem_index_min(unit, mem);
  59187     index_max = soc_mem_index_max(unit, mem);
  59188     for (i = index_min; i <= index_max; i++) {
  59189         if ((size != 0) && (size <= ctr)) {
  59190             break;
  59191         }
  59192         if (SOC_IS_TRIUMPH3(unit)) {
  59193             mem = VLAN_XLATE_EXTDm;
  59194         }
  59195         entry = soc_mem_table_idx_to_pointer
  59196                 (unit, mem, void *, vlan_xlate_buf, i);
  59197 #if defined(BCM_TRIUMPH3_SUPPORT)
  59198         if (SOC_IS_TRIUMPH3(unit)) {
  59199             int key_type;
  59200 
  59201             /* double wide entry should always start at double wide boundary */
  59202             key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPE_0f);
  59203 
  59204             /* if key type is odd number, then it is double wide entry */
  59205             if (!(key_type & 1)) {
  59206                 continue;
  59207             }
  59208             mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf);
  59209             vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf);
  59210             sal_memset(&vent, 0, sizeof(vent));
  59211             rv = _bcm_tr3_vxlate_extd2vxlate(unit, (vlan_xlate_extd_entry_t *)entry, &vent, 0);
  59212             if (rv != BCM_E_NONE) {
  59213                 goto cleanup;
  59214             }
  59215             entry = &vent;
  59216             mem = VLAN_XLATEm;
  59217         } else
  59218 #endif  /* BCM_TRIUMPH3_SUPPORT */
  59219         {
  59220             mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf);
  59221             vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf);
  59222         }
  59223 
  59224 #if defined(BCM_TRIDENT3_SUPPORT)
  59225         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  59226             if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_0f) != 3) {
  59227                 continue;
  59228             }
  59229             if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_1f) != 7) {
  59230                 continue;
  59231             }
  59232         }
  59233 #endif
  59234 
  59235         if (SOC_MEM_FIELD_VALID(unit, mem, VALIDf)) {
  59236             if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) {
  59237                 continue;
  59238             }
  59239         }
  59240 
  59241         if (!(mpls_action & 0x1)) {
  59242             continue; /* Entry is not for an SVP */
  59243         }
  59244 
  59245         key_type_value = (int)soc_mem_field32_get(unit, mem, entry, KEY_TYPEf);
  59246 
  59247         rv = _bcm_esw_vlan_xlate_key_type_get(unit,key_type_value,&key_type);
  59248         if (rv != BCM_E_NONE) {
  59249             goto cleanup;
  59250         }
  59251 
  59252         matched = _bcm_esw_port_vp_gport_check(port, vp);
  59253 
  59254         if (matched) {
  59255             soc_field_t field;
  59256             int port_count;
  59257             int tid;
  59258             int gport_id;
  59259             int outer_vlan_range_found = 0, inner_vlan_range_found = 0;
  59260             ctr++;
  59261             if (size >= ctr) {
  59262                 switch (key_type) {
  59263                 case VLXLT_HASH_KEY_TYPE_OVID:
  59264                     match_array->match = BCM_PORT_MATCH_PORT_VLAN;
  59265                     match_array->match_vlan =
  59266                         soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf);
  59267 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  59268                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  59269                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  59270                             (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)) == 0) {
  59271                             match_array->vpn = 0;
  59272                         } else {
  59273                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  59274                                 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf));
  59275                         }
  59276                     } else {
  59277                         match_array->vpn = 0;
  59278                     }
  59279 #endif
  59280                     /* Check if this match is a VLAN range match */
  59281                     if (BCM_TRUNK_INVALID != trunk_id) {
  59282                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  59283                                                &port_count);
  59284                         if (BCM_FAILURE(rv)) {
  59285                             goto cleanup;
  59286                         }
  59287 
  59288                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  59289                                 "trunk member array");
  59290                         if (member_array == NULL) {
  59291                             rv = BCM_E_MEMORY;
  59292                             goto cleanup;
  59293                         }
  59294                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  59295 
  59296                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  59297                                 member_array, &port_count);
  59298                         if (BCM_FAILURE(rv)) {
  59299                             goto cleanup;
  59300                         }
  59301 
  59302                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  59303                                 &mod_out, &port_out, &tid, &gport_id);
  59304                         if (BCM_FAILURE(rv)) {
  59305                             goto cleanup;
  59306                         }
  59307 
  59308                     }
  59309                     rv = _bcm_esw_src_mod_port_table_index_get(
  59310                                 unit, mod_out, port_out, &stm_idx);
  59311                     if (BCM_FAILURE(rv)) {
  59312                         goto cleanup;
  59313                     }
  59314 
  59315                     source_trunk_map = soc_mem_table_idx_to_pointer
  59316                                           (unit, SOURCE_TRUNK_MAP_TABLEm,
  59317                                            source_trunk_map_table_entry_t *,
  59318                                            source_trunk_map_buf, stm_idx);
  59319                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  59320                         OUTER_VLAN_RANGE_IDXf)) {
  59321                         field = OUTER_VLAN_RANGE_IDXf;
  59322                     } else {
  59323                         field = VLAN_RANGE_IDXf;
  59324                     }
  59325                     prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  59326                                          source_trunk_map, field);
  59327                     _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  59328                                                         max_vlan, prof_idx);
  59329                     for (j = 0; j < 8; j++) {
  59330                         if (min_vlan[j] == match_array->match_vlan) {
  59331                             match_array->match_vlan_max = max_vlan[j];
  59332                             match_array->match =
  59333                                        BCM_PORT_MATCH_PORT_VLAN_RANGE;
  59334                             break; /* Found a VLAN range match */
  59335                         }
  59336                     }
  59337                     if (j == 8) {
  59338                         match_array->match = BCM_PORT_MATCH_PORT_VLAN;
  59339                     }
  59340                     if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) {
  59341                         trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf);
  59342                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  59343                     } else {
  59344                         mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf);
  59345                         port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf);
  59346 
  59347                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  59348                                         mod_in, port_in, &mod_out, &port_out);
  59349                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  59350                     }
  59351                     match_array->port = gp;
  59352                     match_array++;
  59353                     break;
  59354                 case VLXLT_HASH_KEY_TYPE_IVID:
  59355                     match_array->match = BCM_PORT_MATCH_PORT_INNER_VLAN;
  59356                     match_array->match_inner_vlan =
  59357                         soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf);
  59358 
  59359 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  59360                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  59361                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  59362                             (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf) == 0)) {
  59363 
  59364                             match_array->vpn = 0;
  59365                         } else {
  59366                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  59367                                 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf));
  59368 
  59369                         }
  59370                     } else {
  59371                         match_array->vpn = 0;
  59372                     }
  59373 #endif
  59374                     /* Check if this match is a VLAN range match */
  59375                     if (BCM_TRUNK_INVALID != trunk_id) {
  59376                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  59377                                                &port_count);
  59378                         if (BCM_FAILURE(rv)) {
  59379                             goto cleanup;
  59380                         }
  59381 
  59382                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  59383                                 "trunk member array");
  59384                         if (member_array == NULL) {
  59385                             rv = BCM_E_MEMORY;
  59386                             goto cleanup;
  59387                         }
  59388                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  59389 
  59390                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  59391                                 member_array, &port_count);
  59392                         if (BCM_FAILURE(rv)) {
  59393                             goto cleanup;
  59394                         }
  59395 
  59396                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  59397                                 &mod_out, &port_out, &tid, &gport_id);
  59398                         if (BCM_FAILURE(rv)) {
  59399                             goto cleanup;
  59400                         }
  59401 
  59402                     }
  59403 
  59404                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  59405                         INNER_VLAN_RANGE_IDXf)) {
  59406 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  59407                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  59408                             int is_local;
  59409                             bcm_module_t modid = mod_out;
  59410 
  59411                             rv = _bcm_esw_stk_modmap_map(
  59412                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  59413                                     &mod_out, NULL);
  59414                             if (BCM_SUCCESS(rv)) {
  59415                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  59416                                                              &is_local);
  59417                             }
  59418                             if (BCM_SUCCESS(rv)) {
  59419                                 rv = _bcm_esw_src_modid_base_index_get(
  59420                                         unit, modid, is_local, &stm_idx);
  59421                             }
  59422                             if (BCM_FAILURE(rv)) {
  59423                                 goto cleanup;
  59424                             }
  59425                             stm_idx += port_out;
  59426                         } else
  59427 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  59428                         {
  59429                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  59430                                        + port_out;
  59431                         }
  59432                         source_trunk_map =
  59433                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  59434                                                          source_trunk_map_table_entry_t *,
  59435                                                          source_trunk_map_buf,
  59436                                                          stm_idx);
  59437                         field = INNER_VLAN_RANGE_IDXf;
  59438                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  59439                                              source_trunk_map, field);
  59440                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  59441                                                             max_vlan, prof_idx);
  59442                         for (j = 0; j < 8; j++) {
  59443                             if (min_vlan[j] == match_array->match_inner_vlan) {
  59444                                 match_array->match_inner_vlan_max = max_vlan[j];
  59445                                 match_array->match =
  59446                                            BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE;
  59447                                 break; /* Found a VLAN range match */
  59448                             }
  59449                         }
  59450                     }
  59451                     if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) {
  59452                         trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf);
  59453                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  59454                     } else {
  59455                         mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf);
  59456                         port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf);
  59457 
  59458                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  59459                                         mod_in, port_in, &mod_out, &port_out);
  59460                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  59461                     }
  59462                     match_array->port = gp;
  59463                     match_array++;
  59464                     break;
  59465                 case VLXLT_HASH_KEY_TYPE_PRI_CFI:
  59466                     match_array->match = BCM_PORT_MATCH_PORT_VLAN16;
  59467                     match_array->match_vlan =
  59468                         soc_mem_field32_get(unit, mem, entry, OTAGf);
  59469 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  59470                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  59471                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  59472                             (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) {
  59473                             match_array->vpn = 0;
  59474                         } else {
  59475                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  59476                                 soc_mem_field32_get(unit, mem, entry, VFIf));
  59477                         }
  59478                     } else {
  59479                         match_array->vpn = 0;
  59480                     }
  59481 #endif
  59482                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  59483                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  59484                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  59485                     } else {
  59486                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  59487                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  59488 
  59489                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  59490                                         mod_in, port_in, &mod_out, &port_out);
  59491                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  59492                     }
  59493                     match_array->port = gp;
  59494                     match_array++;
  59495                     break;
  59496                 case VLXLT_HASH_KEY_TYPE_IVID_OVID:
  59497                     match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED;
  59498                     match_array->match_vlan =
  59499                         soc_mem_field32_get(unit, mem, entry, OVIDf);
  59500                     match_array->match_inner_vlan =
  59501                         soc_mem_field32_get(unit, mem, entry, IVIDf);
  59502 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  59503                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  59504                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  59505                             (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) {
  59506                             match_array->vpn = 0;
  59507                         } else {
  59508                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  59509                                 soc_mem_field32_get(unit, mem, entry, VFIf));
  59510                         }
  59511                     } else {
  59512                         match_array->vpn = 0;
  59513                     }
  59514 #endif
  59515 
  59516                     /* Check if this match is a VLAN range match */
  59517                     if (BCM_TRUNK_INVALID != trunk_id) {
  59518                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  59519                                                &port_count);
  59520                         if (BCM_FAILURE(rv)) {
  59521                             goto cleanup;
  59522                         }
  59523 
  59524                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  59525                                 "trunk member array");
  59526                         if (member_array == NULL) {
  59527                             rv = BCM_E_MEMORY;
  59528                             goto cleanup;
  59529                         }
  59530                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  59531 
  59532                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  59533                                 member_array, &port_count);
  59534                         if (BCM_FAILURE(rv)) {
  59535                             goto cleanup;
  59536                         }
  59537 
  59538                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  59539                                 &mod_out, &port_out, &tid, &gport_id);
  59540                         if (BCM_FAILURE(rv)) {
  59541                             goto cleanup;
  59542                         }
  59543 
  59544                     }
  59545                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  59546                         OUTER_VLAN_RANGE_IDXf)) {
  59547 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  59548                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  59549                             int is_local;
  59550                             bcm_module_t modid = mod_out;
  59551 
  59552                             rv = _bcm_esw_stk_modmap_map(
  59553                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  59554                                     &mod_out, NULL);
  59555                             if (BCM_SUCCESS(rv)) {
  59556                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  59557                                                              &is_local);
  59558                             }
  59559                             if (BCM_SUCCESS(rv)) {
  59560                                 rv = _bcm_esw_src_modid_base_index_get(
  59561                                         unit, modid, is_local, &stm_idx);
  59562                             }
  59563                             if (BCM_FAILURE(rv)) {
  59564                                 goto cleanup;
  59565                             }
  59566                             stm_idx += port_out;
  59567                         } else
  59568 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  59569                         {
  59570                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  59571                                        + port_out;
  59572                         }
  59573                         source_trunk_map =
  59574                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  59575                                                          source_trunk_map_table_entry_t *,
  59576                                                          source_trunk_map_buf,
  59577                                                          stm_idx);
  59578                         field = OUTER_VLAN_RANGE_IDXf;
  59579                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  59580                                              source_trunk_map, field);
  59581                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  59582                                                             max_vlan, prof_idx);
  59583                         for (j = 0; j < 8; j++) {
  59584                             if (min_vlan[j] == match_array->match_vlan) {
  59585                                 match_array->match_vlan_max = max_vlan[j];
  59586                                 outer_vlan_range_found = 1;
  59587                                 break; /* Found a VLAN range match */
  59588                             }
  59589                         }
  59590                     }
  59591 
  59592                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  59593                         INNER_VLAN_RANGE_IDXf)) {
  59594 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  59595                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  59596                             int is_local;
  59597                             bcm_module_t modid = mod_out;
  59598 
  59599                             rv = _bcm_esw_stk_modmap_map(
  59600                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  59601                                     &mod_out, NULL);
  59602                             if (BCM_SUCCESS(rv)) {
  59603                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  59604                                                              &is_local);
  59605                             }
  59606                             if (BCM_SUCCESS(rv)) {
  59607                                 rv = _bcm_esw_src_modid_base_index_get(
  59608                                         unit, modid, is_local, &stm_idx);
  59609                             }
  59610                             if (BCM_FAILURE(rv)) {
  59611                                 goto cleanup;
  59612                             }
  59613                             stm_idx += port_out;
  59614                         } else
  59615 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  59616                         {
  59617                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  59618                                        + port_out;
  59619                         }
  59620                         source_trunk_map =
  59621                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  59622                                                          source_trunk_map_table_entry_t *,
  59623                                                          source_trunk_map_buf,
  59624                                                          stm_idx);
  59625                         field = INNER_VLAN_RANGE_IDXf;
  59626                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  59627                                              source_trunk_map, field);
  59628                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  59629                                                             max_vlan, prof_idx);
  59630                         for (j = 0; j < 8; j++) {
  59631                             if (min_vlan[j] == match_array->match_inner_vlan) {
  59632                                 match_array->match_inner_vlan_max = max_vlan[j];
  59633                                 inner_vlan_range_found = 1;
  59634                                 break; /* Found a VLAN range match */
  59635                             }
  59636                         }
  59637                     }
  59638                     if (inner_vlan_range_found && outer_vlan_range_found) {
  59639                         match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE;
  59640                     }
  59641 
  59642                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  59643                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  59644                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  59645                     } else {
  59646                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  59647                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  59648 
  59649                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  59650                                         mod_in, port_in, &mod_out, &port_out);
  59651                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  59652                     }
  59653                     match_array->port = gp;
  59654                     match_array++;
  59655                     break;
  59656 #if defined (BCM_TRIUMPH2_SUPPORT)
  59657                 case VLXLT_HASH_KEY_TYPE_LLVID:
  59658                 case VLXLT_HASH_KEY_TYPE_LLVID_OVID:
  59659                 case VLXLT_HASK_KEY_TYPE_LLVID_IVID:
  59660                     if (key_type == VLXLT_HASH_KEY_TYPE_LLVID) {
  59661                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL;
  59662                     } else if (key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) {
  59663                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN;
  59664                     } else {
  59665                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN;
  59666                     }
  59667 
  59668                     match_array->match_pon_tunnel =
  59669                         soc_mem_field32_get(unit, mem, entry, LLTAG__LLVIDf);
  59670                     match_array->match_inner_vlan =
  59671                         soc_mem_field32_get(unit, mem, entry, LLTAG__IVIDf);
  59672                     match_array->match_vlan =
  59673                         soc_mem_field32_get(unit, mem, entry, LLTAG__OVIDf);
  59674 
  59675                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  59676                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  59677                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  59678                     } else {
  59679                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  59680                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  59681 
  59682                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  59683                                         mod_in, port_in, &mod_out, &port_out);
  59684                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  59685                     }
  59686 
  59687                     if (match_array->action != NULL) {
  59688                         action = match_array->action;
  59689                         action->new_outer_vlan =
  59690                             soc_mem_field32_get(unit, mem, entry, NEW_OVIDf);
  59691                         action->new_inner_vlan =
  59692                             soc_mem_field32_get(unit, mem, entry, NEW_IVIDf);
  59693                         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  59694                             action->priority =
  59695                                     soc_mem_field32_get(unit, mem, entry, NEW_OPRIf);
  59696                             action->new_outer_cfi =
  59697                                     soc_mem_field32_get(unit, mem, entry, NEW_OCFIf);
  59698                             action->new_inner_pkt_prio =
  59699                                     soc_mem_field32_get(unit, mem, entry, NEW_IPRIf);
  59700                             action->new_inner_cfi =
  59701                                     soc_mem_field32_get(unit, mem, entry, NEW_ICFIf);
  59702                         }
  59703                         profile_idx = soc_mem_field32_get(unit, mem, entry, TAG_ACTION_PROFILE_PTRf);
  59704                         _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
  59705                     }
  59706                     match_array->port = gp;
  59707                     match_array++;
  59708                     break;
  59709 #endif
  59710                 default:
  59711                     break;
  59712                 }
  59713             }
  59714         }
  59715     }
  59716 
  59717 #if defined(BCM_TRX_SUPPORT)
  59718     /* Get the list from VLAN_MACm */
  59719     if (BCM_SUCCESS(rv)) {
  59720         rv = _bcm_vlan_match_action_multi_get(unit,
  59721                 port, size, match_array, ctr, &ctr);
  59722     }
  59723 #endif
  59724 
  59725     *count = ctr;
  59726 
  59727 cleanup:
  59728     if (vlan_xlate_buf) {
  59729         soc_cm_sfree(unit, vlan_xlate_buf);
  59730     }
  59731     if (source_trunk_map_buf) {
  59732         soc_cm_sfree(unit, source_trunk_map_buf);
  59733     }
  59734     if (member_array) {
  59735         sal_free(member_array);
  59736     }
  59737     return rv;
  59738 #else
  59739     return BCM_E_UNAVAIL;
  59740 #endif
  59741 }
  59742 
  59743 /*
  59744  * Function:
  59745  *      bcm_port_match_set
  59746  * Purpose:
  59747  *      Assign a set of matches to an existing port
  59748  * Parameters:
  59749  *      unit - (IN) Unit number.
  59750  *      port - (IN) Port or gport
  59751  *      size - (IN) Number of elements in match array
  59752  *      match_array - (IN) Match array
  59753  * Returns:
  59754  *      BCM_E_xxx
  59755  * Notes:
  59756  */
  59757 int
  59758 bcm_esw_port_match_set(
  59759     int unit,
  59760     bcm_gport_t port,
  59761     int size,
  59762     bcm_port_match_info_t *match_array)
  59763 {
  59764 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  59765     int i, rv = BCM_E_NONE;
  59766     if ((size <= 0) || (match_array == NULL)) {
  59767         return BCM_E_PARAM;
  59768     }
  59769 
  59770     /* Make sure port module is initialized. */
  59771     PORT_INIT(unit);
  59772 
  59773     /* Add every single match */
  59774     for (i = 0; i < size; i++) {
  59775         rv = bcm_esw_port_match_add(unit, port, match_array + i);
  59776         if (BCM_FAILURE(rv)) {
  59777             return rv;
  59778         }
  59779     }
  59780     return rv;
  59781 #else
  59782     return BCM_E_UNAVAIL;
  59783 #endif
  59784 }
  59785 
  59786 /*
  59787  * Function:
  59788  *      bcm_port_match_delete_all
  59789  * Purpose:
  59790  *      Delete all matches for an existing port
  59791  * Parameters:
  59792  *      unit - (IN) Unit number.
  59793  *      port - (IN) Port or gport
  59794  * Returns:
  59795  *      BCM_E_xxx
  59796  * Notes:
  59797  */
  59798 int
  59799 bcm_esw_port_match_delete_all(
  59800     int unit,
  59801     bcm_gport_t port)
  59802 {
  59803 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  59804     int i, size, count, rv = BCM_E_NONE;
  59805     bcm_port_match_info_t *match_array = NULL;
  59806 
  59807     /* Make sure port module is initialized. */
  59808     PORT_INIT(unit);
  59809 
  59810     /* First get number of entries */
  59811     rv = bcm_esw_port_match_multi_get(unit, port, 0, match_array, &count);
  59812     if (BCM_FAILURE(rv) || (count == 0)) {
  59813         return rv;
  59814     }
  59815     match_array = sal_alloc(sizeof(bcm_port_match_info_t) * count,
  59816                             "match_array");
  59817     if (match_array == NULL) {
  59818         return BCM_E_MEMORY;
  59819     }
  59820     sal_memset(match_array, 0, sizeof(bcm_port_match_info_t) * count);
  59821 
  59822     /* Get all matches */
  59823     size = count;
  59824     rv = bcm_esw_port_match_multi_get(unit, port, size, match_array, &count);
  59825     if (BCM_FAILURE(rv)) {
  59826         sal_free(match_array);
  59827         return rv;
  59828     }
  59829 
  59830     /* Delete every single match */
  59831     for (i = 0; i < count; i++) {
  59832         rv = bcm_esw_port_match_delete(unit, port, match_array + i);
  59833         if (BCM_FAILURE(rv)) {
  59834             sal_free(match_array);
  59835             return rv;
  59836         }
  59837     }
  59838     sal_free(match_array);
  59839     return rv;
  59840 #else
  59841     return BCM_E_UNAVAIL;
  59842 #endif
  59843 }
  59844 
  59845 int
  59846 bcmi_esw_port_eee_cfg_get(int unit, bcm_port_t port, int *value)
  59847 {
  59848 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  59849     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \
  59850     defined(BCM_HURRICANE2_SUPPORT)
  59851     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  59852         return BCM_E_PORT;
  59853     }
  59854 
  59855     *value = eee_cfg[unit][port];
  59856 
  59857     return BCM_E_NONE;
  59858 #else
  59859     return BCM_E_UNAVAIL;
  59860 #endif
  59861 }
  59862 
  59863 
  59864 
  59865 /*
  59866  * Function:
  59867  *      bcm_esw_port_timesync_config_get
  59868  * Purpose:
  59869  *      Delete all matches for an existing port
  59870  * Parameters:
  59871  *      unit - (IN) Unit number.
  59872  *      port - (IN) Port
  59873  *      conf - (IN) Configuration
  59874  * Returns:
  59875  *      BCM_E_xxx
  59876  * Notes:
  59877  */
  59878 
  59879 int
  59880 bcm_esw_port_timesync_config_get(int unit, bcm_port_t port, int array_size,
  59881                                   bcm_port_timesync_config_t *config_array,
  59882                                   int *array_count)
  59883 {
  59884     int rv;
  59885     int is_remote_port = FALSE;
  59886 
  59887     /* Make sure port module is initialized. */
  59888     PORT_INIT(unit);
  59889 
  59890     if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) {
  59891         if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) {
  59892             /* the port is remote mod port */
  59893             is_remote_port = TRUE;
  59894         }
  59895     }
  59896 
  59897     if (!is_remote_port) {
  59898         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  59899     }
  59900 
  59901     COMPILER_REFERENCE(array_size);
  59902     COMPILER_REFERENCE(config_array);
  59903     COMPILER_REFERENCE(array_count);
  59904 
  59905 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  59906     defined(BCM_TIMESYNC_V3_SUPPORT)|| defined(BCM_SABER2_SUPPORT) || \
  59907     defined(BCM_APACHE_SUPPORT)
  59908     /*
  59909      * Internal timesync function handles port lock and retrieves
  59910      * timesync config profiles
  59911      */
  59912     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  59913          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  59914          SOC_IS_APACHE(unit)) &&
  59915         (soc_feature(unit,soc_feature_timesync_support))) {
  59916         rv = _bcm_esw_port_timesync_config_get(unit, port, array_size,
  59917                                            config_array, array_count, is_remote_port);
  59918     } else
  59919 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  59920           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  59921     {
  59922         rv = BCM_E_UNAVAIL;
  59923     }
  59924 
  59925     return rv;
  59926 }
  59927 
  59928 /*
  59929  * Function:
  59930  *      bcm_esw_port_timesync_config_set
  59931  * Purpose:
  59932  *      Set Timesync Configuration profiles for the port
  59933  * Parameters:
  59934  *      unit            - (IN) bcm device
  59935  *      port            - (IN) port
  59936  *      config_count    - (IN)Count of timesync profile
  59937  *      *config_array   - (IN/OUT) Pointer to array of timesync profiles
  59938  * Returns:
  59939  *      BCM_E_xxx
  59940  * Notes:
  59941  */
  59942 int
  59943 bcm_esw_port_timesync_config_set(int unit, bcm_port_t port, int config_count,
  59944                                   bcm_port_timesync_config_t *config_array)
  59945 {
  59946     int rv;
  59947     int is_remote_port = FALSE;
  59948 
  59949     /* Make sure port module is initialized. */
  59950     PORT_INIT(unit);
  59951 
  59952     if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) {
  59953         if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) {
  59954             int cnt;
  59955             bcm_port_timesync_config_t *ts_config;
  59956             is_remote_port = TRUE;
  59957             for (cnt = 0; cnt < config_count; cnt++)
  59958             {
  59959                 ts_config = (bcm_port_timesync_config_t*) (config_array + cnt);
  59960                 /* the params can't be configured on remote logical port */
  59961                 if (ts_config->flags & BCM_PORT_TIMESYNC_ONE_STEP_TIMESTAMP ||
  59962                     ts_config->flags & BCM_PORT_TIMESYNC_TWO_STEP_TIMESTAMP ||
  59963                     ts_config->flags & BCM_PORT_TIMESYNC_TIMESTAMP_CFUPDATE_ALL ||
  59964                     ts_config->pkt_drop & BCM_PORT_TIMESYNC_PKT_INVALID) {
  59965                     return BCM_E_PORT;
  59966                 }
  59967             }
  59968         }
  59969     }
  59970 
  59971     if (!is_remote_port) {
  59972         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  59973     }
  59974 
  59975     COMPILER_REFERENCE(config_count);
  59976     COMPILER_REFERENCE(config_array);
  59977 
  59978 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  59979     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) || \
  59980     defined(BCM_APACHE_SUPPORT)
  59981     /*
  59982      * Internal timesync function handles port lock and adds
  59983      * timesync config profiles
  59984      */
  59985     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  59986          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  59987          SOC_IS_APACHE(unit)) &&
  59988         (soc_feature(unit,soc_feature_timesync_support))) {
  59989         rv = _bcm_esw_port_timesync_config_set(unit, port, config_count,
  59990                                            config_array, is_remote_port);
  59991     } else
  59992 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  59993           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  59994     {
  59995         rv = BCM_E_UNAVAIL;
  59996     }
  59997 
  59998     return rv;
  59999 }
  60000 
  60001 /*
  60002  * Function:
  60003  *     bcm_esw_port_timesync_tx_timestamp_and_seqid_get
  60004  * Purpose:
  60005  *    Retrives two-step PTP timestamp and seqid from MAC FIFO after packet TX
  60006  * Parameters:
  60007  *      unit - (IN) Unit number.
  60008  *      port - (IN) Port
  60009  *      conf - (IN) Configuration
  60010  * Returns:
  60011  *      BCM_E_xxx
  60012  * Notes:
  60013  */
  60014 
  60015 int
  60016 bcm_esw_port_timesync_tx_info_get(int unit, bcm_port_t port,
  60017                                   bcm_port_timesync_tx_info_t *tx_info)
  60018 {
  60019     int rv;
  60020 
  60021     /* Make sure port module is initialized. */
  60022     PORT_INIT(unit);
  60023 
  60024     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60025 
  60026 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) \
  60027     || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) \
  60028     || defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) \
  60029     || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) \
  60030     || defined(BCM_GREYHOUND_SUPPORT)
  60031     /*
  60032      * Internal timesync function handles port lock and retrieves
  60033      * timesync config profiles
  60034      */
  60035     if (((SOC_IS_TD2_TT2(unit)) || SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2(unit) ||
  60036         SOC_IS_TRIUMPH3(unit) || SOC_IS_FIRELIGHT(unit) || SOC_IS_GREYHOUND(unit)) &&
  60037         (soc_feature(unit,soc_feature_timesync_support))) {
  60038         if (SOC_USE_PORTCTRL(unit)) {
  60039             rv = _bcm_esw_port_timesync_tx_info_get(unit, port, tx_info);
  60040         } else {
  60041             soc_port_timesync_tx_info_t info;
  60042             sal_memset(&info, 0, sizeof(soc_port_timesync_tx_info_t));
  60043 
  60044             PORT_LOCK(unit)
  60045             rv = MAC_TIMESYNC_TX_INFO_GET(PORT(unit, port).p_mac, unit, port, &info);
  60046             PORT_UNLOCK(unit);
  60047             COMPILER_64_SET(tx_info->timestamp, info.timestamps_in_fifo_hi, info.timestamps_in_fifo);
  60048             tx_info->sequence_id = info.sequence_id;
  60049         }
  60050     } else
  60051 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  60052           || defined(BCM_TOMAHAWK2_SUPPORT) */
  60053     {
  60054         rv = BCM_E_UNAVAIL;
  60055     }
  60056 
  60057     return rv;
  60058 }
  60059 
  60060 /*
  60061  * Function:
  60062  *     bcm_esw_port_timestamp_adjust_get
  60063  * Purpose:
  60064  *     get OSTS,TSTS timestamp adjust based on current speed
  60065  * Parameters:
  60066  *      unit - (IN) Unit number.
  60067  *      port - (IN) Port
  60068  *      ts_adjust - (OUT) configuration for tsts,osts timestamp adjustment.
  60069  * Returns:
  60070  *      BCM_E_xxx
  60071  * Notes:
  60072  */
  60073 int
  60074 bcm_esw_port_timestamp_adjust_get(int unit, bcm_port_t port,
  60075                                   bcm_port_timestamp_adjust_t *ts_adjust)
  60076 {
  60077         int rv;
  60078 
  60079         /* Make sure port module is initialized. */
  60080         PORT_INIT(unit);
  60081 
  60082         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60083 
  60084 #ifdef PORTMOD_SUPPORT
  60085         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60086             PORT_LOCK(unit);
  60087             rv = bcmi_esw_portctrl_timestamp_adjust_get(unit, port, ts_adjust);
  60088             PORT_UNLOCK(unit);
  60089         } else
  60090 #endif /* PORTMOD_SUPPORT */
  60091         {
  60092             rv = BCM_E_UNAVAIL;
  60093         }
  60094 
  60095         return rv;
  60096 
  60097 }
  60098 
  60099 /*
  60100  * Function:
  60101  *     bcm_esw_port_timestamp_adjust_set
  60102  * Purpose:
  60103  *     set OSTS,TSTS timestamp adjust based on speed
  60104  * Parameters:
  60105  *      unit - (IN) Unit number.
  60106  *      port - (IN) Port.
  60107  *      ts_adjust - (IN) configuration for tsts,osts timestamp adjust.
  60108  * Returns:
  60109  *      BCM_E_xxx
  60110  * Notes:
  60111  */
  60112 int
  60113 bcm_esw_port_timestamp_adjust_set(int unit, bcm_port_t port,
  60114                                   bcm_port_timestamp_adjust_t *ts_adjust)
  60115 {
  60116         int rv;
  60117         /* Make sure port module is initialized. */
  60118         PORT_INIT(unit);
  60119 
  60120         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60121 
  60122 #ifdef PORTMOD_SUPPORT
  60123         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60124             PORT_LOCK(unit);
  60125             rv = bcmi_esw_portctrl_timestamp_adjust_set(unit, port, ts_adjust);
  60126             PORT_UNLOCK(unit);
  60127         } else
  60128 #endif /* PORTMOD_SUPPORT */
  60129         {
  60130             rv = BCM_E_UNAVAIL;
  60131         }
  60132 
  60133         return rv;
  60134 
  60135 }
  60136 
  60137 /*
  60138  * Function:
  60139  *      bcm_esw_port_phy_timesync_config_set
  60140  * Purpose:
  60141  *      Delete all matches for an existing port
  60142  * Parameters:
  60143  *      unit - (IN) Unit number.
  60144  *      port - (IN) Port
  60145  *      conf - (IN) Configuration
  60146  * Returns:
  60147  *      BCM_E_xxx
  60148  * Notes:
  60149  */
  60150 int
  60151 bcm_esw_port_phy_timesync_config_set(int unit, bcm_port_t port,
  60152                                      bcm_port_phy_timesync_config_t *conf)
  60153 {
  60154     int rv;
  60155     /* Make sure port module is initialized. */
  60156     PORT_INIT(unit);
  60157 
  60158     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60159 
  60160 #ifdef PORTMOD_SUPPORT
  60161     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60162         PORT_LOCK(unit);
  60163         rv = soc_portctrl_phy_timesync_config_set(unit, port,
  60164              (soc_port_phy_timesync_config_t *)conf);
  60165         PORT_UNLOCK(unit);
  60166     } else
  60167 #endif /* PORTMOD_SUPPORT */
  60168     {
  60169         PORT_LOCK(unit);
  60170         rv = soc_port_phy_timesync_config_set(unit, port,
  60171              (soc_port_phy_timesync_config_t *)conf);
  60172         PORT_UNLOCK(unit);
  60173     }
  60174 
  60175     return rv;
  60176 }
  60177 
  60178 /*
  60179  * Function:
  60180  *      bcm_esw_port_phy_timesync_config_get
  60181  * Purpose:
  60182  *      Delete all matches for an existing port
  60183  * Parameters:
  60184  *      unit - (IN) Unit number.
  60185  *      port - (IN) Port
  60186  *      conf - (OUT) Configuration
  60187  * Returns:
  60188  *      BCM_E_xxx
  60189  * Notes:
  60190  */
  60191 int
  60192 bcm_esw_port_phy_timesync_config_get(int unit, bcm_port_t port,
  60193                                      bcm_port_phy_timesync_config_t *conf)
  60194 {
  60195     int rv;
  60196 
  60197     /* Make sure port module is initialized. */
  60198     PORT_INIT(unit);
  60199 
  60200     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60201 
  60202 #ifdef PORTMOD_SUPPORT
  60203     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60204         PORT_LOCK(unit);
  60205         rv = soc_portctrl_phy_timesync_config_get(unit, port,
  60206              (soc_port_phy_timesync_config_t *)conf);
  60207         PORT_UNLOCK(unit);
  60208     } else
  60209 #endif /* PORTMOD_SUPPORT */
  60210     {
  60211         PORT_LOCK(unit);
  60212         rv = soc_port_phy_timesync_config_get(unit, port,
  60213              (soc_port_phy_timesync_config_t *)conf);
  60214         PORT_UNLOCK(unit);
  60215     }
  60216 
  60217     return rv;
  60218 }
  60219 
  60220 /*
  60221  * Function:
  60222  *      bcm_esw_port_control_phy_timesync_set
  60223  * Purpose:
  60224  *      Delete all matches for an existing port
  60225  * Parameters:
  60226  *      unit - (IN) Unit number.
  60227  *      port - (IN) Port
  60228  *      type - (IN) Operation
  60229  *      value- (IN) Arg to operation
  60230  * Returns:
  60231  *      BCM_E_xxx
  60232  * Notes:
  60233  */
  60234 int
  60235 bcm_esw_port_control_phy_timesync_set(int unit, bcm_port_t port,
  60236                                       bcm_port_control_phy_timesync_t type,
  60237                                       uint64 value)
  60238 {
  60239     int rv;
  60240 
  60241     /* Make sure port module is initialized. */
  60242     PORT_INIT(unit);
  60243 
  60244     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60245 
  60246 #ifdef PORTMOD_SUPPORT
  60247     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60248         PORT_LOCK(unit);
  60249         rv = soc_portctrl_control_phy_timesync_set(unit, port, type, value);
  60250         PORT_UNLOCK(unit);
  60251     } else
  60252 #endif /* PORTMOD_SUPPORT */
  60253     {
  60254         PORT_LOCK(unit);
  60255         rv = soc_port_control_phy_timesync_set(unit, port, type, value);
  60256         PORT_UNLOCK(unit);
  60257     }
  60258 
  60259     return rv;
  60260 }
  60261 
  60262 /*
  60263  * Function:
  60264  *      bcm_esw_port_control_phy_timesync_get
  60265  * Purpose:
  60266  *      Delete all matches for an existing port
  60267  * Parameters:
  60268  *      unit - (IN) Unit number.
  60269  *      port - (IN) Port
  60270  *      type - (IN) Operation
  60271  *      value- (OUT) Pointer to arg for operation
  60272  * Returns:
  60273  *      BCM_E_xxx
  60274  * Notes:
  60275  */
  60276 int
  60277 bcm_esw_port_control_phy_timesync_get(int unit, bcm_port_t port,
  60278                                       bcm_port_control_phy_timesync_t type,
  60279                                       uint64 *value)
  60280 {
  60281     int rv;
  60282 
  60283     /* Make sure port module is initialized. */
  60284     PORT_INIT(unit);
  60285 
  60286     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60287 
  60288 #ifdef PORTMOD_SUPPORT
  60289     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60290         PORT_LOCK(unit);
  60291         rv = soc_portctrl_control_phy_timesync_get(unit, port, type, value);
  60292         PORT_UNLOCK(unit);
  60293     } else
  60294 #endif /* PORTMOD_SUPPORT */
  60295     {
  60296         PORT_LOCK(unit);
  60297         rv = soc_port_control_phy_timesync_get(unit, port, type, value);
  60298         PORT_UNLOCK(unit);
  60299     }
  60300 
  60301     return rv;
  60302 }
  60303 
  60304 /*
  60305  * Function:
  60306  *      bcm_esw_port_phy_timesync_enhanced_capture_get
  60307  * Purpose:
  60308  *      Delete all matches for an existing port
  60309  * Parameters:
  60310  *      unit - (IN) Unit number.
  60311  *      port - (IN) Port
  60312  *      value - (OUT) Configuration
  60313  * Returns:
  60314  *      BCM_E_xxx
  60315  * Notes:
  60316  */
  60317 int
  60318 bcm_esw_port_phy_timesync_enhanced_capture_get(int unit, bcm_port_t port,
  60319                                      bcm_port_phy_timesync_enhanced_capture_t *value)
  60320 {
  60321     int rv;
  60322     /* Make sure port module is initialized. */
  60323     PORT_INIT(unit);
  60324 
  60325     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60326 
  60327     PORT_LOCK(unit);
  60328     rv = soc_port_phy_timesync_enhanced_capture_get(unit, port,
  60329                                           (soc_port_phy_timesync_enhanced_capture_t *)value);
  60330     PORT_UNLOCK(unit);
  60331 
  60332     return rv;
  60333 }
  60334 
  60335 /* bcm_port_config_phy_oam_set */
  60336 int bcm_esw_port_config_phy_oam_set(int unit, bcm_port_t port,
  60337                                     bcm_port_config_phy_oam_t *conf){
  60338     int rv;
  60339 
  60340     /* Make sure port module is initialized. */
  60341     PORT_INIT(unit);
  60342     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60343 
  60344 #ifdef PORTMOD_SUPPORT
  60345     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60346         rv = BCM_E_UNAVAIL;
  60347     } else
  60348 #endif /* PORTMOD_SUPPORT */
  60349     {
  60350 
  60351         PORT_LOCK(unit);
  60352         rv = soc_port_config_phy_oam_set(unit, port,
  60353                                          (soc_port_config_phy_oam_t *)conf);
  60354         PORT_UNLOCK(unit);
  60355     }
  60356 
  60357     return rv;
  60358 }
  60359 
  60360 /* bcm_port_config_phy_oam_get */
  60361 int bcm_esw_port_config_phy_oam_get(int unit, bcm_port_t port,
  60362                                     bcm_port_config_phy_oam_t *conf){
  60363     int rv;
  60364 
  60365     /* Make sure port module is initialized. */
  60366     PORT_INIT(unit);
  60367     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60368 
  60369 #ifdef PORTMOD_SUPPORT
  60370     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60371         rv = BCM_E_UNAVAIL;
  60372     } else
  60373 #endif /* PORTMOD_SUPPORT */
  60374     {
  60375         PORT_LOCK(unit);
  60376         rv = soc_port_config_phy_oam_get(unit, port,
  60377                                          (soc_port_config_phy_oam_t *)conf);
  60378         PORT_UNLOCK(unit);
  60379     }
  60380 
  60381     return rv;
  60382 }
  60383 
  60384 /* bcm_port_control_phy_oam_set */
  60385 int bcm_esw_port_control_phy_oam_set(int unit, bcm_port_t port,
  60386                                      bcm_port_control_phy_oam_t type,
  60387                                      uint64 value){
  60388     int rv;
  60389 
  60390     /* Make sure port module is initialized. */
  60391     PORT_INIT(unit);
  60392     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60393 
  60394 #ifdef PORTMOD_SUPPORT
  60395     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60396         rv = BCM_E_UNAVAIL;
  60397     } else
  60398 #endif /* PORTMOD_SUPPORT */
  60399     {
  60400         PORT_LOCK(unit);
  60401         rv = soc_port_control_phy_oam_set(unit, port,type, value);
  60402         PORT_UNLOCK(unit);
  60403     }
  60404 
  60405     return rv;
  60406 }
  60407 
  60408 /* bcm_port_control_phy_oam_get */
  60409 int bcm_esw_port_control_phy_oam_get(int unit, bcm_port_t port,
  60410                                      bcm_port_control_phy_oam_t type,
  60411                                      uint64 *value){
  60412     int rv;
  60413 
  60414     /* Make sure port module is initialized. */
  60415     PORT_INIT(unit);
  60416     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  60417 
  60418 #ifdef PORTMOD_SUPPORT
  60419     if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  60420         rv = BCM_E_UNAVAIL;
  60421     } else
  60422 #endif /* PORTMOD_SUPPORT */
  60423     {
  60424         PORT_LOCK(unit);
  60425         rv = soc_port_control_phy_oam_get(unit, port,type, value);
  60426         PORT_UNLOCK(unit);
  60427     }
  60428 
  60429     return rv;
  60430 }
  60431 
  60432 /*
  60433  * Function:
  60434  *      bcm_esw_port_tpid_get_all
  60435  * Purpose:
  60436  *      Get a list of tpids and associated color selections for a given port
  60437  * Parameters:
  60438  *      unit  - (IN) Unit number.
  60439  *      port  - (IN) Port
  60440  *      size  - (IN) number of elements of the next two array parameters
  60441  *tpid_array  - (OUT) buffer array to hold a list of retrieved tpids
  60442  *color_array - (OUT) buffer array to hold a list of retrieved color selections
  60443  *      count - (OUT) actual number of tpids retrieved.
  60444  * Returns:
  60445  *      BCM_E_xxx
  60446  */
  60447 int
  60448 bcm_esw_port_tpid_get_all(int unit, bcm_port_t port,
  60449      int size,            /* number of elements of the arrays */
  60450      uint16 *tpid_array,  /* buffer array to hold a list of retrieved tpids */
  60451      int    *color_array, /* buffer array to hold a list of retrieved colors */
  60452      int    *count)       /* actual number of tpids retrieved. */
  60453 {
  60454     int rv = BCM_E_UNAVAIL;
  60455     bcm_module_t mod_out;
  60456     bcm_port_t port_out;
  60457     bcm_trunk_t tgid_out;
  60458     int id_out;
  60459     int is_local = 0;
  60460 
  60461     /* safety check */
  60462     if (size < 0 || count == NULL) {
  60463         return BCM_E_PARAM;
  60464     }
  60465     if ((size > 0) && (tpid_array == NULL || color_array == NULL)) {
  60466         return BCM_E_PARAM;
  60467     }
  60468 
  60469     *count = 0;
  60470 
  60471     /* Make sure port module is initialized. */
  60472     PORT_INIT(unit);
  60473     if (BCM_GPORT_IS_SET(port)) {
  60474         /* Handle virtual ports separetly */
  60475         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  60476             BCM_GPORT_IS_MIM_PORT(port) ||
  60477             BCM_GPORT_IS_TRILL_PORT(port) ||
  60478             BCM_GPORT_IS_VXLAN_PORT(port) ||
  60479             BCM_GPORT_IS_FLOW_PORT(port) ||
  60480             BCM_GPORT_IS_VLAN_PORT(port)) {
  60481 
  60482             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  60483 #if defined(BCM_TRX_SUPPORT)
  60484                 PORT_LOCK(unit);
  60485                 rv = _bcm_trx_vp_tpid_get_all(unit, port, size,
  60486                          tpid_array, color_array,count);
  60487                 PORT_UNLOCK(unit);
  60488 #endif
  60489             }
  60490             return rv;
  60491         } else {
  60492             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  60493                         &mod_out, &port_out, &tgid_out, &id_out));
  60494             if ((-1 != tgid_out) || (-1 != id_out)) {
  60495                 return BCM_E_PARAM;
  60496             }
  60497 
  60498             BCM_IF_ERROR_RETURN
  60499                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  60500             if (!is_local) {
  60501                 return BCM_E_PORT;
  60502             } else {
  60503                 BCM_IF_ERROR_RETURN(
  60504                         bcm_esw_port_local_get(unit, port, &port));
  60505             }
  60506         }
  60507 
  60508     } else if (!SOC_PORT_VALID(unit, port)) {
  60509         return BCM_E_PORT;
  60510     }
  60511 
  60512 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  60513     || defined(BCM_RAVEN_SUPPORT)
  60514     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  60515         PORT_LOCK(unit);
  60516         rv = _bcm_fb2_port_tpid_get_all(unit, port, size,tpid_array,
  60517                                 color_array, count);
  60518         PORT_UNLOCK(unit);
  60519     }
  60520 #endif
  60521     return (rv);
  60522 }
  60523 void bcm_esw_kt2_port_lock(int unit)
  60524 {
  60525     PORT_LOCK(unit);
  60526 }
  60527 void bcm_esw_kt2_port_unlock(int unit)
  60528 {
  60529     PORT_UNLOCK(unit);
  60530 }
  60531 
  60532 #ifdef BCM_WARM_BOOT_SUPPORT
  60533 int
  60534 _bcm_port_cleanup(int unit)
  60535 {
  60536 #if defined(BCM_FIREBOLT_SUPPORT)
  60537     if (SOC_IS_FB_FX_HX(unit)) {
  60538         bcm_port_t port;
  60539 
  60540         for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
  60541             if (PORT(unit, port).p_vd_pbvl != NULL) {
  60542                 sal_free(PORT(unit, port).p_vd_pbvl);
  60543                 PORT(unit, port).p_vd_pbvl = NULL;
  60544             }
  60545 
  60546             if (PORT(unit, port).e2ecc_config != NULL) {
  60547                 sal_free(PORT(unit, port).e2ecc_config);
  60548                 PORT(unit, port).e2ecc_config = NULL;
  60549             }
  60550         }
  60551 
  60552         if (bcm_port_info[unit] != NULL) {
  60553             sal_free(bcm_port_info[unit]);
  60554             bcm_port_info[unit] = NULL;
  60555         }
  60556     }
  60557 #endif /* BCM_FIREBOLT_SUPPORT */
  60558 
  60559     return BCM_E_NONE;
  60560 }
  60561 #endif /* BCM_WARM_BOOT_SUPPORT */
  60562 
  60563 #ifndef BCM_SW_STATE_DUMP_DISABLE
  60564 /*
  60565  * Function:
  60566  *     _bcm_port_sw_dump
  60567  * Purpose:
  60568  *     Displays port information maintained by software.
  60569  * Parameters:
  60570  *     unit - Device unit number
  60571  * Returns:
  60572  *     None
  60573  * Note:
  60574  *    Skip following structure fields: p_phy, p_mac
  60575  */
  60576 void
  60577 _bcm_port_sw_dump(int unit)
  60578 {
  60579     _bcm_port_info_t *info;
  60580     int              i, j;
  60581     int              idxmax, entries, max_num_ports = 0;
  60582     bcm_port_t       port;
  60583     bcm_pbmp_t       all_pbmp;
  60584 
  60585     info = bcm_port_info[unit];
  60586     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm) + 1;
  60587     entries = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE -  1)) / _BCM_PORT_VD_PBVL_ESIZE;
  60588 
  60589     max_num_ports = SOC_MAX_NUM_PORTS;
  60590 
  60591     SOC_PBMP_CLEAR(all_pbmp);
  60592     SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  60593 
  60594 #ifdef BCM_KATANA2_SUPPORT
  60595     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  60596         soc_feature(unit, soc_feature_subtag_coe)) {
  60597         _bcm_kt2_subport_pbmp_update (unit, &all_pbmp);
  60598         if (SOC_INFO(unit).linkphy_enabled ||
  60599             SOC_INFO(unit).subtag_enabled) {
  60600             max_num_ports = SOC_MAX_NUM_PP_PORTS;
  60601         }
  60602     }
  60603 #endif
  60604 
  60605 
  60606     LOG_CLI((BSL_META_U(unit,
  60607                         "\nSW Information Port - Unit %d\n"), unit));
  60608 
  60609     if (info != NULL) {
  60610         for (i = 0; i < max_num_ports; i++) {
  60611             LOG_CLI((BSL_META_U(unit,
  60612                                 "       Port %2d : "), i));
  60613             LOG_CLI((BSL_META_U(unit,
  60614                                 "     MAC driver - %s\n"),
  60615                      ((SOC_PORT_VALID(unit, i)) && (info[i].p_mac != NULL)) ?
  60616                      (info[i].p_mac)->drv_name : "none"));
  60617             LOG_CLI((BSL_META_U(unit,
  60618                                 "     Untagged priority - %d\n"),
  60619                      info[i].p_ut_prio));
  60620             LOG_CLI((BSL_META_U(unit,
  60621                                 "     Double-tag mode - ")));
  60622             if (0 != info[i].dtag_mode) {
  60623                 if (0 != (info[i].dtag_mode &
  60624                           BCM_PORT_DTAG_MODE_INTERNAL)) {
  60625                     LOG_CLI((BSL_META_U(unit,
  60626                                         " Internal")));
  60627                 }
  60628                 if (0 != (info[i].dtag_mode &
  60629                           BCM_PORT_DTAG_MODE_EXTERNAL)) {
  60630                     LOG_CLI((BSL_META_U(unit,
  60631                                         " External")));
  60632                 }
  60633                 if (0 != (info[i].dtag_mode &
  60634                           BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) {
  60635                     LOG_CLI((BSL_META_U(unit,
  60636                                         " AddTag")));
  60637                 }
  60638                 if (0 != (info[i].dtag_mode &
  60639                           BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) {
  60640                     LOG_CLI((BSL_META_U(unit,
  60641                                         " RemoveTag")));
  60642                 }
  60643             } else {
  60644                 LOG_CLI((BSL_META_U(unit,
  60645                                     " None")));
  60646             }
  60647             LOG_CLI((BSL_META_U(unit,
  60648                                 "\n")));
  60649             LOG_CLI((BSL_META_U(unit,
  60650                                 "     VLAN_PROTOCOL_DATA index - %d\n"),
  60651                      info[i].vlan_prot_ptr));
  60652             LOG_CLI((BSL_META_U(unit,
  60653                                 "     Number of VPs - %d\n"),
  60654                      info[i].vp_count));
  60655         }
  60656 
  60657         LOG_CLI((BSL_META_U(unit,
  60658                             "\n")));
  60659 
  60660         LOG_CLI((BSL_META_U(unit,
  60661                             "     Protocol based VLAN - \n")));
  60662         LOG_CLI((BSL_META_U(unit,
  60663                             "       Total Entries : %d\n"), entries));
  60664 
  60665         PBMP_ITER(all_pbmp, port) {
  60666             LOG_CLI((BSL_META_U(unit,
  60667                                 "       Port %2d : "), port));
  60668             if (info[port].p_vd_pbvl == NULL) {
  60669                 LOG_CLI((BSL_META_U(unit,
  60670                                     "\n")));
  60671                 continue;
  60672             }
  60673 
  60674             for (j = 0; j < entries; j++) {
  60675                 if ((j > 0) && !(j % 10)) {
  60676                     LOG_CLI((BSL_META_U(unit,
  60677                                         "\n                 ")));
  60678                 }
  60679                 LOG_CLI((BSL_META_U(unit,
  60680                                     " 0x%2.2x"), info[port].p_vd_pbvl[j]));
  60681             }
  60682             LOG_CLI((BSL_META_U(unit,
  60683                                 "\n")));
  60684         }
  60685 
  60686         if (soc_feature(unit, soc_feature_e2ecc)) {
  60687             bcm_port_congestion_config_t *e2ep;
  60688 
  60689             LOG_CLI((BSL_META_U(unit,
  60690                                 "\n")));
  60691             LOG_CLI((BSL_META_U(unit,
  60692                                 "     E2E Congestion Control - \n")));
  60693             PBMP_ALL_ITER(unit, port) {
  60694                 e2ep = info[port].e2ecc_config;
  60695                 if (NULL == e2ep) {
  60696                    continue;
  60697                 }
  60698 
  60699                 if ((0 == (e2ep->flags & (BCM_PORT_CONGESTION_CONFIG_E2ECC |
  60700                         BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL |
  60701                         BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE  |
  60702                         BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)))) {
  60703                     continue;
  60704                 }
  60705 
  60706                 LOG_CLI((BSL_META_U(unit,
  60707                                     "\n       Port : %d\n"), port));
  60708                 if ((e2ep->flags &
  60709                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ||
  60710                     (e2ep->flags &
  60711                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)) {
  60712                     LOG_CLI((BSL_META_U(unit,
  60713                           "         E2ECC COE Flags:  %s %s \n"),
  60714                           (e2ep->flags &
  60715                            BCM_PORT_CONGESTION_CONFIG_RX) ?
  60716                                         "RX" : "",
  60717                           ((e2ep->flags &
  60718                             BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ?
  60719                                        "FLEX mode":
  60720                           (e2ep->flags &
  60721                            BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ?
  60722                                         "STRICT mode" : ""))) ;
  60723                 } else {
  60724                     LOG_CLI((BSL_META_U(unit,
  60725                                     "         Flags : %s %s %s\n"),
  60726                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ?
  60727                             "E2ECC" : "DestMod Flow control",
  60728                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) ?
  60729                             "TX" : "",
  60730                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_RX) ?
  60731                             "RX" : ""));
  60732                 }
  60733 
  60734                 if (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) {
  60735                     LOG_CLI((BSL_META_U(unit,
  60736                                         "         Port bits : 0x%02x\n"),
  60737                              e2ep->port_bits));
  60738                     LOG_CLI((BSL_META_U(unit,
  60739                                         "         Packets/sec : %d\n"),
  60740                              e2ep->packets_per_sec));
  60741                     LOG_CLI((BSL_META_U(unit,
  60742                                         "         Source gport : 0x%08x\n"),
  60743                              e2ep->src_port));
  60744                     LOG_CLI((BSL_META_U(unit,
  60745                                         "         Multicast ID : 0x%04x\n"),
  60746                              e2ep->multicast_id));
  60747                     LOG_CLI((BSL_META_U(unit,
  60748                                         "         Traffic class : %d\n"),
  60749                              e2ep->traffic_class));
  60750                     LOG_CLI((BSL_META_U(unit,
  60751                                         "         Color : %d\n"),
  60752                              e2ep->color));
  60753                     LOG_CLI((BSL_META_U(unit,
  60754                                         "         Source MAC : 0x%02x%02x%02x%02x%02x%02x\n"),
  60755                              e2ep->src_mac[0], e2ep->src_mac[1],
  60756                              e2ep->src_mac[2], e2ep->src_mac[3],
  60757                              e2ep->src_mac[4], e2ep->src_mac[5]));
  60758                 }
  60759 
  60760                 LOG_CLI((BSL_META_U(unit,
  60761                                     "         Destination MAC : "
  60762                                     "0x%02x%02x%02x%02x%02x%02x\n"),
  60763                          e2ep->dest_mac[0], e2ep->dest_mac[1],
  60764                          e2ep->dest_mac[2], e2ep->dest_mac[3],
  60765                          e2ep->dest_mac[4], e2ep->dest_mac[5]));
  60766                 LOG_CLI((BSL_META_U(unit,
  60767                                     "         Ethertype : 0x%04x\n"),
  60768                          e2ep->ethertype));
  60769                 LOG_CLI((BSL_META_U(unit,
  60770                                     "         Opcode : 0x%04x\n"),
  60771                          e2ep->opcode));
  60772             }
  60773         }
  60774 
  60775 #ifdef BCM_TRIUMPH2_SUPPORT
  60776         if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  60777 
  60778             LOG_CLI((BSL_META_U(unit,
  60779                                 "\n")));
  60780             LOG_CLI((BSL_META_U(unit,
  60781                                 "     Source Modid Egress Blocking Profiles - \n")));
  60782             PBMP_ITER(all_pbmp, port) {
  60783                 if (-1 == PORT_SRC_MOD_EGR_PROF_PTR(unit, port)) {
  60784                     continue;
  60785                 }
  60786                 LOG_CLI((BSL_META_U(unit,
  60787                                     "       Port %2d : "), port));
  60788                 LOG_CLI((BSL_META_U(unit,
  60789                                     "Profile index %d\n"),
  60790                          PORT_SRC_MOD_EGR_PROF_PTR(unit, port)));
  60791             }
  60792             /* Display those entries with reference count > 0 */
  60793             if (PORT_SRC_MOD_EGR_PROFILE(unit) != NULL) {
  60794                 int     i;
  60795                 int     num_entries;
  60796                 int     ref_count;
  60797                 int     entries_per_set;
  60798                 int     modid_count;
  60799                 uint32  index;
  60800                 pbmp_t  sme_pbmp;
  60801                 src_modid_egress_entry_t *entry_p;
  60802                 char    sme_pfm[SOC_PBMP_FMT_LEN];
  60803 
  60804                 num_entries = soc_mem_index_count(unit,
  60805                       PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].mem);
  60806                 LOG_CLI((BSL_META_U(unit,
  60807                                     "  Source Modid Egress Profile\n")));
  60808                 LOG_CLI((BSL_META_U(unit,
  60809                                     "      Number of entries: %d\n"), num_entries));
  60810                 LOG_CLI((BSL_META_U(unit,
  60811                                     "      Index RefCount EntriesPerSet - "
  60812                          "PortBlockMaskBitmap\n")));
  60813 
  60814                 modid_count = SOC_MODID_MAX(unit) + 1;
  60815                 for (index = 0; index < num_entries; index += modid_count) {
  60816                     if (SOC_FAILURE(soc_profile_mem_ref_count_get(unit,
  60817                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  60818                                                  index, &ref_count))) {
  60819                         break;
  60820                     }
  60821 
  60822                     if (ref_count <= 0) {
  60823                         continue;
  60824                     }
  60825 
  60826                     for (i = 0; i < modid_count; i++) {
  60827                         entries_per_set =
  60828                             PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].\
  60829                             entries[index+i].entries_per_set;
  60830                         entry_p = SOC_PROFILE_MEM_ENTRY(unit,
  60831                                       PORT_SRC_MOD_EGR_PROFILE(unit),
  60832                                       src_modid_egress_entry_t *,
  60833                                                         index + i);
  60834                         soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm,
  60835                                                entry_p,
  60836                                                PORT_BLOCK_MASK_BITMAPf,
  60837                                                &sme_pbmp);
  60838 
  60839                         if (BCM_PBMP_NOT_NULL(sme_pbmp)) {
  60840                             LOG_CLI((BSL_META_U(unit,
  60841                                                 "     %5d %8d %13d    "),
  60842                                      index + i, ref_count,
  60843                                      entries_per_set));
  60844                             LOG_CLI((BSL_META_U(unit,
  60845                                                 "%s\n"),
  60846                                      SOC_PBMP_FMT(sme_pbmp, sme_pfm)));
  60847                         }
  60848                     }
  60849                 }
  60850             }
  60851         }
  60852 #endif /* BCM_TRIUMPH2_SUPPORT */
  60853     }
  60854 
  60855     LOG_CLI((BSL_META_U(unit,
  60856                         "\n")));
  60857 
  60858     return;
  60859 }
  60860 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  60861 
  60862 
  60863 /*
  60864  * Function:
  60865  *      _bcm_esw_port_gport_phyn_validate
  60866  * Purpose:
  60867  *      Validate PHY specific gport
  60868  * Parameters:
  60869  *      unit       -  (IN)  Unit number.
  60870  *      port       -  (IN)  Port number.
  60871  *      local_port -  (OUT) Local Port number.
  60872  *      phyn       -  (OUT) Phy number
  60873  *      phy_lane   -  (OUT) Lane number
  60874  *      sys_side   -  (OUT) System side(1)or line side(0).
  60875  * Returns:
  60876  *      BCM_E_XXX
  60877  */
  60878 
  60879 int
  60880 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port,
  60881                                   bcm_port_t *local_port, int *phyn,
  60882                                   int *phy_lane, int *sys_side)
  60883 {
  60884     /* Validate input arguments */
  60885     if (local_port == NULL || phy_lane == NULL ||
  60886         phyn == NULL || sys_side == NULL) {
  60887        return BCM_E_PARAM;
  60888     }
  60889 
  60890     if (BCM_PHY_GPORT_IS_PHYN(port)) {
  60891         *local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  60892         *phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  60893         *phy_lane = -1;
  60894     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  60895         *local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  60896         *phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  60897         *phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  60898     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  60899         *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  60900         *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  60901         *sys_side = TRUE;
  60902         *phy_lane = -1;
  60903     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  60904         *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  60905         *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  60906         *phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  60907         *sys_side = TRUE;
  60908     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  60909         *local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  60910         *phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  60911     } else {
  60912         *local_port = -1;
  60913         return BCM_E_NONE;
  60914     }
  60915 
  60916     if (!SOC_PORT_VALID(unit, *local_port)) {
  60917        return BCM_E_PORT;
  60918     }
  60919 
  60920     return BCM_E_NONE;
  60921 }
  60922 
  60923 /**
  60924  * Function:
  60925  *      _bcm_esw_link_force_for_disabled_loopback_port
  60926  * Purpose:
  60927  *      Force linkscan's current link status on for a disabled port
  60928  *      which is configured to MAC loopback.
  60929  * Parameters:
  60930  *      unit - (IN) Unit number.
  60931  * Returns:
  60932  *      BCM_E_xxx
  60933  * Notes:
  60934  */
  60935 int
  60936 _bcm_esw_link_force_for_disabled_loopback_port(int unit)
  60937 {
  60938     bcm_port_t port;
  60939     int loopback;
  60940     int enable;
  60941     bcm_pbmp_t pbmp;
  60942 
  60943     SOC_PBMP_ASSIGN(pbmp, PBMP_E_ALL(unit));
  60944 #if defined(BCM_SABER2_SUPPORT)
  60945     if(SOC_IS_SABER2(unit)){
  60946         /*
  60947          * During warmboot init, the oamp port is not removed
  60948          * from ethernet bitmaps till sat is initialized.
  60949          * So manually removing it here.
  60950          */
  60951         int oamp_enable;
  60952         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  60953         /* Skip OAMP port for saber2 device */
  60954         if(oamp_enable) {
  60955             SOC_PBMP_PORT_REMOVE(pbmp,
  60956                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  60957         }
  60958     }
  60959 #endif
  60960 
  60961     PBMP_ITER(pbmp,port) {
  60962         BCM_IF_ERROR_RETURN(
  60963             bcm_esw_port_loopback_get(unit, port, &loopback));
  60964         BCM_IF_ERROR_RETURN(
  60965             bcm_esw_port_enable_get(unit, port, &enable));
  60966         if ((loopback == BCM_PORT_LOOPBACK_MAC) && (enable == FALSE)) {
  60967             BCM_IF_ERROR_RETURN
  60968                 (_bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE));
  60969         }
  60970     }
  60971 
  60972     return BCM_E_NONE;
  60973 }
  60974 
  60975 #ifdef BCM_MAVERICK2_SUPPORT
  60976 /**
  60977  * Function:
  60978  *      _bcm_esw_mv2_asf_init
  60979  * Purpose:
  60980  *      Initialize ASF subsystem and configure all the applicable ports
  60981  *      to the specified forwarding mode
  60982  * Parameters:
  60983  *      unit - (IN) Unit number.
  60984  *      mode - (IN) forwarding mode
  60985  * Returns:
  60986  *      BCM_E_xxx
  60987  */
  60988 STATIC int
  60989 _bcm_esw_mv2_asf_init(
  60990     int                 unit,
  60991     soc_mv2_asf_mode_e  asf_mode)
  60992 {
  60993     bcm_port_t port;
  60994     int        speed;
  60995     soc_info_t *si;
  60996 
  60997     if (!(si = &SOC_INFO(unit))) {
  60998         return BCM_E_INTERNAL;
  60999     }
  61000 
  61001     BCM_IF_ERROR_RETURN(soc_mv2_asf_init_start(unit));
  61002 
  61003     PBMP_ALL_ITER(unit, port) {
  61004         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  61005             continue;
  61006         }
  61007         speed = si->port_init_speed[port];
  61008         if (speed == 0) {
  61009             BCM_IF_ERROR_RETURN(
  61010                 bcm_esw_port_speed_get(unit, port, &speed));
  61011         }
  61012         BCM_IF_ERROR_RETURN(
  61013             soc_mv2_port_asf_init(unit, port, speed, asf_mode));
  61014     }
  61015     BCM_IF_ERROR_RETURN(soc_mv2_asf_init_done(unit));
  61016 
  61017     return BCM_E_NONE;
  61018 }
  61019 
  61020 STATIC int
  61021 _bcm_esw_mv2_port_asf_mode_set(
  61022     int         unit,
  61023     bcm_port_t  port,
  61024     int         mode)
  61025 {
  61026     int rv = BCM_E_NONE, speed;
  61027     soc_info_t *si;
  61028     int txp = 0, rxp = 0;
  61029     pbmp_t *pause_bmp;
  61030 
  61031     if (!(si = &SOC_INFO(unit))) {
  61032         return SOC_E_INTERNAL;
  61033     }
  61034 
  61035     pause_bmp = soc_mv2_port_asf_pause_bpmp_get(unit);
  61036     if (pause_bmp == NULL) {
  61037         return BCM_E_INTERNAL;
  61038     }
  61039 
  61040     /* Update Pause for ASF mode */
  61041     if (_SOC_MV2_ASF_MODE_SAF != mode) {
  61042         /* Disable rx pause for cut through */
  61043         BCM_IF_ERROR_RETURN
  61044             (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61045 
  61046         if (rxp) {
  61047             SOC_PBMP_PORT_ADD((*pause_bmp), port);
  61048         }
  61049         BCM_IF_ERROR_RETURN
  61050             (bcm_esw_port_pause_set(unit, port, txp, 0));
  61051 
  61052     }
  61053 
  61054     speed = si->port_init_speed[port];
  61055     if (speed == 0) {
  61056         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  61057     }
  61058     PORT_LOCK(unit);
  61059     rv = soc_mv2_port_asf_mode_set(unit, port, speed, mode);
  61060     PORT_UNLOCK(unit);
  61061 
  61062     /* Update Pause for ASF mode */
  61063     if (((rv != SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF != mode)) ||
  61064         ((rv == SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF == mode))) {
  61065         /* restore pause */
  61066         if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  61067             BCM_IF_ERROR_RETURN
  61068                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61069             BCM_IF_ERROR_RETURN
  61070                 (bcm_esw_port_pause_set(unit, port, txp, 1));
  61071             SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  61072         }
  61073     }
  61074 
  61075     return rv;
  61076 }
  61077 #endif
  61078 
  61079 #ifdef BCM_TRIDENT3_SUPPORT
  61080 /**
  61081  * Function:
  61082  *      _bcm_esw_td3_asf_init
  61083  * Purpose:
  61084  *      Initialize ASF subsystem and configure all the applicable ports
  61085  *      to the specified forwarding mode
  61086  * Parameters:
  61087  *      unit - (IN) Unit number.
  61088  *      mode - (IN) forwarding mode
  61089  * Returns:
  61090  *      BCM_E_xxx
  61091  */
  61092 STATIC int
  61093 _bcm_esw_td3_asf_init(
  61094     int                 unit,
  61095     soc_td3_asf_mode_e  asf_mode)
  61096 {
  61097     bcm_port_t port;
  61098     int        speed;
  61099     soc_info_t *si;
  61100 
  61101     if (!(si = &SOC_INFO(unit))) {
  61102         return BCM_E_INTERNAL;
  61103     }
  61104 
  61105     BCM_IF_ERROR_RETURN(soc_td3_asf_init_start(unit));
  61106 
  61107     PBMP_ALL_ITER(unit, port) {
  61108         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  61109             continue;
  61110         }
  61111         speed = si->port_init_speed[port];
  61112         if (speed == 0) {
  61113             BCM_IF_ERROR_RETURN(
  61114                 bcm_esw_port_speed_get(unit, port, &speed));
  61115         }
  61116         BCM_IF_ERROR_RETURN(
  61117             soc_td3_port_asf_init(unit, port, speed, asf_mode));
  61118     }
  61119     BCM_IF_ERROR_RETURN(soc_td3_asf_init_done(unit));
  61120 
  61121     return BCM_E_NONE;
  61122 }
  61123 
  61124 STATIC int
  61125 _bcm_esw_td3_port_asf_mode_set(
  61126     int         unit,
  61127     bcm_port_t  port,
  61128     int         mode)
  61129 {
  61130     int rv = BCM_E_NONE, speed;
  61131     soc_info_t *si;
  61132     int txp = 0, rxp = 0;
  61133     pbmp_t *pause_bmp;
  61134 
  61135     if (!(si = &SOC_INFO(unit))) {
  61136         return SOC_E_INTERNAL;
  61137     }
  61138 
  61139     pause_bmp = soc_td3_port_asf_pause_bpmp_get(unit);
  61140     if (pause_bmp == NULL) {
  61141         return BCM_E_INTERNAL;
  61142     }
  61143 
  61144     /* Update Pause for ASF mode */
  61145     if (_SOC_TD3_ASF_MODE_SAF != mode) {
  61146         /* Disable rx pause for cut through */
  61147         BCM_IF_ERROR_RETURN
  61148             (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61149 
  61150         if (rxp) {
  61151             SOC_PBMP_PORT_ADD((*pause_bmp), port);
  61152         }
  61153         BCM_IF_ERROR_RETURN
  61154             (bcm_esw_port_pause_set(unit, port, txp, 0));
  61155 
  61156     }
  61157 
  61158     speed = si->port_init_speed[port];
  61159     if (speed == 0) {
  61160         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  61161     }
  61162     PORT_LOCK(unit);
  61163     rv = soc_td3_port_asf_mode_set(unit, port, speed, mode);
  61164     PORT_UNLOCK(unit);
  61165 
  61166     /* Update Pause for ASF mode */
  61167     if (((rv != SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF != mode)) ||
  61168         ((rv == SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF == mode))) {
  61169         /* restore pause */
  61170         if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  61171             BCM_IF_ERROR_RETURN
  61172                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61173             BCM_IF_ERROR_RETURN
  61174                 (bcm_esw_port_pause_set(unit, port, txp, 1));
  61175             SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  61176         }
  61177     }
  61178 
  61179     return rv;
  61180 }
  61181 #endif
  61182 
  61183 #if defined(BCM_TOMAHAWK_SUPPORT)
  61184 /* ASF (Cut-thru Forwarding) */
  61185 
  61186 /**
  61187  * Function:
  61188  *      _bcm_esw_asf_init
  61189  * Purpose:
  61190  *      Initialize ASF subsystem and configure all the applicable ports
  61191  *      to the specified forwarding mode
  61192  * Parameters:
  61193  *      unit - (IN) Unit number.
  61194  *      mode - (IN) forwarding mode
  61195  * Returns:
  61196  *      BCM_E_xxx
  61197  */
  61198 STATIC int
  61199 _bcm_esw_asf_init(
  61200     int                 unit,
  61201     soc_th_asf_mode_e   asf_mode)
  61202 {
  61203     bcm_port_t port;
  61204     int        speed;
  61205     soc_info_t *si;
  61206 
  61207     if (!(si = &SOC_INFO(unit))) {
  61208         return SOC_E_INTERNAL;
  61209     }
  61210 
  61211     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61212         return BCM_E_UNAVAIL;
  61213     }
  61214 
  61215 #ifdef BCM_WARM_BOOT_SUPPORT
  61216     if (SOC_WARM_BOOT(unit)) {
  61217         /* WB recovery happens in _bcm_esw_port_wb_recover context */
  61218         return BCM_E_NONE;
  61219     }
  61220 #endif /* BCM_WARM_BOOT_SUPPORT */
  61221 
  61222 #ifdef BCM_TOMAHAWK3_SUPPORT
  61223     if (SOC_IS_TOMAHAWK3(unit)) {
  61224         return soc_th3_asf_init(unit);
  61225     } else
  61226 #endif
  61227     {
  61228         BCM_IF_ERROR_RETURN(soc_th_asf_init_start(unit));
  61229 
  61230         PBMP_ALL_ITER(unit, port) {
  61231             if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  61232                 continue;
  61233             }
  61234             speed = si->port_init_speed[port];
  61235             BCM_IF_ERROR_RETURN(
  61236                 soc_th_port_asf_init(unit, port, speed, asf_mode));
  61237         }
  61238         BCM_IF_ERROR_RETURN(soc_th_asf_init_done(unit));
  61239     }
  61240 
  61241     return BCM_E_NONE;
  61242 }
  61243 
  61244 /**
  61245  * Function:
  61246  *      _bcm_esw_asf_deinit
  61247  * Purpose:
  61248  *      Deinitialize ASF subsystem and release ASF internal structures
  61249  * Parameters:
  61250  *      unit - (IN) Unit number.
  61251  * Returns:
  61252  *      BCM_E_xxx
  61253  */
  61254 STATIC int
  61255 _bcm_esw_asf_deinit(int unit)
  61256 {
  61257 #ifdef BCM_TRIDENT3_SUPPORT
  61258     if (SOC_IS_TRIDENT3X(unit)) {
  61259         return soc_td3_asf_deinit(unit);
  61260     } else
  61261 #endif
  61262 #ifdef BCM_TOMAHAWK3_SUPPORT
  61263     if (SOC_IS_TOMAHAWK3(unit)) {
  61264         return soc_th3_asf_deinit(unit);
  61265     } else
  61266 #endif
  61267     {
  61268         if (SOC_IS_TOMAHAWKX(unit)) {
  61269             return soc_th_asf_deinit(unit);
  61270         }
  61271     }
  61272 
  61273     return BCM_E_NONE;
  61274 }
  61275 
  61276 #ifdef BCM_WARM_BOOT_SUPPORT
  61277 /**
  61278  * Function:
  61279  *      bcm_esw_asf_wb_memsz_get
  61280  * Purpose:
  61281  *      Returns the WB Memory requirement from ASF subsystem
  61282  * Parameters:
  61283  *      unit - (IN) Unit number
  61284  *      mem_sz - (OUT) WB Memory required in bytes
  61285  * Returns:
  61286  *      BCM_E_xxx
  61287  */
  61288 STATIC int
  61289 _bcm_esw_asf_wb_memsz_get(
  61290     int               unit,
  61291     OUT uint32* const mem_sz,
  61292     uint16            scache_ver)
  61293 {
  61294     int rv;
  61295 
  61296     if (soc_feature(unit, soc_feature_asf_multimode)) {
  61297 #ifdef  BCM_MAVERICK2_SUPPORT
  61298         if (SOC_IS_MAVERICK2(unit)) {
  61299             rv = soc_mv2_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  61300         } else
  61301 #endif
  61302 #ifdef BCM_TRIDENT3_SUPPORT
  61303         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  61304             rv = soc_td3_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  61305         } else
  61306 #endif
  61307 #ifdef BCM_TOMAHAWK3_SUPPORT
  61308         if (SOC_IS_TOMAHAWK3(unit)) {
  61309             rv = soc_th3_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  61310         } else
  61311 #endif
  61312         if (SOC_IS_TOMAHAWKX(unit)) {
  61313             rv = soc_th_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  61314         } else {
  61315             *mem_sz = 0;
  61316             rv = BCM_E_NONE;
  61317         }
  61318     } else {
  61319         *mem_sz = 0;
  61320         rv = BCM_E_NONE;
  61321     }
  61322 
  61323     return rv;
  61324 }
  61325 
  61326 /**
  61327  * Function:
  61328  *      _bcm_esw_asf_wb_sync
  61329  * Purpose:
  61330  *      ASF Warmboot Sync
  61331  * Parameters:
  61332  *      unit - (IN) Unit number
  61333  *      wb_data - (IN/OUT) ptr to ASF WB data area
  61334  * Returns:
  61335  *      BCM_E_xxx
  61336  */
  61337 STATIC int
  61338 _bcm_esw_asf_wb_sync(
  61339     int    unit,
  61340     IN_OUT uint8* wb_data)
  61341 {
  61342     int rv;
  61343 
  61344     if (soc_feature(unit, soc_feature_asf_multimode)) {
  61345 #ifdef  BCM_MAVERICK2_SUPPORT
  61346         if (SOC_IS_MAVERICK2(unit)) {
  61347             rv = soc_mv2_asf_wb_sync(unit, wb_data);
  61348         } else
  61349 #endif
  61350 #ifdef BCM_TRIDENT3_SUPPORT
  61351         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  61352             rv = soc_td3_asf_wb_sync(unit, wb_data);
  61353         } else
  61354 #endif
  61355 #ifdef BCM_TOMAHAWK3_SUPPORT
  61356         if (SOC_IS_TOMAHAWK3(unit)) {
  61357             rv = soc_th3_asf_wb_sync(unit, wb_data);
  61358         } else
  61359 #endif
  61360 
  61361         if (SOC_IS_TOMAHAWKX(unit)) {
  61362             rv = soc_th_asf_wb_sync(unit, wb_data);
  61363         } else {
  61364             rv = BCM_E_NONE;
  61365         }
  61366     } else {
  61367         rv = BCM_E_NONE;
  61368     }
  61369 
  61370     return rv;
  61371 }
  61372 
  61373 /**
  61374  * Function:
  61375  *      _bcm_esw_asf_wb_recover
  61376  * Purpose:
  61377  *      ASF Warmboot Recovery
  61378  * Parameters:
  61379  *      unit - (IN) Unit number
  61380  *      wb_data - (IN) pointer to ASF WB data area
  61381  * Returns:
  61382  *      BCM_E_xxx
  61383  */
  61384 STATIC int
  61385 _bcm_esw_asf_wb_recover(
  61386     int          unit,
  61387     uint8* const wb_data,
  61388     uint16       scache_ver)
  61389 {
  61390     int rv;
  61391 
  61392     if (soc_feature(unit, soc_feature_asf_multimode)) {
  61393 #ifdef  BCM_MAVERICK2_SUPPORT
  61394         if (SOC_IS_MAVERICK2(unit)) {
  61395             rv = soc_mv2_asf_wb_recover(unit, wb_data, scache_ver);
  61396         } else
  61397 #endif
  61398 #ifdef BCM_TRIDENT3_SUPPORT
  61399         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  61400             rv = soc_td3_asf_wb_recover(unit, wb_data, scache_ver);
  61401         } else
  61402 #endif
  61403 #ifdef BCM_TOMAHAWK3_SUPPORT
  61404         if (SOC_IS_TOMAHAWK3(unit)) {
  61405             rv = soc_th3_asf_wb_recover(unit, wb_data, scache_ver);
  61406         } else
  61407 #endif
  61408 
  61409         if (SOC_IS_TOMAHAWKX(unit)) {
  61410             rv = soc_th_asf_wb_recover(unit, wb_data, scache_ver);
  61411         } else {
  61412             rv = BCM_E_NONE;
  61413         }
  61414     } else {
  61415         rv = BCM_E_NONE;
  61416     }
  61417 
  61418     return rv;
  61419 }
  61420 #endif /* BCM_WARMBOOT_SUPPORT */
  61421 
  61422 /**
  61423  * Function:
  61424  *      bcm_esw_port_asf_mode_get
  61425  * Purpose:
  61426  *      Returns the forwarding mode configured on the specified port
  61427  * Parameters:
  61428  *      unit - (IN)  Unit number
  61429  *      port - (IN)  Logical port
  61430  *      mode - (OUT) SAF/ASF mode configured on the port
  61431  *              0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast)
  61432  *              3=ASF (Fast to Slow)
  61433  * Returns:
  61434  *      BCM_E_xxx
  61435  */
  61436 int
  61437 bcm_esw_port_asf_mode_get(
  61438     int              unit,
  61439     bcm_port_t       port,
  61440     OUT int* const   mode)
  61441 {
  61442     int rv = BCM_E_UNAVAIL, speed;
  61443     soc_info_t *si;
  61444 
  61445     if (!(si = &SOC_INFO(unit))) {
  61446         return SOC_E_INTERNAL;
  61447     }
  61448 
  61449     /* Make sure port module is initialized. */
  61450     PORT_INIT(unit);
  61451     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61452         return BCM_E_UNAVAIL;
  61453     }
  61454     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  61455     speed = si->port_init_speed[port];
  61456 
  61457     PORT_LOCK(unit);
  61458 #ifdef BCM_MAVERICK2_SUPPORT
  61459     if (SOC_IS_MAVERICK2(unit)) {
  61460         rv = soc_mv2_port_asf_mode_get(unit, port, speed,
  61461                (soc_mv2_asf_mode_e *) mode );
  61462     } else
  61463 #endif
  61464 #ifdef BCM_TRIDENT3_SUPPORT
  61465     if (SOC_IS_TRIDENT3X(unit)) {
  61466         rv = soc_td3_port_asf_mode_get(unit, port, speed,
  61467                                        (soc_td3_asf_mode_e *) mode);
  61468     } else
  61469 #endif
  61470 
  61471 #ifdef BCM_TOMAHAWK3_SUPPORT
  61472     if (SOC_IS_TOMAHAWK3(unit)) {
  61473         rv = soc_th3_port_asf_mode_get(unit, port, speed,
  61474                                           (soc_th3_asf_mode_t *) mode);
  61475     } else
  61476 #endif
  61477     if (SOC_IS_TOMAHAWKX(unit)) {
  61478         rv = soc_th_port_asf_mode_get(unit, port, speed,
  61479                                       (soc_th_asf_mode_e *) mode);
  61480     }
  61481     PORT_UNLOCK(unit);
  61482 
  61483     return rv;
  61484 }
  61485 
  61486 /**
  61487  * Function:
  61488  *      bcm_esw_port_asf_mode_set
  61489  * Purpose:
  61490  *      Configure specified SAF/ASF mode on the given port
  61491  * Parameters:
  61492  *      unit - (IN) Unit number
  61493  *      port - (IN) Logical port
  61494  *      mode - (IN) Forwarding mode to be configured on the port
  61495  *              0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast)
  61496  *              3=ASF (Fast to Slow)
  61497  * Returns:
  61498  *      BCM_E_xxx
  61499  */
  61500 int
  61501 bcm_esw_port_asf_mode_set(
  61502     int          unit,
  61503     bcm_port_t   port,
  61504     int          mode)
  61505 {
  61506     int rv = BCM_E_UNAVAIL, speed = 0;
  61507     soc_info_t *si;
  61508 #if defined(BCM_TOMAHAWK2_SUPPORT)
  61509     int txp = 0, rxp = 0;
  61510     pbmp_t *pause_bmp = NULL;
  61511 #endif /* BCM_TOMAHAWK2_SUPPORT */
  61512 
  61513     if (!(si = &SOC_INFO(unit))) {
  61514         return SOC_E_INTERNAL;
  61515     }
  61516 
  61517     /* Make sure port module is initialized. */
  61518     PORT_INIT(unit);
  61519     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61520         return BCM_E_UNAVAIL;
  61521     }
  61522     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  61523 
  61524 #if defined(BCM_TOMAHAWK2_SUPPORT)
  61525     /* Update Pause for ASF mode */
  61526     if (SOC_IS_TOMAHAWK2(unit)) {
  61527         pause_bmp = soc_th_port_asf_pause_bpmp_get(unit);
  61528         if (pause_bmp == NULL) {
  61529             return BCM_E_INTERNAL;
  61530         }
  61531 
  61532         if (_SOC_TH_ASF_MODE_SAF != mode) {
  61533             /* Disable rx pause for cut through */
  61534             BCM_IF_ERROR_RETURN
  61535                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61536 
  61537             if (rxp) {
  61538                 SOC_PBMP_PORT_ADD((*pause_bmp), port);
  61539             }
  61540             BCM_IF_ERROR_RETURN
  61541                 (bcm_esw_port_pause_set(unit, port, txp, 0));
  61542         }
  61543     }
  61544 #endif /* BCM_TOMAHAWK2_SUPPORT */
  61545 
  61546 #ifdef BCM_MAVERICK2_SUPPORT
  61547     if (SOC_IS_MAVERICK2(unit)) {
  61548         rv = _bcm_esw_mv2_port_asf_mode_set(unit, port, mode);
  61549     } else
  61550 #endif
  61551 #ifdef BCM_TRIDENT3_SUPPORT
  61552     if (SOC_IS_TRIDENT3X(unit)) {
  61553         rv = _bcm_esw_td3_port_asf_mode_set(unit, port, mode);
  61554     } else
  61555 #endif
  61556 #ifdef BCM_TOMAHAWK3_SUPPORT
  61557     if(SOC_IS_TOMAHAWK3(unit)) {
  61558         if (mode >= 2) {
  61559             return BCM_E_PARAM;
  61560         }
  61561         speed = si->port_init_speed[port];
  61562         PORT_LOCK(unit);
  61563         rv = soc_th3_port_asf_mode_set(unit, port, speed, mode);
  61564         PORT_UNLOCK(unit);
  61565     } else
  61566 #endif
  61567     {
  61568         speed = si->port_init_speed[port];
  61569         PORT_LOCK(unit);
  61570         rv = soc_th_port_asf_mode_set(unit, port, speed, mode);
  61571         PORT_UNLOCK(unit);
  61572     }
  61573 
  61574 #if defined(BCM_TOMAHAWK2_SUPPORT)
  61575     /* Update Pause for ASF mode */
  61576     if (SOC_IS_TOMAHAWK2(unit)) {
  61577       if (_SOC_TH_ASF_MODE_SAF == mode) { /* SAF */
  61578             /* restore pause */
  61579             if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  61580                 BCM_IF_ERROR_RETURN
  61581                     (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  61582                 BCM_IF_ERROR_RETURN
  61583                     (bcm_esw_port_pause_set(unit, port, txp, 1));
  61584                 SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  61585             }
  61586         }
  61587     }
  61588 #endif /* BCM_TOMAHAWK2_SUPPORT */
  61589 
  61590     return rv;
  61591 }
  61592 
  61593 /**
  61594  * Function:
  61595  *      bcm_esw_asf_diag
  61596  * Purpose:
  61597  *      Dump all ASF configurations specific to the unit
  61598  * Parameters:
  61599  *      unit - (IN) Unit number
  61600  * Returns:
  61601  *      BCM_E_xxx
  61602  */
  61603 int
  61604 bcm_esw_asf_diag(int unit)
  61605 {
  61606     /* Make sure port module is initialized. */
  61607     PORT_INIT(unit);
  61608     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61609         return BCM_E_UNAVAIL;
  61610     }
  61611 
  61612 #ifdef BCM_MAVERICK2_SUPPORT
  61613     if (SOC_IS_MAVERICK2(unit)) {
  61614         return soc_mv2_asf_config_dump(unit);
  61615     } else
  61616 #endif
  61617 #ifdef BCM_TRIDENT3_SUPPORT
  61618     if (SOC_IS_TRIDENT3X(unit)) {
  61619         return soc_td3_asf_config_dump(unit);
  61620     } else
  61621 #endif
  61622 #ifdef BCM_TOMAHAWK3_SUPPORT
  61623     if(SOC_IS_TOMAHAWK3(unit)) {
  61624         return soc_th3_asf_config_dump(unit);
  61625     } else
  61626 #endif
  61627     if (SOC_IS_TOMAHAWKX(unit)) {
  61628         return soc_th_asf_config_dump(unit);
  61629     }
  61630 
  61631     return BCM_E_UNAVAIL;
  61632 }
  61633 
  61634 /**
  61635  * Function:
  61636  *      bcm_esw_port_asf_show
  61637  * Purpose:
  61638  *      Display formatted ASF information for a port
  61639  * Parameters:
  61640  *      unit - (IN) Unit number
  61641  *      port - (IN) Logical port
  61642  * Returns:
  61643  *      BCM_E_xxx
  61644  */
  61645 int
  61646 bcm_esw_port_asf_show(
  61647     int          unit,
  61648     bcm_port_t   port)
  61649 {
  61650     int speed;
  61651     soc_info_t *si;
  61652 
  61653     if (!(si = &SOC_INFO(unit))) {
  61654         return SOC_E_INTERNAL;
  61655     }
  61656 
  61657     /* Make sure port module is initialized. */
  61658     PORT_INIT(unit);
  61659     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61660         return BCM_E_UNAVAIL;
  61661     }
  61662     if(!SOC_IS_TOMAHAWK3(unit)) {
  61663     
  61664         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  61665     } else {
  61666         speed = si->port_init_speed[port];
  61667     }
  61668 #ifdef BCM_MAVERICK2_SUPPORT
  61669     if (SOC_IS_MAVERICK2(unit)) {
  61670         return soc_mv2_port_asf_show(unit, port, speed);
  61671     } else
  61672 #endif
  61673 #ifdef BCM_TRIDENT3_SUPPORT
  61674     if (SOC_IS_TRIDENT3X(unit)) {
  61675         return soc_td3_port_asf_show(unit, port, speed);
  61676     } else
  61677 #endif
  61678 #ifdef BCM_TOMAHAWK3_SUPPORT
  61679     if(SOC_IS_TOMAHAWK3(unit)) {
  61680         return soc_th3_port_asf_show(unit, port, speed);
  61681     } else
  61682 #endif
  61683     if (SOC_IS_TOMAHAWKX(unit)) {
  61684         return soc_th_port_asf_show(unit, port, speed);
  61685     }
  61686 
  61687     return BCM_E_UNAVAIL;
  61688 }
  61689 
  61690 /**
  61691  * Function:
  61692  *      bcm_esw_port_asf_diag
  61693  * Purpose:
  61694  *      Dump all related ASF configurations for the given port
  61695  * Parameters:
  61696  *      unit - (IN) Unit number
  61697  *      port - (IN) Logical port
  61698  * Returns:
  61699  *      BCM_E_xxx
  61700  */
  61701 int
  61702 bcm_esw_port_asf_diag(
  61703     int          unit,
  61704     bcm_port_t   port)
  61705 {
  61706     int speed;
  61707     soc_info_t *si;
  61708 
  61709     if (!(si = &SOC_INFO(unit))) {
  61710         return SOC_E_INTERNAL;
  61711     }
  61712 
  61713     /* Make sure port module is initialized. */
  61714     PORT_INIT(unit);
  61715     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  61716         return BCM_E_UNAVAIL;
  61717     }
  61718     if(!SOC_IS_TOMAHAWK3(unit)) {
  61719     
  61720         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  61721     } else {
  61722         speed = si->port_init_speed[port];
  61723     }
  61724 #ifdef BCM_MAVERICK2_SUPPORT
  61725     if (SOC_IS_MAVERICK2(unit)) {
  61726         return soc_mv2_port_asf_config_dump(unit, port, speed);
  61727     } else
  61728 #endif
  61729 #ifdef BCM_TRIDENT3_SUPPORT
  61730     if (SOC_IS_TRIDENT3X(unit)) {
  61731         return soc_td3_port_asf_config_dump(unit, port, speed);
  61732     } else
  61733 #endif
  61734 #ifdef BCM_TOMAHAWK3_SUPPORT
  61735     if (SOC_IS_TOMAHAWK3(unit)) {
  61736         return soc_th3_port_asf_config_dump(unit, port, speed);
  61737     } else
  61738 #endif
  61739     if (SOC_IS_TOMAHAWKX(unit)) {
  61740         return soc_th_port_asf_config_dump(unit, port, speed);
  61741     }
  61742 
  61743     return BCM_E_UNAVAIL;
  61744 }
  61745 #endif /* BCM_TOMAHAWK_SUPPORT */
  61746 
  61747 /**
  61748  * Function :
  61749  *      _bcm_esw_port_sw_info_display
  61750  * Purpose:
  61751  *      To display status of port related software structures
  61752  * Parameters:
  61753  *      unit - (IN) Unit number
  61754  *      port - (IN) Port number
  61755  * Returns :
  61756  *      BCM_E_xxxx
  61757  * Note:
  61758  *      Implementation currently limited to KATANA2 and SABER2 ONLY
  61759  */
  61760 int
  61761 _bcm_esw_port_sw_info_display(int unit, bcm_port_t port)
  61762 {
  61763 #ifdef BCM_METROLITE_SUPPORT
  61764     if (SOC_IS_METROLITE(unit)) {
  61765         BCM_IF_ERROR_RETURN(_bcm_ml_port_sw_info_display(unit, port));
  61766     } else
  61767 #endif
  61768 #ifdef BCM_SABER2_SUPPORT
  61769     if (SOC_IS_SABER2(unit)) {
  61770         BCM_IF_ERROR_RETURN(_bcm_sb2_port_sw_info_display(unit, port));
  61771     } else
  61772 #endif
  61773 #ifdef BCM_KATANA2_SUPPORT
  61774     if (SOC_IS_KATANA2(unit)) {
  61775         BCM_IF_ERROR_RETURN(_bcm_kt2_port_sw_info_display(unit, port));
  61776     } else
  61777 #endif
  61778     {
  61779         LOG_ERROR(BSL_LS_BCM_PORT,
  61780                   (BSL_META_U(unit,
  61781                           "_bcm_esw_port_sw_info_display \
  61782                           implementation not implemented\n")));
  61783         return SOC_E_UNIT;
  61784     }
  61785 
  61786     return BCM_E_NONE;
  61787 }
  61788 
  61789 /**
  61790  * Function :
  61791  *      _bcm_esw_port_hw_info_display
  61792  * Purpose:
  61793  *     To display status of port related harware registers.
  61794  * Parameters:
  61795  *     unit - (IN) Unit number.
  61796  *     port - (IN) Port number
  61797  * Returns:
  61798  *     BCM_E_xxxx
  61799  * Notes:
  61800  *      Implementation currently limited to KATANA2 and SABER2 ONLY
  61801  */
  61802 int
  61803 _bcm_esw_port_hw_info_display(int unit, bcm_port_t port)
  61804 {
  61805 #ifdef BCM_METROLITE_SUPPORT
  61806     if (SOC_IS_METROLITE(unit)) {
  61807         BCM_IF_ERROR_RETURN(_bcm_ml_port_hw_info_display(unit, port));
  61808     } else
  61809 #endif
  61810 #ifdef BCM_SABER2_SUPPORT
  61811     if (SOC_IS_SABER2(unit)) {
  61812         BCM_IF_ERROR_RETURN(_bcm_sb2_port_hw_info_display(unit, port));
  61813     } else
  61814 #endif
  61815 #ifdef BCM_KATANA2_SUPPORT
  61816     if (SOC_IS_KATANA2(unit)) {
  61817     BCM_IF_ERROR_RETURN(_bcm_kt2_port_hw_info_display(unit, port));
  61818     } else
  61819 #endif
  61820     {
  61821         LOG_ERROR(BSL_LS_BCM_PORT,
  61822                   (BSL_META_U(unit,
  61823                           "_bcm_esw_port_hw_info_display \
  61824                           implementation not implemented\n")));
  61825         return SOC_E_UNIT;
  61826     }
  61827 
  61828     return BCM_E_NONE;
  61829 }
  61830 
  61831 /*
  61832  * Function:
  61833  *      bcmi_esw_port_resource_portmod_support_check
  61834  * Purpose:
  61835  *      - Validates if all ports in resource array are supported by portmod
  61836  * Parameters:
  61837  *      unit     - (IN) Unit number.
  61838  *      nport    - (IN) Number of logical port.
  61839  *      resource - (IN) Port resource configuration.
  61840  * Returns:
  61841  *      BCM_E_XXX
  61842  */
  61843  int
  61844  bcmi_esw_port_resource_portmod_support_check(int unit,
  61845                                               int nport,
  61846                                               bcm_port_resource_t *res)
  61847  {
  61848 #if defined(BCM_XGS5_SWITCH_PORT_SUPPORT) && \
  61849     defined(BCM_MIXED_LEGACY_AND_PORTMOD_SUPPORT)
  61850      int idx, port;
  61851      int rv = BCM_E_NONE;
  61852 
  61853      if (soc_feature(unit, soc_feature_mixed_legacy_and_portmod)) {
  61854          if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) {
  61855              return BCM_E_PARAM;
  61856          }
  61857 
  61858          if (res == NULL) {
  61859              return BCM_E_PARAM;
  61860          }
  61861 
  61862          for (idx = 0; idx < nport; idx++) {
  61863              rv = bcmi_xgs5_port_addressable_local_get(unit, res[idx].port,
  61864                                                        &port);
  61865              if (BCM_SUCCESS(rv)) {
  61866                  if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) {
  61867                      return BCM_E_PARAM;
  61868                  }
  61869              }
  61870          }
  61871      }
  61872 #endif
  61873      return BCM_E_NONE;
  61874  }
  61875 
  61876 /*
  61877  * Function:
  61878  *      bcm_esw_port_resource_set
  61879  * Purpose:
  61880  *      Modify the following port resources:
  61881  *      - Logical to physical port mapping
  61882  *      - Speed
  61883  *      - Number of PHY lanes
  61884  *      - Encapsulation mode
  61885  * Parameters:
  61886  *      unit     - (IN) Unit number.
  61887  *      port     - (IN) Logical port.
  61888  *      resource - (IN) Port resource configuration.
  61889  * Returns:
  61890  *      BCM_E_XXX
  61891  */
  61892 int
  61893 bcm_esw_port_resource_set(int unit,
  61894                           bcm_gport_t port, bcm_port_resource_t *resource)
  61895 {
  61896     int rv = BCM_E_UNAVAIL;
  61897 
  61898     PORT_INIT(unit);
  61899 
  61900     PORT_LOCK(unit);
  61901 
  61902     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  61903         if (BCM_ESW_PORT_DRV(unit)->resource_set != NULL) {
  61904             rv = bcmi_esw_port_resource_portmod_support_check(unit,
  61905                                                               1, resource);
  61906             if (BCM_SUCCESS(rv)) {
  61907                 rv = BCM_ESW_PORT_DRV(unit)->resource_set(unit, port, resource);
  61908             }
  61909         }
  61910     }
  61911 
  61912     if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) {
  61913         BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, 1, resource);
  61914     }
  61915 
  61916     PORT_UNLOCK(unit);
  61917 
  61918     return rv;
  61919 }
  61920 
  61921 
  61922 /*
  61923  * Function:
  61924  *      bcm_esw_port_resource_get
  61925  * Purpose:
  61926  *      Get the port resource configuration for the specified logical port.
  61927  * Parameters:
  61928  *      unit      - (IN) Unit number.
  61929  *      port      - (IN) Logical port.
  61930  *      resource  - (OUT) Returns port resource information.
  61931  * Returns:
  61932  *      BCM_E_XXX
  61933  */
  61934 int
  61935 bcm_esw_port_resource_get(int unit,
  61936                           bcm_gport_t port, bcm_port_resource_t *resource)
  61937 {
  61938     int rv = BCM_E_UNAVAIL;
  61939 
  61940     PORT_INIT(unit);
  61941 
  61942     PORT_LOCK(unit);
  61943 
  61944     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  61945         if (BCM_ESW_PORT_DRV(unit)->resource_get != NULL) {
  61946             rv = BCM_ESW_PORT_DRV(unit)->resource_get(unit, port, resource);
  61947         }
  61948     }
  61949 
  61950     PORT_UNLOCK(unit);
  61951 
  61952     return rv;
  61953 }
  61954 
  61955 /*
  61956  * Function:
  61957  *      bcm_esw_port_resource_multi_set
  61958  * Purpose:
  61959  *      Modify the following port resources:
  61960  *      - Logical to physical port mapping
  61961  *      - Speedu
  61962  *      - Number of PHY lanes
  61963  *      - Encapsulation mode
  61964  * Parameters:
  61965  *      unit     - (IN) Unit number.
  61966  *      nport    - (IN) Number of elements in array resource.
  61967  *      resource - (IN) Port resource configuration array.
  61968  * Returns:
  61969  *      BCM_E_XXX
  61970  */
  61971 int
  61972 bcm_esw_port_resource_multi_set(int unit,
  61973                                 int nport, bcm_port_resource_t *resource)
  61974 {
  61975     int rv = BCM_E_UNAVAIL;
  61976 
  61977     PORT_INIT(unit);
  61978 
  61979     PORT_LOCK(unit);
  61980 
  61981     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  61982         if (BCM_ESW_PORT_DRV(unit)->resource_multi_set != NULL) {
  61983             rv = bcmi_esw_port_resource_portmod_support_check(unit,
  61984                                                               nport, resource);
  61985             if (BCM_SUCCESS(rv)) {
  61986                 rv = BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, nport,
  61987                                                                 resource);
  61988             }
  61989         }
  61990     }
  61991 
  61992     if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) {
  61993         BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, nport, resource);
  61994     }
  61995 
  61996     PORT_UNLOCK(unit);
  61997 
  61998     return rv;
  61999 }
  62000 /*
  62001  * Function:
  62002  *      bcm_esw_port_resource_speed_config_validate
  62003  * Purpose:
  62004  *      Validate the resource configuration
  62005  * Parameters:
  62006  *      unit      - (IN) Unit number.
  62007  *      resource  - (IN) Port resource information.
  62008  *      pbmp      - (OUT) Returns the affected sister ports
  62009  * Returns:
  62010  *      BCM_E_NONE - Config is honred without affecting sister ports
  62011  *      BCM_E_PARAM - Config will affect sister ports in pbmp
  62012  */
  62013 int
  62014 bcm_esw_port_resource_speed_config_validate(int unit,
  62015                            bcm_port_resource_t *resource, bcm_pbmp_t *pbmp)
  62016 {
  62017     int rv = BCM_E_UNAVAIL;
  62018 
  62019     /* Make sure port module is initialized. */
  62020     PORT_INIT(unit);
  62021 
  62022     /* Call Port Control module */
  62023     if (SOC_USE_PORTCTRL(unit)) {
  62024         BCM_IF_ERROR_RETURN
  62025             (bcmi_esw_port_resource_portmod_support_check(unit,
  62026                                                           1, resource));
  62027         rv = bcmi_esw_portctrl_resource_speed_config_validate(unit,
  62028                                                             resource, pbmp);
  62029     }
  62030 
  62031     return rv;
  62032 }
  62033 
  62034 /*
  62035  * Function:
  62036  *      bcm_esw_port_resource_speed_get
  62037  * Purpose:
  62038  *      Get the speed port resource configuration for the specified logical
  62039  *      port.
  62040  * Parameters:
  62041  *      unit      - (IN) Unit number.
  62042  *      port      - (IN) Logical port.
  62043  *      resource  - (OUT) Returns port resource information.
  62044  * Returns:
  62045  *      BCM_E_XXX
  62046  */
  62047 int
  62048 bcm_esw_port_resource_speed_get(int unit,
  62049                           bcm_gport_t port, bcm_port_resource_t *resource)
  62050 {
  62051     int rv = BCM_E_UNAVAIL;
  62052 
  62053     rv = bcm_esw_port_resource_get(unit, port, resource);
  62054 
  62055     return rv;
  62056 }
  62057 
  62058 /*
  62059  * Function:
  62060  *      bcm_esw_port_resource_speed_set
  62061  * Purpose:
  62062  *      Modify the following port resources:
  62063  *      - Speed
  62064  *      Note: The parameter for this function will be used to derive the
  62065  *            associated physical port
  62066  * Parameters:
  62067  *      unit     - (IN) Unit number.
  62068  *      gport    - (IN) Logical Port.
  62069  *      resource - (IN) Port resource configuration array.
  62070  * Returns:
  62071  *      BCM_E_XXX
  62072  */
  62073 int
  62074 bcm_esw_port_resource_speed_set(int unit,
  62075                                 bcm_gport_t port, bcm_port_resource_t *resource)
  62076 {
  62077     int rv = BCM_E_UNAVAIL;
  62078     int lport;
  62079 
  62080     if (NULL == resource) {
  62081         return BCM_E_PARAM;
  62082     }
  62083 
  62084     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &lport));
  62085 
  62086     /* Use the passed in logical port to be consistent with port_speed_set */
  62087     resource->port = lport;
  62088 
  62089     rv = bcm_esw_port_resource_speed_multi_set(unit, 1, resource);
  62090 
  62091     return rv;
  62092 }
  62093 
  62094 /*
  62095  * Function:
  62096  *      bcm_esw_port_resource_speed_multi_set
  62097  * Purpose:
  62098  *      Modify the following port resources:
  62099  *      - Speed
  62100  * Parameters:
  62101  *      unit     - (IN) Unit number.
  62102  *      nport    - (IN) Number of elements in array resource.
  62103  *      resource - (IN) Port resource configuration array.
  62104  * Returns:
  62105  *      BCM_E_XXX
  62106  */
  62107 int
  62108 bcm_esw_port_resource_speed_multi_set(int unit,
  62109                                 int nport, bcm_port_resource_t *resource)
  62110 {
  62111     int i, max_speed;
  62112     pbmp_t pbm;
  62113     int *enable;
  62114     int rv = BCM_E_UNAVAIL;
  62115 
  62116 
  62117     PORT_INIT(unit);
  62118 
  62119     /* Do this check because we don't want to allocate 4 billion ints
  62120      * if there's bad input
  62121      */
  62122     if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) {
  62123         return BCM_E_PARAM;
  62124     }
  62125 
  62126     if (resource == NULL) {
  62127         return BCM_E_PARAM;
  62128     }
  62129 
  62130     BCM_IF_ERROR_RETURN
  62131         (bcmi_esw_port_resource_portmod_support_check(unit,
  62132                                                       nport, resource));
  62133 
  62134     enable = sal_alloc(nport * sizeof(int), "port enable array");
  62135     if (NULL == enable) {
  62136         return BCM_E_MEMORY;
  62137     }
  62138 
  62139     /* Iterate through each entry and do some sanity checks */
  62140     for (i = 0; i < nport; i++) {
  62141         rv = (_bcm_esw_port_gport_validate(unit,
  62142                     resource[i].port, &resource[i].port));
  62143         if(!BCM_SUCCESS(rv)) {
  62144             goto speed_multi_cleanup;
  62145         }
  62146 
  62147         rv = (bcm_esw_port_speed_max(unit,resource[i].port, &max_speed));
  62148         if(!BCM_SUCCESS(rv)) {
  62149             goto speed_multi_cleanup;
  62150         }
  62151 
  62152 
  62153         if ((resource[i].speed < 0) || (resource[i].speed > max_speed)) {
  62154             if ((resource[i].speed > max_speed) &&
  62155                 !soc_feature(unit, soc_feature_flexport_based_speed_set))
  62156             rv = BCM_E_PARAM;
  62157             if(!BCM_SUCCESS(rv)) {
  62158                 goto speed_multi_cleanup;
  62159             }
  62160         }
  62161 
  62162         /*
  62163          * When performing flexport based speed changes, disable port
  62164          * first prior to affecting speed change, but keep track of whether
  62165          * the port was enabled
  62166          */
  62167         if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  62168             !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) &&
  62169             !SOC_PORT_USE_PORTCTRL(unit, resource[i].port)) {
  62170             rv = (bcm_esw_port_enable_get(unit,
  62171                                         resource[i].port, &enable[i]));
  62172             if(!BCM_SUCCESS(rv)) {
  62173                 goto speed_multi_cleanup;
  62174             }
  62175 
  62176             if (TRUE == enable[i]) {
  62177                 rv = (bcm_esw_port_enable_set(unit, resource[i].port, FALSE));
  62178                 if(!BCM_SUCCESS(rv)) {
  62179                     goto speed_multi_cleanup;
  62180                 }
  62181 
  62182             }
  62183         }
  62184 
  62185     }
  62186     PORT_LOCK(unit);
  62187     rv = bcmi_esw_portctrl_speed_multi_set(unit, nport, resource);
  62188     PORT_UNLOCK(unit);
  62189     if(!BCM_SUCCESS(rv)) {
  62190         goto speed_multi_cleanup;
  62191     }
  62192 
  62193     for (i = 0; i < nport; i++) {
  62194         /*
  62195          * Restore port's enable state based on what was read prior
  62196          * to setting speed
  62197          */
  62198         if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  62199             !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) &&
  62200             !SOC_PORT_USE_PORTCTRL(unit, resource[i].port)) {
  62201             if (TRUE == enable[i]) {
  62202                 rv = bcm_esw_port_enable_set(unit, resource[i].port, TRUE);
  62203                 if(!BCM_SUCCESS(rv)) {
  62204                     goto speed_multi_cleanup;
  62205                 }
  62206             }
  62207         }
  62208 
  62209         if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  62210             SOC_PBMP_CLEAR(pbm);
  62211             SOC_PBMP_PORT_ADD(pbm, resource[i].port);
  62212             (void)bcm_esw_link_change(unit, pbm);
  62213         }
  62214 
  62215         rv = _bcm_esw_port_link_delay_update(unit, resource[i].port,
  62216                                                 resource[i].speed);
  62217         if(!BCM_SUCCESS(rv)) {
  62218             goto speed_multi_cleanup;
  62219         }
  62220     }
  62221 
  62222 
  62223 speed_multi_cleanup:
  62224     if (NULL != enable) {
  62225         sal_free(enable);
  62226     }
  62227 
  62228     return rv;
  62229 }
  62230 /*
  62231  * Function:
  62232  *      bcm_esw_port_resource_traverse
  62233  * Purpose:
  62234  *      Iterates over the port resource configurations on a given
  62235  *      unit and calls user-provided callback for every entry.
  62236  * Parameters:
  62237  *      unit       - (IN) Unit number.
  62238  *      trav_fn    - (IN) Callback function to execute.
  62239  *      user_data  - (IN) Pointer to any user data.
  62240  * Returns:
  62241  *      BCM_E_XXX
  62242  */
  62243 int
  62244 bcm_esw_port_resource_traverse(int unit,
  62245                                bcm_port_resource_traverse_cb trav_fn,
  62246                                void *user_data)
  62247 {
  62248     int rv = BCM_E_UNAVAIL;
  62249 
  62250     PORT_INIT(unit);
  62251 
  62252     PORT_LOCK(unit);
  62253 
  62254     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  62255         if (BCM_ESW_PORT_DRV(unit)->resource_traverse != NULL) {
  62256             rv = BCM_ESW_PORT_DRV(unit)->resource_traverse(unit, trav_fn,
  62257                                                            user_data);
  62258         }
  62259     }
  62260 
  62261     PORT_UNLOCK(unit);
  62262 
  62263     return rv;
  62264 }
  62265 
  62266 /*
  62267  * Function:
  62268  *      bcm_esw_port_priority_group_mapping_set
  62269  * Purpose:
  62270  *      Assign a Priority Group for the input priority.
  62271  * Parameters:
  62272  *      unit       - (IN) device id.
  62273  *      gport     - (IN) generic port.
  62274  *      prio       - (IN) input priority.
  62275  *      priority_group  - (IN) priority group ID that the input priority mapped to.
  62276  * Returns:
  62277  *      BCM_E_XXX
  62278  */
  62279 int
  62280 bcm_esw_port_priority_group_mapping_set(int unit, bcm_gport_t gport, int prio, int priority_group)
  62281 {
  62282     int rv = BCM_E_UNAVAIL;
  62283 
  62284     PORT_INIT(unit);
  62285     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  62286 #ifdef BCM_SABER2_SUPPORT
  62287         if (SOC_IS_SABER2(unit)) {
  62288             return (bcm_kt2_port_priority_group_mapping_set(unit, gport, prio, priority_group));
  62289         }
  62290 #endif
  62291 #if defined(BCM_GREYHOUND_SUPPORT)
  62292         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  62293             return (bcm_gh_port_priority_group_mapping_set(unit, gport, prio, priority_group));
  62294         }
  62295 #endif /* BCM_GREYHOUND_SUPPORT */
  62296 #if defined(BCM_TRIDENT3_SUPPORT)
  62297         if (SOC_IS_TRIDENT3X(unit)) {
  62298             return (bcm_td3_port_priority_group_mapping_set(unit, gport, prio,
  62299                                                             priority_group));
  62300         }
  62301 #endif /* BCM_TRIDENT3_SUPPORT */
  62302 #if defined(BCM_TRIDENT2_SUPPORT)
  62303         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  62304             SOC_IS_TITAN2X(unit)) {
  62305             return (bcm_td2_port_priority_group_mapping_set(unit, gport, prio,
  62306                                                             priority_group));
  62307         }
  62308 #endif /* BCM_TRIDENT2_SUPPORT */
  62309 #if defined(BCM_TOMAHAWK3_SUPPORT)
  62310         if (SOC_IS_TOMAHAWK3(unit)) {
  62311             return BCM_E_UNAVAIL;
  62312         }
  62313 #endif /* BCM_TOMAHAWK3_SUPPORT */
  62314 #if defined(BCM_TOMAHAWK_SUPPORT)
  62315         if (SOC_IS_TOMAHAWKX(unit)) {
  62316             return (bcm_th_port_priority_group_mapping_set(unit, gport, prio,
  62317                                                             priority_group));
  62318         }
  62319 #endif /* BCM_TOMAHAWK_SUPPORT */
  62320 #if defined(BCM_APACHE_SUPPORT)
  62321         if (SOC_IS_APACHE(unit)){
  62322             return (bcm_ap_port_priority_group_mapping_set(unit, gport, prio,
  62323                                                             priority_group));
  62324         }
  62325 #endif
  62326     }
  62327     return rv;
  62328 }
  62329 
  62330 /*
  62331  * Function:
  62332  *      bcm_esw_port_priority_group_mapping_get
  62333  * Purpose:
  62334  *      Get the assigned Priority Group ID of the input priority.
  62335  * Parameters:
  62336  *      unit       - (IN) device id.
  62337  *      gport     - (IN) generic port.
  62338  *      prio       - (IN) input priority.
  62339  *      priority_group  - (OUT) priority group ID that the input priority mapped to.
  62340  * Returns:
  62341  *      BCM_E_XXX
  62342  */
  62343 int
  62344 bcm_esw_port_priority_group_mapping_get(int unit, bcm_gport_t gport, int prio, int *priority_group)
  62345 {
  62346     int rv = BCM_E_UNAVAIL;
  62347 
  62348     PORT_INIT(unit);
  62349     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  62350 #ifdef BCM_SABER2_SUPPORT
  62351         if (SOC_IS_SABER2(unit)) {
  62352             return (bcm_kt2_port_priority_group_mapping_get(unit, gport, prio, priority_group));
  62353         }
  62354 #endif
  62355 
  62356 #if defined(BCM_GREYHOUND_SUPPORT)
  62357         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  62358             return (bcm_gh_port_priority_group_mapping_get(unit, gport, prio, priority_group));
  62359         }
  62360 #endif /* BCM_GREYHOUND_SUPPORT */
  62361 #if defined(BCM_TRIDENT3_SUPPORT)
  62362         if (SOC_IS_TRIDENT3X(unit)) {
  62363             return (bcm_td3_port_priority_group_mapping_get(unit, gport, prio,
  62364                                                             priority_group));
  62365         }
  62366 #endif /* BCM_TRIDENT3_SUPPORT */
  62367 #if defined(BCM_TRIDENT2_SUPPORT)
  62368         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  62369             SOC_IS_TITAN2X(unit)) {
  62370             return (bcm_td2_port_priority_group_mapping_get(unit, gport, prio,
  62371                                                             priority_group));
  62372         }
  62373 #endif /* BCM_TRIDENT2_SUPPORT */
  62374 #if defined(BCM_TOMAHAWK3_SUPPORT)
  62375         if (SOC_IS_TOMAHAWK3(unit)) {
  62376             return BCM_E_UNAVAIL;
  62377         }
  62378 #endif /* BCM_TOMAHAWK3_SUPPORT */
  62379 #if defined(BCM_TOMAHAWK_SUPPORT)
  62380         if (SOC_IS_TOMAHAWKX(unit)) {
  62381             return (bcm_th_port_priority_group_mapping_get(unit, gport, prio,
  62382                                                             priority_group));
  62383         }
  62384 #endif /* BCM_TOMAHAWK_SUPPORT */
  62385 #if defined(BCM_APACHE_SUPPORT)
  62386         if (SOC_IS_APACHE(unit)) {
  62387             return (bcm_ap_port_priority_group_mapping_get(unit, gport, prio,
  62388                                                             priority_group));
  62389         }
  62390 #endif
  62391     }
  62392     return rv;
  62393 }
  62394 
  62395 /*
  62396  * Function:
  62397  *      bcm_esw_port_priority_group_config_set
  62398  * Purpose:
  62399  *      Set the port priority group configuration.
  62400  * Parameters:
  62401  *      unit       - (IN) device id.
  62402  *      gport     - (IN) generic port.
  62403  *      priority_group - (IN) priority group id.
  62404  *      prigrp_config  - (IN) structure describes port priority group configuration.
  62405  * Returns:
  62406  *      BCM_E_XXX
  62407  */
  62408 int
  62409 bcm_esw_port_priority_group_config_set(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
  62410 {
  62411     int rv = BCM_E_UNAVAIL;
  62412 
  62413     PORT_INIT(unit);
  62414     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  62415 #if defined(BCM_GREYHOUND_SUPPORT)
  62416         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  62417             return (bcm_gh_port_priority_group_config_set(unit, gport, priority_group, prigrp_config));
  62418         }
  62419 #endif /* BCM_GREYHOUND_SUPPORT */
  62420 #if defined(BCM_TRIDENT3_SUPPORT)
  62421         if (SOC_IS_TRIDENT3X(unit)) {
  62422             return (bcm_td3_port_priority_group_config_set(unit, gport,
  62423                         priority_group, prigrp_config));
  62424         }
  62425 #endif /* BCM_TRIDENT3_SUPPORT */
  62426 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  62427         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  62428             SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) ||
  62429             SOC_IS_APACHE(unit)) {
  62430             if (SOC_PORT_USE_PORTCTRL(unit, gport)) {
  62431                 return bcmi_esw_portctrl_priority_group_config_set(unit, gport,
  62432                         priority_group, prigrp_config);
  62433             }
  62434             return (bcm_td2_port_priority_group_config_set(unit, gport,
  62435                         priority_group, prigrp_config));
  62436         }
  62437 #endif /* BCM_TRIDENT2_SUPPORT */
  62438 #if defined(BCM_TOMAHAWK_SUPPORT)
  62439         if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
  62440             return (bcm_th_port_priority_group_config_set(unit, gport,
  62441                         priority_group, prigrp_config));
  62442         }
  62443 #endif /* BCM_TOMAHAWK_SUPPORT */
  62444 
  62445 #if defined(BCM_TOMAHAWK3_SUPPORT)
  62446         if(SOC_IS_TOMAHAWK3(unit)) {
  62447             return (bcm_th3_port_priority_group_config_set(unit, gport,
  62448                         priority_group, prigrp_config));
  62449         }
  62450 #endif
  62451 
  62452     }
  62453     return rv;
  62454 }
  62455 
  62456 /*
  62457  * Function:
  62458  *      bcm_esw_port_priority_group_config_get
  62459  * Purpose:
  62460  *      Get the port priority group configuration.
  62461  * Parameters:
  62462  *      unit       - (IN) device id.
  62463  *      gport     - (IN) generic port.
  62464  *      priority_group - (IN) priority group id.
  62465  *      prigrp_config  - (OUT) structure describes port priority group configuration.
  62466  * Returns:
  62467  *      BCM_E_XXX
  62468  */
  62469 int
  62470 bcm_esw_port_priority_group_config_get(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
  62471 {
  62472     int rv = BCM_E_UNAVAIL;
  62473 
  62474     PORT_INIT(unit);
  62475     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  62476 #if defined(BCM_GREYHOUND_SUPPORT)
  62477         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  62478             return (bcm_gh_port_priority_group_config_get(unit, gport, priority_group, prigrp_config));
  62479         }
  62480 #endif /* BCM_GREYHOUND_SUPPORT */
  62481 #if defined(BCM_TRIDENT3_SUPPORT)
  62482         if (SOC_IS_TRIDENT3X(unit)) {
  62483             return (bcm_td3_port_priority_group_config_get(unit, gport,
  62484                         priority_group, prigrp_config));
  62485         }
  62486 #endif /* BCM_TRIDENT3_SUPPORT */
  62487 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  62488         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  62489             SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) ||
  62490             SOC_IS_APACHE(unit)) {
  62491             return (bcm_td2_port_priority_group_config_get(unit, gport,
  62492                         priority_group, prigrp_config));
  62493         }
  62494 #endif /* BCM_TRIDENT2_SUPPORT */
  62495 
  62496 #if defined(BCM_TOMAHAWK3_SUPPORT)
  62497         if (SOC_IS_TOMAHAWK3(unit)) {
  62498             return (bcm_th3_port_priority_group_config_get(unit, gport,
  62499                         priority_group, prigrp_config));
  62500         }
  62501 #endif /* BCM_TOMAHAWK3_SUPPORT */
  62502 
  62503 #if defined(BCM_TOMAHAWK_SUPPORT)
  62504         if (SOC_IS_TOMAHAWKX(unit)) {
  62505             return (bcm_th_port_priority_group_config_get(unit, gport,
  62506                         priority_group, prigrp_config));
  62507         }
  62508 #endif /* BCM_TOMAHAWK_SUPPORT */
  62509 
  62510     }
  62511     return rv;
  62512 }
  62513 
  62514 /*
  62515  * Function:
  62516  *      bcm_esw_port_redirect_config_t_init
  62517  * Purpose:
  62518  *      Initialize the redirection config structure
  62519  * Parameters:
  62520  *      redirect_config  - (IN) Pointer to the redirection config structure
  62521  * Returns:
  62522  *      None
  62523  */
  62524 void bcm_esw_port_redirect_config_t_init(
  62525                     bcm_port_redirect_config_t *redirect_config)
  62526 {
  62527     return;
  62528 }
  62529 
  62530 /*
  62531  * Function:
  62532  *      bcm_esw_port_redirect_set
  62533  * Purpose:
  62534  *      Configure the redirection data
  62535  * Parameters:
  62536  *      unit             - (IN) device id.
  62537  *      port             - (IN) Port number.
  62538  *      redirect_config  - (IN) Pointer to the redirection config structure
  62539  * Returns:
  62540  *      None
  62541  */
  62542 int
  62543 bcm_esw_port_redirect_config_set(int unit, int port,
  62544                                  bcm_port_redirect_config_t *redirect_config)
  62545 {
  62546     int rv = BCM_E_UNAVAIL;
  62547 
  62548     PORT_INIT(unit);
  62549 
  62550     PORT_LOCK(unit);
  62551 
  62552     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  62553         if (BCM_ESW_PORT_DRV(unit)->port_redirect_set != NULL) {
  62554             rv = BCM_ESW_PORT_DRV(unit)->port_redirect_set(unit, port,
  62555                                                             redirect_config);
  62556         }
  62557     }
  62558 
  62559     PORT_UNLOCK(unit);
  62560 
  62561     return rv;
  62562 }
  62563 
  62564 
  62565 /*
  62566  * Function:
  62567  *      bcm_esw_port_redirect_get
  62568  * Purpose:
  62569  *      Configure the redirection data
  62570  * Parameters:
  62571  *      unit             - (IN) device id.
  62572  *      port             - (IN) Port number.
  62573  *      redirect_config  - (IN) Pointer to the redirection config structure
  62574  * Returns:
  62575  *      None
  62576  */
  62577 int
  62578 bcm_esw_port_redirect_config_get(int unit, int port,
  62579                                  bcm_port_redirect_config_t *redirect_config)
  62580 {
  62581     int rv = BCM_E_UNAVAIL;
  62582 
  62583     PORT_INIT(unit);
  62584 
  62585     PORT_LOCK(unit);
  62586 
  62587     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  62588         if (BCM_ESW_PORT_DRV(unit)->port_redirect_get != NULL) {
  62589             rv = BCM_ESW_PORT_DRV(unit)->port_redirect_get(unit, port,
  62590                                                             redirect_config);
  62591         }
  62592     }
  62593 
  62594     PORT_UNLOCK(unit);
  62595 
  62596     return rv;
  62597 }
  62598 
  62599 /*
  62600  * Function    : _bcm_esw_glp_bits_pos
  62601  * Description : Internal function to get modid, port, and trunk_id
  62602  *               from a glp
  62603  * Parameters  : (IN)  unit          - BCM device number
  62604  *               (OUT) trunk_pos     - Trunk ID position
  62605  *               (OUT) max_modid     - Max module ID bits
  62606  *               (OUT) modid_pos     - Module ID position
  62607  *               (OUT) max_port      - Max port addr bits
  62608  * Returns     : BCM_E_XXX
  62609  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  62610  *               get qualifiers for GLP related fields in FP_TCAM
  62611  */
  62612 static int
  62613 _bcm_esw_glp_bits_pos(int unit,
  62614                       uint8 *trunk_pos, uint8 *max_modid,
  62615                       uint8 *modid_pos, uint8 *max_port)
  62616 {
  62617     if ((NULL == trunk_pos) || (NULL == max_modid) || (NULL == modid_pos) ||
  62618         (NULL == max_port)) {
  62619         return BCM_E_PARAM;
  62620     }
  62621 
  62622 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)  || \
  62623     defined(BCM_TITAN_SUPPORT)  || defined(BCM_TRIDENT_SUPPORT)  || \
  62624     defined(BCM_TITAN2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  62625     defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  62626     defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \
  62627     defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  62628     if(SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit)  ||
  62629             SOC_IS_TITAN(unit)  || SOC_IS_TRIDENT(unit)  ||
  62630             SOC_IS_TITAN2(unit) || SOC_IS_TRIDENT2(unit) ||
  62631             SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit) ||
  62632             SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  62633             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  62634         *trunk_pos = 15;
  62635         *max_modid = 0xff;
  62636         *modid_pos = 7;
  62637         *max_port  = 0x7f;
  62638     } else
  62639 #endif
  62640 #if defined(BCM_TOMAHAWK_SUPPORT)
  62641         if (SOC_IS_TOMAHAWKX(unit)) {
  62642             *trunk_pos = 16;
  62643             *max_modid = 0xff;
  62644             *modid_pos = 8;
  62645             *max_port  = 0xff;
  62646         } else
  62647 #endif
  62648 #if defined(BCM_CONQUEROR_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || \
  62649     defined(BCM_SHADOW_SUPPORT)
  62650             if (SOC_IS_CONQUEROR(unit) || SOC_IS_SCORPION(unit) ||
  62651                 SOC_IS_SHADOW(unit)) {
  62652                 *trunk_pos = 14;
  62653                 *max_modid = 0xff;
  62654                 *modid_pos = 6;
  62655                 *max_port  = 0x3f;
  62656             } else
  62657 #endif
  62658 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  62659             defined(BCM_HAWKEYE_SUPPORT)
  62660             if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  62661                 *trunk_pos = 0;
  62662                 *max_modid = 0x0;
  62663                 *modid_pos = 6;
  62664                 *max_port  = 0x3f;
  62665             } else
  62666 #endif
  62667             {
  62668                 *trunk_pos = 13;
  62669                 *max_modid = 0x7f;
  62670                 *modid_pos = 6;
  62671                 *max_port  = 0x3f;
  62672             }
  62673 
  62674     return BCM_E_NONE;
  62675 }
  62676 
  62677 /*
  62678  * Function    : _bcm_esw_glp_construct
  62679  * Description : Internal function to set GLP port
  62680  *               from modid, port, and trunk_id
  62681  * Parameters  : (IN)  unit      - BCM device number
  62682  *               (IN)  modid     - Module ID
  62683  *               (IN)  port      - Port number
  62684  *               (IN)  trunk_id  - Trunk ID
  62685  *               (OUT) glp       - is trunk + modid + port num
  62686  * Returns     : BCM_E_XXX
  62687  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  62688  *               set qualifiers for GLP related fields in FP_TCAM
  62689  */
  62690 int
  62691 _bcm_esw_glp_construct(int unit, bcm_trunk_t trunk_id,
  62692                        bcm_module_t modid, bcm_port_t port,
  62693                        bcm_gport_t *glp)
  62694 {
  62695     uint8 trunk_pos = 0;
  62696     uint8 max_modid = 0;
  62697     uint8 modid_pos = 0;
  62698     uint8 max_port  = 0;
  62699 
  62700     if (NULL == glp) {
  62701         return BCM_E_PARAM;
  62702     }
  62703 
  62704     BCM_IF_ERROR_RETURN
  62705         (_bcm_esw_glp_bits_pos(unit,
  62706                        &trunk_pos, &max_modid,
  62707                        &modid_pos, &max_port));
  62708 
  62709     if (trunk_id != BCM_TRUNK_INVALID) {
  62710         *glp = ((1 << trunk_pos) | trunk_id);
  62711     } else {
  62712         *glp = (((modid & max_modid) << modid_pos) |
  62713                    (port & max_port));
  62714     }
  62715 
  62716     return BCM_E_NONE;
  62717 }
  62718 
  62719 /*
  62720  * Function    : _bcm_esw_glp_resolve
  62721  * Description : Internal function to get modid, port, and trunk_id
  62722  *               from a glp
  62723  * Parameters  : (IN)  unit      - BCM device number
  62724  *               (IN)  glp       - trunk + modid + port num
  62725  *               (OUT) modid     - Module ID
  62726  *               (OUT) port      - Port number
  62727  *               (OUT) trunk_id  - Trunk ID
  62728  * Returns     : BCM_E_XXX
  62729  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  62730  *               get qualifiers for GLP related fields in FP_TCAM
  62731  */
  62732 int
  62733 _bcm_esw_glp_resolve(int unit, bcm_trunk_t *trunk_id,
  62734                      bcm_module_t *modid, bcm_port_t *port,
  62735                      bcm_gport_t glp)
  62736 {
  62737     uint8 trunk_pos = 0;
  62738     uint8 max_modid = 0;
  62739     uint8 modid_pos = 0;
  62740     uint8 max_port  = 0;
  62741 
  62742     if ((NULL == trunk_id) || (NULL == modid) || (NULL == port)){
  62743         return BCM_E_PARAM;
  62744     }
  62745 
  62746     BCM_IF_ERROR_RETURN
  62747         (_bcm_esw_glp_bits_pos(unit,
  62748                        &trunk_pos, &max_modid,
  62749                        &modid_pos, &max_port));
  62750 
  62751     if (glp & (1 << trunk_pos)) {
  62752         *trunk_id = (glp & ~(1 << trunk_pos));
  62753     } else {
  62754         *port = (glp & max_port);
  62755         *modid = ((glp >> modid_pos) & max_modid);
  62756     }
  62757 
  62758     return BCM_E_NONE;
  62759 }
  62760 
  62761 /*
  62762  * Function    : _bcm_esw_gport_to_glp
  62763  * Description : Internal function to set GLP port from gport
  62764  * Parameters  : (IN)  unit      - BCM device number
  62765  *               (IN)  gport     - trunk + modid + port num
  62766  *               (OUT) glp       - trunk + modid + port num
  62767  * Returns     : BCM_E_XXX
  62768  * Notes       : The glport as Eg: 16 bits {T, MODID[7:0], PORT[7:0]},
  62769  *               get qualifiers for GLP related fields in FP_TCAM
  62770  */
  62771 int
  62772 _bcm_esw_gport_to_glp(int unit, bcm_gport_t gport, bcm_gport_t *glp)
  62773 {
  62774     bcm_trunk_t  trunk_id;
  62775     bcm_module_t mod_id;
  62776     bcm_port_t   port;
  62777     int          local_id;
  62778 
  62779     if (BCM_GPORT_IS_SET(gport)) {
  62780         SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &mod_id,
  62781                     &port, &trunk_id, &local_id));
  62782 
  62783         BCM_IF_ERROR_RETURN
  62784             (_bcm_esw_glp_construct(unit,
  62785                                     trunk_id, mod_id,
  62786                                     port, glp));
  62787         return BCM_E_NONE;
  62788     }
  62789 
  62790     return BCM_E_PARAM;
  62791 }
  62792 
  62793 /*
  62794  * Function:
  62795  *      bcmi_esw_port_eee_cfg_get
  62796  * Purpose:
  62797  *      Set the eee_cfg value for given port.
  62798  * Parameters:
  62799  *      unit     - (IN) Unit number.
  62800  *      port     - (IN) Logical port, BCM format.
  62801  *      value    - (IN) Value to set.
  62802  * Returns:
  62803  *      BCM_E_XXX
  62804  * Notes:
  62805  */
  62806 int
  62807 bcmi_esw_port_eee_cfg_set(int unit, bcm_port_t port, int value)
  62808 {
  62809 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  62810     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \
  62811     defined(BCM_HURRICANE2_SUPPORT)
  62812     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  62813         return BCM_E_PORT;
  62814     }
  62815 
  62816     eee_cfg[unit][port] = value;
  62817 
  62818     return BCM_E_NONE;
  62819 #else
  62820     return BCM_E_UNAVAIL;
  62821 #endif
  62822 }
  62823 
  62824 
  62825 /*
  62826  * Function:
  62827  *      bcmi_esw_port_egr_prof_ptr_set
  62828  * Purpose:
  62829  *      Set the port_src_mod_egr_prof_ptr value for given port.
  62830  * Parameters:
  62831  *      unit          - (IN) Unit number.
  62832  *      port          - (IN) Logical port, BCM format.
  62833  *      egr_prof_ptr  - (IN) Value to set.
  62834  * Returns:
  62835  *      BCM_E_XXX
  62836  * Notes:
  62837  */
  62838 int
  62839 bcmi_esw_port_egr_prof_ptr_set(int unit, bcm_port_t port, int value)
  62840 {
  62841 #ifdef BCM_TRIUMPH2_SUPPORT
  62842     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  62843         return BCM_E_PORT;
  62844     }
  62845 
  62846     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = value;
  62847 
  62848     return BCM_E_NONE;
  62849 #else
  62850     return BCM_E_UNAVAIL;
  62851 #endif /* BCM_TRIUMPH2_SUPPORT */
  62852 }
  62853 
  62854 
  62855 /*
  62856  * Function:
  62857  *      bcmi_port_force_lb_set
  62858  * Purpose:
  62859  *      Force port into internal loopback accroding to bond options.
  62860  * Parameters:
  62861  *      unit          - (IN) Unit number.
  62862  *      port          - (IN) Logical port, BCM format.
  62863  *      egr_prof_ptr  - (IN) Value to set.
  62864  * Returns:
  62865  *      BCM_E_XXX
  62866  * Notes:
  62867  */
  62868 int
  62869 bcmi_port_force_lb_set(int unit)
  62870 {
  62871     int rv = BCM_E_UNAVAIL;
  62872 
  62873     PORT_INIT(unit);
  62874 
  62875     PORT_LOCK(unit);
  62876 
  62877     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  62878         if (BCM_ESW_PORT_DRV(unit)->force_lb_set != NULL) {
  62879             rv = BCM_ESW_PORT_DRV(unit)->force_lb_set(unit);
  62880         }
  62881     }
  62882 
  62883     PORT_UNLOCK(unit);
  62884 
  62885     return rv;
  62886 }
  62887 
  62888 /*
  62889  * Function:
  62890  *      bcm_esw_port_preemption_control_set
  62891  * Purpose:
  62892  *      Set various configurations for Preemption.
  62893  * Parameters:
  62894  *      unit         - (IN) Unit number.
  62895  *      gport        - (IN) gport id
  62896  *      type         - (IN) preemption control type defined in bcm_port_preempt_control_t
  62897  *      arg          - (IN) the preemption control value
  62898  * Returns:
  62899  *      BCM_E_XXX
  62900  * Notes:
  62901  */
  62902 int
  62903 bcm_esw_port_preemption_control_set(int unit, bcm_gport_t gport,
  62904                                     bcm_port_preempt_control_t type,
  62905                                     uint32 arg)
  62906 {
  62907     PORT_INIT(unit);
  62908 
  62909 #if defined(BCM_PREEMPTION_SUPPORT)
  62910     if (soc_feature(unit, soc_feature_preemption)) {
  62911         bcm_port_t local_port;
  62912         uint32 preempt_support;
  62913 #ifdef BCM_MONTEREY_SUPPORT
  62914         int link = BCM_PORT_LINK_STATUS_DOWN;
  62915 #endif
  62916 
  62917         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  62918         if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) {
  62919             /* hg port does not support preemption */
  62920             BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL);
  62921         }
  62922 #ifdef BCM_MONTEREY_SUPPORT
  62923         if (SOC_IS_MONTEREY(unit)) {
  62924             if ((type == bcmPortPreemptControlVerifyTime) ||
  62925                 (type == bcmPortPreemptControlVerifyAttempts) ||
  62926                 (type == bcmPortPreemptControlVerifyEnable)) {
  62927                 return BCM_E_UNAVAIL;
  62928             }
  62929             if (type == bcmPortPreemptControlPreemptionSupport) {
  62930                 /* Intentionally supreesing return type to avoid unrelated error */
  62931                 (void)_bcm_esw_link_get(unit, local_port, &link);
  62932                 if (!arg && (link == BCM_PORT_LINK_STATUS_UP)) {
  62933                     return BCM_E_CONFIG;
  62934                 }
  62935             }
  62936         }
  62937 #endif /* BCM_MONTEREY_SUPPORT */
  62938         PORT_LOCK(unit);
  62939         switch (type) {
  62940             /*  only need set mac-related */
  62941             case bcmPortPreemptControlEnableTx:
  62942             case bcmPortPreemptControlVerifyEnable:
  62943                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62944                     bcmi_esw_preemption_capability_get(unit,
  62945                                                        local_port,
  62946                                                        &preempt_support));
  62947                 if (0 == preempt_support) {
  62948                     /* need to enable preempt ability on this port first */
  62949                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  62950                 }
  62951             /* fall-through */
  62952             case bcmPortPreemptControlVerifyTime:
  62953             case bcmPortPreemptControlVerifyAttempts:
  62954             case bcmPortPreemptControlNonFinalFragSizeRx:
  62955             case bcmPortPreemptControlFinalFragSizeRx:
  62956                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62957                     bcmi_esw_preemption_mac_config_set(unit,
  62958                                                        local_port,
  62959                                                        type, arg));
  62960                 break;
  62961             /* only need setup chip-related */
  62962             case bcmPortPreemptControlNonFinalFragSizeTx:
  62963                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62964                     bcmi_esw_preemption_frag_config_tx_set(unit,
  62965                                                            local_port, 0,
  62966                                                            arg));
  62967                 break;
  62968             case bcmPortPreemptControlFinalFragSizeTx:
  62969                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62970                     bcmi_esw_preemption_frag_config_tx_set(unit,
  62971                                                            local_port, 1,
  62972                                                            arg));
  62973                 break;
  62974             case bcmPortPreemptControlHoldReqCntMode:
  62975                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62976                     bcmi_esw_preemption_hold_request_mode_set(unit,
  62977                                                               local_port,
  62978                                                               arg));
  62979                 break;
  62980             case bcmPortPreemptControlQueueBitmap:
  62981                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62982                     bcmi_esw_preemption_queue_bitmap_set(unit,
  62983                                                          local_port,
  62984                                                          arg));
  62985                 break;
  62986             case bcmPortPreemptControlPreemptionSupport:
  62987                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  62988                     bcmi_esw_preemption_capability_set(unit,
  62989                                                        local_port,
  62990                                                        arg));
  62991                 break;
  62992             default:
  62993                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  62994 
  62995         }
  62996         PORT_UNLOCK(unit);
  62997         return BCM_E_NONE;
  62998     } else
  62999 #endif /* BCM_PREEMPTION_SUPPORT */
  63000     {
  63001         return BCM_E_UNAVAIL;
  63002     }
  63003 }
  63004 
  63005 
  63006 /*
  63007  * Function:
  63008  *      bcmi_esw_port_mac_type_get
  63009  * Purpose:
  63010  *      Get mactype for a given logical port
  63011  * Parameters:
  63012  *      unit         - (IN) Unit number.
  63013  *      lport        - (IN) logical port
  63014  *      type         - (OUT) mac type defined in bcmi_port_mac_type_t
  63015  * Returns:
  63016  *      BCM_E_XXX
  63017  * Notes:
  63018  */
  63019 int bcmi_esw_port_mac_type_get(int unit, bcm_port_t lport,
  63020                                bcmi_port_mac_type_t *type) {
  63021 #if defined(BCM_GREYHOUND2_SUPPORT)
  63022     if(SOC_IS_GREYHOUND2(unit)) {
  63023         return bcmi_gh2_port_mac_type_get(unit, lport, type);
  63024     } else
  63025 #endif /* BCM_GREYHOUND2_SUPPORT */
  63026     {
  63027         if (NULL == type) {
  63028             return SOC_E_PARAM;
  63029         }
  63030         *type = bcmiPortMacTypePortmode;
  63031     }
  63032     return BCM_E_NONE;
  63033 }
  63034 
  63035 /*
  63036  * Function:
  63037  *      bcm_esw_port_preemption_control_get
  63038  * Purpose:
  63039  *      Get various configurations for Preemption.
  63040  * Parameters:
  63041  *      unit         - (IN) Unit number.
  63042  *      gport        - (IN) gport id
  63043  *      type         - (IN) preemption control type defined in bcm_port_preempt_control_t
  63044  *      arg          - (OUT) the preemption control value
  63045  * Returns:
  63046  *      BCM_E_XXX
  63047  * Notes:
  63048  */
  63049 int
  63050 bcm_esw_port_preemption_control_get(int unit, bcm_gport_t gport,
  63051                                     bcm_port_preempt_control_t type,
  63052                                     uint32 *arg)
  63053 {
  63054     PORT_INIT(unit);
  63055 
  63056 #if defined(BCM_PREEMPTION_SUPPORT)
  63057     if (soc_feature(unit, soc_feature_preemption)) {
  63058         bcm_port_t local_port;
  63059 
  63060         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  63061         if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) {
  63062             /* hg port does not support preemption */
  63063             BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL);
  63064         }
  63065 #ifdef BCM_MONTEREY_SUPPORT
  63066         if (SOC_IS_MONTEREY(unit)) {
  63067             if ((type == bcmPortPreemptControlVerifyTime) ||
  63068                 (type == bcmPortPreemptControlVerifyAttempts) ||
  63069                 (type == bcmPortPreemptControlVerifyEnable)) {
  63070                 return BCM_E_UNAVAIL;
  63071             }
  63072         }
  63073 #endif /* BCM_MONTEREY_SUPPORT */
  63074         PORT_LOCK(unit);
  63075         switch (type) {
  63076             /*  mac-related */
  63077             case bcmPortPreemptControlEnableTx:
  63078             case bcmPortPreemptControlVerifyEnable:
  63079             case bcmPortPreemptControlVerifyTime:
  63080             case bcmPortPreemptControlVerifyAttempts:
  63081             case bcmPortPreemptControlNonFinalFragSizeRx:
  63082             case bcmPortPreemptControlFinalFragSizeRx:
  63083                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63084                     bcmi_esw_preemption_mac_config_get(unit,
  63085                                                        local_port,
  63086                                                        type, arg));
  63087                 break;
  63088             /* chip-related */
  63089             case bcmPortPreemptControlNonFinalFragSizeTx:
  63090                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63091                     bcmi_esw_preemption_frag_config_tx_get(unit,
  63092                                                            local_port, 0,
  63093                                                            arg));
  63094                 break;
  63095             case bcmPortPreemptControlFinalFragSizeTx:
  63096                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63097                     bcmi_esw_preemption_frag_config_tx_get(unit,
  63098                                                            local_port, 1,
  63099                                                            arg));
  63100                 break;
  63101             case bcmPortPreemptControlHoldReqCntMode:
  63102                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63103                     bcmi_esw_preemption_hold_request_mode_get(unit,
  63104                                                               local_port,
  63105                                                               arg));
  63106                 break;
  63107             case bcmPortPreemptControlQueueBitmap:
  63108                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63109                     bcmi_esw_preemption_queue_bitmap_get(unit,
  63110                                                          local_port,
  63111                                                          arg));
  63112                 break;
  63113             case bcmPortPreemptControlPreemptionSupport:
  63114                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63115                     bcmi_esw_preemption_capability_get(unit,
  63116                                                        local_port,
  63117                                                        arg));
  63118                 break;
  63119             default:
  63120                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  63121 
  63122         }
  63123         PORT_UNLOCK(unit);
  63124         return BCM_E_NONE;
  63125     } else
  63126 #endif /* BCM_PREEMPTION_SUPPORT */
  63127     {
  63128         return BCM_E_UNAVAIL;
  63129     }
  63130 }
  63131 
  63132 
  63133 /*
  63134  * Function:
  63135  *      bcm_esw_port_preemption_status_get
  63136  * Purpose:
  63137  *      Get the specified preemption status.
  63138  * Parameters:
  63139  *      unit         - (IN) Unit number.
  63140  *      gport        - (IN) gport id
  63141  *      type         - (IN) preemption status type defined in bcm_port_preempt_status_t
  63142  *      status       - (OUT) the preemption status
  63143  *                           For bcmPortPreemptStatusTx type, the status value
  63144  *                           defined in bcm_port_preempt_status_tx_t.
  63145  *                           For bcmPortPreemptStatusVerify type, the status value
  63146  *                           defined in bcm_port_preempt_status_verify_t.
  63147  * Returns:
  63148  *      BCM_E_XXX
  63149  * Notes:
  63150  */
  63151 int bcm_esw_port_preemption_status_get(int unit, bcm_gport_t gport,
  63152                                        bcm_port_preempt_status_t type,
  63153                                        uint32 *status)
  63154 {
  63155     PORT_INIT(unit);
  63156 
  63157 #if defined(BCM_PREEMPTION_SUPPORT)
  63158     if (soc_feature(unit, soc_feature_preemption)) {
  63159         bcm_port_t local_port;
  63160         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  63161         PORT_LOCK(unit);
  63162         switch (type) {
  63163             case bcmPortPreemptStatusTx:
  63164                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63165                     bcmi_esw_preemption_status_tx_get(unit, local_port,
  63166                                                       status));
  63167                 break;
  63168             case bcmPortPreemptStatusVerify:
  63169                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  63170                     bcmi_esw_preemption_status_verify_get(unit, local_port,
  63171                                                           status));
  63172                 break;
  63173             default:
  63174                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  63175         }
  63176         PORT_UNLOCK(unit);
  63177         return BCM_E_NONE;
  63178     } else
  63179 #endif /* BCM_PREEMPTION_SUPPORT */
  63180     {
  63181         return BCM_E_UNAVAIL;
  63182     }
  63183 }
  63184 
  63185 /*
  63186  * Description:
  63187  *      Enable and configure the remote module to apply E2EFC mechanism.
  63188  *      Or disable it.
  63189  * Parameter:
  63190  *      unit           - (IN) unit number
  63191  *      remote_module  - (IN) remote module id
  63192  *      mode           - (IN) selected mode
  63193  *      enable         - (IN) enable or disable selection
  63194  *      e2efc_rmod_cfg - (IN) structure containing the configuration.
  63195  *                       Ignored when enable = 0.
  63196  */
  63197 int
  63198 bcm_esw_port_e2efc_remote_module_enable_set(
  63199     int unit,
  63200     bcm_module_t remote_module,
  63201     bcm_port_e2efc_mode_t mode,
  63202     int enable,
  63203     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
  63204 {
  63205     if (e2efc_rmod_cfg == NULL) {
  63206         return BCM_E_UNAVAIL;
  63207     }
  63208 
  63209     if (soc_feature(unit, soc_feature_e2efc)) {
  63210 #if defined(BCM_GREYHOUND2_SUPPORT)
  63211         if (SOC_IS_GREYHOUND2(unit)) {
  63212             return bcmi_gh2_port_e2efc_remote_module_enable_set(unit,
  63213                                 remote_module, mode, enable, e2efc_rmod_cfg);
  63214         }
  63215 #endif /* BCM_GREYHOUND2_SUPPORT */
  63216 
  63217 #if defined(BCM_KATANA2_SUPPORT)
  63218         if (SOC_IS_KATANA2(unit)) {
  63219             return bcmi_kt2_port_e2efc_remote_module_enable_set(unit,
  63220                                 remote_module, mode, enable, e2efc_rmod_cfg);
  63221         }
  63222 #endif /* BCM_KATANA2_SUPPORT */
  63223     }
  63224 
  63225     return BCM_E_UNAVAIL;
  63226 }
  63227 
  63228 /*
  63229  * Description:
  63230  *      Get the enable mode and configuration of the remote module that
  63231  *      applies E2EFC mechanism.
  63232  * Parameter:
  63233  *      unit           - (IN) unit number
  63234  *      remote_module  - (IN) remote module id
  63235  *      mode           - (IN) selected mode
  63236  *      enable         - (OUT) enable or disable selection
  63237  *      e2efc_rmod_cfg - (OUT) structure containing the configuration.
  63238  *                       Only valid if the remote module is enabled.
  63239  */
  63240 int
  63241 bcm_esw_port_e2efc_remote_module_enable_get(
  63242     int unit,
  63243     bcm_module_t remote_module,
  63244     bcm_port_e2efc_mode_t mode,
  63245     int *enable,
  63246     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
  63247 {
  63248 
  63249     if (e2efc_rmod_cfg == NULL || enable == NULL) {
  63250         return BCM_E_UNAVAIL;
  63251     }
  63252 
  63253     if (soc_feature(unit, soc_feature_e2efc)) {
  63254 #if defined(BCM_GREYHOUND2_SUPPORT)
  63255         if (SOC_IS_GREYHOUND2(unit)) {
  63256             return bcmi_gh2_port_e2efc_remote_module_enable_get(unit,
  63257                                 remote_module, mode, enable, e2efc_rmod_cfg);
  63258         }
  63259 #endif /* BCM_GREYHOUND2_SUPPORT */
  63260 
  63261 #if defined(BCM_KATANA2_SUPPORT)
  63262         if (SOC_IS_KATANA2(unit)) {
  63263             return bcmi_kt2_port_e2efc_remote_module_enable_get(unit,
  63264                                 remote_module, mode, enable, e2efc_rmod_cfg);
  63265         }
  63266 #endif /* BCM_KATANA2_SUPPORT */
  63267     }
  63268 
  63269     return BCM_E_UNAVAIL;
  63270 }
  63271 
  63272 /*
  63273  * Description:
  63274  *      Traverse enabled remote modules that apply E2EFC mechanism.
  63275  * Parameter:
  63276  *      unit      - (IN) unit number
  63277  *      cb        - (IN) call back function to execute
  63278  *      user_data - (IN) pointer to user data
  63279 */
  63280 int
  63281 bcm_esw_port_e2efc_remote_module_traverse(
  63282     int unit,
  63283     bcm_port_e2efc_remote_module_traverse_cb cb,
  63284     void *user_data)
  63285 {
  63286     if ( user_data == NULL || cb == NULL) {
  63287         return BCM_E_PARAM;
  63288     }
  63289 
  63290     if (soc_feature(unit, soc_feature_e2efc)) {
  63291 #if defined(BCM_GREYHOUND2_SUPPORT)
  63292         if (SOC_IS_GREYHOUND2(unit)) {
  63293             return bcmi_gh2_port_e2efc_remote_module_traverse(unit, cb,
  63294                                                               user_data);
  63295         }
  63296 #endif /* BCM_GREYHOUND2_SUPPORT */
  63297 
  63298 #if defined(BCM_KATANA2_SUPPORT)
  63299         if (SOC_IS_KATANA2(unit)) {
  63300             return bcmi_kt2_port_e2efc_remote_module_traverse(unit, cb,
  63301                                                               user_data);
  63302         }
  63303 #endif /* BCM_KATANA2_SUPPORT */
  63304     }
  63305     return BCM_E_UNAVAIL;
  63306 }
  63307 
  63308 /*
  63309  * Description:
  63310  *      Add remote module-port and set configuration.
  63311  *      Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs.
  63312  *      The API of remote module-port configuration is only for E2EFC
  63313  *      transmission.
  63314  * Parameter:
  63315  *      unit            - (IN) unit number
  63316  *      e2efc_rport_cfg - (IN) structure containing the configuration
  63317  *      rport_handle_id - (OUT) remote port handle id, to be used for the rest
  63318  *                        of bcm_port_e2efc_remote_port_xxx APIs
  63319  */
  63320 int
  63321 bcm_esw_port_e2efc_remote_port_add(
  63322     int unit,
  63323     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg,
  63324     int *rport_handle_id)
  63325 {
  63326     if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) {
  63327         return BCM_E_UNAVAIL;
  63328     }
  63329     if (soc_feature(unit, soc_feature_e2efc)) {
  63330 #if defined(BCM_GREYHOUND2_SUPPORT)
  63331         if (SOC_IS_GREYHOUND2(unit)) {
  63332             return bcmi_gh2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg,
  63333                                                        rport_handle_id);
  63334         }
  63335 #endif /* BCM_GREYHOUND2_SUPPORT */
  63336 
  63337 #if defined(BCM_KATANA2_SUPPORT)
  63338         if (SOC_IS_KATANA2(unit)) {
  63339             return bcmi_kt2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg,
  63340                                                        rport_handle_id);
  63341         }
  63342 #endif /* BCM_KATANA2_SUPPORT */
  63343     }
  63344     return BCM_E_UNAVAIL;
  63345 }
  63346 
  63347 /*
  63348  * Description:
  63349  *      Set (modify) configuration of the remote port.
  63350  * Parameter:
  63351  *      unit            - (IN) unit number
  63352  *      rport_handle_id - (IN) remote port handle id
  63353  *      e2efc_rport_cfg - (IN) structure containing the configuration
  63354  */
  63355 int
  63356 bcm_esw_port_e2efc_remote_port_set(
  63357     int unit,
  63358     int rport_handle_id,
  63359     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
  63360 {
  63361     if (e2efc_rport_cfg == NULL) {
  63362         return BCM_E_UNAVAIL;
  63363     }
  63364     if (soc_feature(unit, soc_feature_e2efc)) {
  63365 #if defined(BCM_GREYHOUND2_SUPPORT)
  63366         if (SOC_IS_GREYHOUND2(unit)) {
  63367             return bcmi_gh2_port_e2efc_remote_port_set(unit, rport_handle_id,
  63368                                                        e2efc_rport_cfg);
  63369         }
  63370 #endif /* BCM_GREYHOUND2_SUPPORT */
  63371 
  63372 #if defined(BCM_KATANA2_SUPPORT)
  63373         if (SOC_IS_KATANA2(unit)) {
  63374             return bcmi_kt2_port_e2efc_remote_port_set(unit, rport_handle_id,
  63375                                                        e2efc_rport_cfg);
  63376         }
  63377 #endif /* BCM_KATANA2_SUPPORT */
  63378     }
  63379     return BCM_E_UNAVAIL;
  63380 }
  63381 
  63382 /*
  63383  * Description:
  63384  *      Get configuration of the remote port.
  63385  *      Return the remote module, remote port and configuration of the
  63386  *      handle id.
  63387  * Parameter:
  63388  *      unit            - (IN) unit number
  63389  *      rport_handle_id - (IN) remote port handle id
  63390  *      e2efc_rport_cfg - (OUT) structure containing the configuration
  63391  */
  63392 int
  63393 bcm_esw_port_e2efc_remote_port_get(
  63394     int unit,
  63395     int rport_handle_id,
  63396     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
  63397 {
  63398     if (e2efc_rport_cfg == NULL) {
  63399         return BCM_E_UNAVAIL;
  63400     }
  63401     if (soc_feature(unit, soc_feature_e2efc)) {
  63402 #if defined(BCM_GREYHOUND2_SUPPORT)
  63403         if (SOC_IS_GREYHOUND2(unit)) {
  63404             return bcmi_gh2_port_e2efc_remote_port_get(unit, rport_handle_id,
  63405                                                        e2efc_rport_cfg);
  63406         }
  63407 #endif /* BCM_GREYHOUND2_SUPPORT */
  63408 
  63409 #if defined(BCM_KATANA2_SUPPORT)
  63410         if (SOC_IS_KATANA2(unit)) {
  63411             return bcmi_kt2_port_e2efc_remote_port_get(unit, rport_handle_id,
  63412                                                        e2efc_rport_cfg);
  63413         }
  63414 #endif /* BCM_KATANA2_SUPPORT */
  63415     }
  63416     return BCM_E_UNAVAIL;
  63417 }
  63418 
  63419 /*
  63420  * Description:
  63421  *      Delete remote port.
  63422  * Parameter:
  63423  *      unit            - (IN) unit number
  63424  *      rport_handle_id - (IN) remote port handle id
  63425  */
  63426 int
  63427 bcm_esw_port_e2efc_remote_port_delete(
  63428     int unit,
  63429     int rport_handle_id)
  63430 {
  63431 
  63432     if (soc_feature(unit, soc_feature_e2efc)) {
  63433 #if defined(BCM_GREYHOUND2_SUPPORT)
  63434         if (SOC_IS_GREYHOUND2(unit)) {
  63435             return bcmi_gh2_port_e2efc_remote_port_delete(unit,
  63436                                                           rport_handle_id);
  63437         }
  63438 #endif /* BCM_GREYHOUND2_SUPPORT */
  63439 
  63440 #if defined(BCM_KATANA2_SUPPORT)
  63441         if (SOC_IS_KATANA2(unit)) {
  63442             return bcmi_kt2_port_e2efc_remote_port_delete(unit,
  63443                                                           rport_handle_id);
  63444         }
  63445 #endif /* BCM_KATANA2_SUPPORT */
  63446     }
  63447     return BCM_E_UNAVAIL;
  63448 }
  63449 
  63450 /*
  63451  * Description:
  63452  *      Traverse remote ports.
  63453  * Parameter:
  63454  *      unit      - (IN) unit number
  63455  *      cb        - (IN) call back function to execute
  63456  *      user_data - (IN) pointer to user data
  63457  */
  63458 int
  63459 bcm_esw_port_e2efc_remote_port_traverse(
  63460     int unit,
  63461     bcm_port_e2efc_remote_port_traverse_cb cb,
  63462     void *user_data)
  63463 {
  63464     if ( user_data == NULL || cb == NULL) {
  63465         return BCM_E_PARAM;
  63466     }
  63467 
  63468     if (soc_feature(unit, soc_feature_e2efc)) {
  63469 #if defined(BCM_GREYHOUND2_SUPPORT)
  63470         if (SOC_IS_GREYHOUND2(unit)) {
  63471             return bcmi_gh2_port_e2efc_remote_port_traverse(unit, cb,
  63472                                                             user_data);
  63473         }
  63474 #endif /* BCM_GREYHOUND2_SUPPORT */
  63475 
  63476 #if defined(BCM_KATANA2_SUPPORT)
  63477         if (SOC_IS_KATANA2(unit)) {
  63478             return bcmi_kt2_port_e2efc_remote_port_traverse(unit, cb,
  63479                                                             user_data);
  63480         }
  63481 #endif /* BCM_KATANA2_SUPPORT */
  63482     }
  63483     return BCM_E_UNAVAIL;
  63484 }
  63485 
  63486 #ifdef SW_AUTONEG_SUPPORT
  63487 /*
  63488  * Function    : _bcm_esw_port_notify_link_down_evt
  63489  * Description : Notify Link_Down event to SW AN SM.
  63490  * Parameters  : (IN) unit      - BCM device number
  63491  *               (IN) port       - Port number
  63492  * Returns     : BCM_E_XXX
  63493  */
  63494 int
  63495 _bcm_esw_port_notify_link_down_evt(int unit, bcm_port_t port)
  63496 {
  63497     int    an_mode = 0;
  63498     int    an_enabled = 0;
  63499     int    rv = BCM_E_NONE;
  63500 
  63501     if (soc_feature(unit, soc_feature_sw_autoneg)) {
  63502         /* if the link is down notify the SW AN thread
  63503          * to restart AN if AN is enabled for the port
  63504          */
  63505         an_mode = soc_property_port_get(unit, port,
  63506                           spn_PHY_AN_C73, an_mode);
  63507 
  63508         /* phy_an_c73 value of 3 indicated MSA AN mode */
  63509         if ((an_mode == SW_AN_MODE_CL73_MSA) ||
  63510             (an_mode == SW_AN_MODE_MSA_ONLY)) {
  63511 
  63512 
  63513             rv = bcm_esw_port_autoneg_get(unit, port , &an_enabled);
  63514             if (BCM_FAILURE(rv)) {
  63515                 LOG_WARN(BSL_LS_BCM_PORT,
  63516                          (BSL_META_U(unit,
  63517                                      "u=%d p=%d AUTONEG GET FALSE rv=%d\n"),
  63518                           unit, port, rv));
  63519                 return rv;
  63520             }
  63521 
  63522             if (an_enabled) {
  63523                 /* notify the SW AN thread of link down event */
  63524                 rv = bcm_sw_an_post_event(unit, port, BCM_PORT_SW_AN_EVENT_AN_LINK_DOWN);
  63525             }
  63526 
  63527             if (BCM_FAILURE(rv)) {
  63528                 LOG_WARN(BSL_LS_BCM_PORT,
  63529                          (BSL_META_U(unit,
  63530                                      "u=%d p=%d SW AN POST EVENT FAILED rv=%d\n"),
  63531                           unit, port, rv));
  63532             }
  63533         }
  63534     }
  63535     return BCM_E_NONE;
  63536 }
  63537 #endif
  63538 
  63539 
  63540 /*
  63541  * Function:
  63542  *      bcm_esw_port_phy_tx_set
  63543  * Purpose:
  63544  *      Set port phy tx properties
  63545  * Parameters:
  63546  *      unit - StrataSwitch Unit #.
  63547  *      port - StrataSwitch port #.
  63548  *      tx   - tx properties
  63549  * Returns:
  63550  *      BCM_E_NONE
  63551  *      BCM_E_XXX
  63552  */
  63553 int
  63554 bcm_esw_port_phy_tx_set(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) {
  63555     int rv = BCM_E_UNAVAIL;
  63556 
  63557     if (NULL == tx) {
  63558         return BCM_E_PARAM;
  63559     }
  63560 
  63561     /* Make sure port module is initialized. */
  63562     PORT_INIT(unit);
  63563 
  63564     if (SOC_IS_TOMAHAWK3(unit)) {
  63565         /* Call Port Control module */
  63566         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  63567             rv = bcmi_esw_portctrl_phy_tx_set(unit, port, tx);
  63568         }
  63569     }
  63570 
  63571     return rv;
  63572 }
  63573 
  63574 /*
  63575  * Function:
  63576  *      bcm_esw_port_phy_tx_get
  63577  * Purpose:
  63578  *      Get port phy tx properties
  63579  * Parameters:
  63580  *      unit - StrataSwitch Unit #.
  63581  *      port - StrataSwitch port #.
  63582  *      tx   - tx properties
  63583  * Returns:
  63584  *      BCM_E_NONE
  63585  *      BCM_E_XXX
  63586  */
  63587 int
  63588 bcm_esw_port_phy_tx_get(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) {
  63589     int rv = BCM_E_UNAVAIL;
  63590 
  63591     if (NULL == tx) {
  63592         return BCM_E_PARAM;
  63593     }
  63594 
  63595     /* Make sure port module is initialized. */
  63596     PORT_INIT(unit);
  63597 
  63598     if (SOC_IS_TOMAHAWK3(unit)) {
  63599         /* Call Port Control module */
  63600         if (SOC_PORT_USE_PORTCTRL(unit, port)) {
  63601             rv = bcmi_esw_portctrl_phy_tx_get(unit, port, tx);
  63602         }
  63603     }
  63604 
  63605     return rv;
  63606 }
  63607 
  63608 /*
  63609  * Function:
  63610  *      bcm_esw_port_rlm_config_set
  63611  * Purpose:
  63612  *      Set port rlm config properties
  63613  * Parameters:
  63614  *      unit       - (IN) StrataSwitch Unit #.
  63615  *      port       - (IN) StrataSwitch port #.
  63616  *      rlm_config - (IN) rlm properties
  63617  *      enable     - (IN) enable or disable rlm
  63618  * Returns:
  63619  *      BCM_E_NONE
  63620  *      BCM_E_XXX
  63621  */
  63622 int
  63623 bcm_esw_port_rlm_config_set(int unit, bcm_port_t port,
  63624                             bcm_port_rlm_config_t *rlm_config, int enable) {
  63625     int rv = BCM_E_UNAVAIL;
  63626     int port_enabled = 0;
  63627     int link;
  63628 
  63629     if (NULL == rlm_config) {
  63630         return BCM_E_PARAM;
  63631     }
  63632 
  63633     /* Make sure port module is initialized. */
  63634     PORT_INIT(unit);
  63635 
  63636     /* Check for valid port */
  63637     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  63638 
  63639     if (!enable) {
  63640         /* need to disable the port first if disable RLM */
  63641         rv = bcm_esw_port_enable_set(unit, port, 0);
  63642     } else {
  63643         /*next check if the port is enabled */
  63644         rv = bcm_esw_port_enable_get(unit, port, &port_enabled);
  63645         if (!port_enabled) {
  63646             LOG_ERROR(BSL_LS_BCM_PORT,
  63647                       (BSL_META_U(unit,
  63648                                   "port %d is not enabled \n"), port));
  63649             return BCM_E_CONFIG;
  63650         }
  63651 
  63652         /* check link status */
  63653         SOC_IF_ERROR_RETURN
  63654             (bcm_esw_port_link_status_get(unit, port, &link));
  63655         if (FALSE == link) {
  63656             LOG_ERROR(BSL_LS_BCM_PORT,
  63657                       (BSL_META_U(unit,
  63658                                   "port %d link is not up \n"), port));
  63659             return BCM_E_CONFIG;
  63660         }
  63661     }
  63662 
  63663     if (SOC_IS_TOMAHAWK3(unit)) {
  63664         /* Call Port Control module */
  63665         if (SOC_USE_PORTCTRL(unit)) {
  63666             rv = bcmi_esw_portctrl_rlm_config_set(unit,
  63667                                  port,
  63668                                  rlm_config,
  63669                                  enable);
  63670         }
  63671     }
  63672 
  63673     if (!enable) {
  63674         /* need to re-enable the port after RLM is disabled */
  63675         rv = bcm_esw_port_enable_set(unit, port, 1);
  63676     }
  63677 
  63678     return rv;
  63679 }
  63680 
  63681 /*
  63682  * Function:
  63683  *      bcm_esw_port_rlm_config_get
  63684  * Purpose:
  63685  *      Get port phy tx properties
  63686  * Parameters:
  63687  *      unit       - (IN) StrataSwitch Unit #.
  63688  *      port       - (IN) StrataSwitch port #.
  63689  *      rlm_config - (OUT) rlm config properties
  63690  *      enable     - (OUT) enable/disable
  63691  * Returns:
  63692  *      BCM_E_NONE
  63693  *      BCM_E_XXX
  63694  */
  63695 int
  63696 bcm_esw_port_rlm_config_get(int unit, bcm_port_t port,
  63697                             bcm_port_rlm_config_t *rlm_config, int *enable) {
  63698     int rv = BCM_E_UNAVAIL;
  63699 
  63700     if (NULL == rlm_config) {
  63701         return BCM_E_PARAM;
  63702     }
  63703 
  63704     /* Make sure port module is initialized. */
  63705     PORT_INIT(unit);
  63706 
  63707     /* Check for valid port */
  63708     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  63709 
  63710     if (SOC_IS_TOMAHAWK3(unit)) {
  63711         /* Call Port Control module */
  63712         if (SOC_USE_PORTCTRL(unit)) {
  63713             rv = bcmi_esw_portctrl_rlm_config_get(unit,
  63714                                  port,
  63715                                  rlm_config,
  63716                                  enable);
  63717         }
  63718     }
  63719 
  63720     return rv;
  63721 }
  63722 /*
  63723  * Function:
  63724  *      bcm_esw_port_rlm_status_get
  63725  * Purpose:
  63726  *      Get port rlm status
  63727  * Parameters:
  63728  *      unit       - (IN) StrataSwitch Unit #.
  63729  *      port       - (IN) StrataSwitch port #.
  63730  *      rlm_status - (OUT) rlm config properties
  63731  * Returns:
  63732  *      BCM_E_NONE
  63733  *      BCM_E_XXX
  63734  */
  63735 int
  63736 bcm_esw_port_rlm_status_get(int unit, bcm_port_t port,
  63737                             bcm_port_rlm_status_t *rlm_status) {
  63738     int rv = BCM_E_UNAVAIL;
  63739 
  63740     if (NULL == rlm_status) {
  63741         return BCM_E_PARAM;
  63742     }
  63743 
  63744     /* Make sure port module is initialized. */
  63745     PORT_INIT(unit);
  63746 
  63747     /* Check for valid port */
  63748     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  63749 
  63750     if (SOC_IS_TOMAHAWK3(unit)) {
  63751         /* Call Port Control module */
  63752         if (SOC_USE_PORTCTRL(unit)) {
  63753             rv = bcmi_esw_portctrl_rlm_status_get(unit,
  63754                                  port,
  63755                                  rlm_status);
  63756         }
  63757     }
  63758 
  63759     return rv;
  63760 }
  63761 
  63762 /*
  63763  * bcm_port_txpi_rxcdr_clk_get
  63764  *
  63765  * @brief get both tx/rx clocks in Hz.
  63766  *
  63767  * @param [in]  unit            - unit id
  63768  * @param [in]  port            - logical port
  63769  * @param [out]  txpi_clk        - tx pi clk in Hz
  63770  * @param [out]  rxcdr_clk       - rx cdr clk in Hz
  63771  */
  63772 int bcm_esw_port_txpi_rxcdr_clk_get(int unit, bcm_port_t port,
  63773                                 uint32* txpi_clk, uint32* rxcdr_clk)
  63774 {
  63775     int rv = BCM_E_UNAVAIL;
  63776 #if (defined(BCM_MONTEREY_SUPPORT) & defined(INCLUDE_GDPLL)) ||\
  63777      defined(BCM_FIRELIGHT_SUPPORT) || defined(BCM_FIREBOLT6_SUPPORT)
  63778     if (SOC_IS_MONTEREY(unit) || SOC_IS_FIRELIGHT(unit) || SOC_IS_FIREBOLT6(unit)) {
  63779         if (SOC_USE_PORTCTRL(unit)) {
  63780             rv = portmod_port_txpi_rxcdr_clk_get(unit, port, txpi_clk, rxcdr_clk);
  63781         }
  63782     }
  63783 #endif
  63784     return rv;
  63785 }
  63786 
  63787 /*
  63788  * Function:
  63789  *      bcm_esw_port_post_ber_proj_get
  63790  * Purpose:
  63791  *      Get the BER histogram and post-FEC estimation values
  63792  * Parameters:
  63793  *      unit       - (IN) StrataSwitch Unit #.
  63794  *      port       - (IN) StrataSwitch port #.
  63795  *      ber_proj   - (IN) BER Projection parameters
  63796  *      max_errnct - (IN) size of errcnt_array[]
  63797  *      errcnt_array  - (OUT) errcnt_array[] for storing post-FEC estimation values
  63798  *      actual_errcnt - (OUT) actual number of errcnt in errcnt_array[]
  63799  * Returns:
  63800  *      BCM_E_NONE
  63801  *      BCM_E_XXX
  63802  */
  63803 int
  63804 bcm_esw_port_post_ber_proj_get(int unit, bcm_port_t port,
  63805                                bcm_port_ber_proj_params_t *ber_proj,
  63806                                int max_errcnt,
  63807                                bcm_port_ber_proj_analyzer_errcnt_t *errcnt_array,
  63808                                int *actual_errcnt) {
  63809     int rv = BCM_E_UNAVAIL;
  63810 
  63811     if ((ber_proj == NULL) || (errcnt_array == NULL)) {
  63812         return BCM_E_PARAM;
  63813     }
  63814 
  63815     /* Make sure port module is initialized. */
  63816     PORT_INIT(unit);
  63817 
  63818     if (SOC_IS_TOMAHAWK3(unit)) {
  63819         /* Call Port Control module */
  63820         if (SOC_USE_PORTCTRL(unit)) {
  63821             rv = bcmi_esw_portctrl_post_ber_proj_get(unit, port,
  63822                 ber_proj, max_errcnt, errcnt_array, actual_errcnt);
  63823         }
  63824     }
  63825 
  63826     return rv;
  63827 }
  63828 
  63829 int
  63830 bcm_esw_port_get(int unit, bcm_port_t port, uint32 *flags,
  63831                  bcm_port_interface_info_t *interface_info,
  63832                  bcm_port_mapping_info_t *mapping_info)
  63833 {
  63834 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  63835     int mcq, ucq;
  63836     pbmp_t pbmp = PBMP_ALL(unit);
  63837 
  63838     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWK(unit)) {
  63839         if (!_SHR_PBMP_MEMBER((pbmp), (port))) {
  63840             return BCM_E_PARAM;
  63841         }
  63842         if (interface_info == NULL || mapping_info == NULL) {
  63843             return BCM_E_PARAM;
  63844         }
  63845         sal_memset(interface_info, 0, sizeof(bcm_port_interface_info_t));
  63846         sal_memset(mapping_info, 0, sizeof(bcm_port_mapping_info_t));
  63847 
  63848         /* phy_pbmp, interface_id, channel, core, base_q_pair, num_priorities,
  63849          * pp_port, base_hr and num_sch_priorities, are used for Dune switch.
  63850          */
  63851         interface_info->phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  63852         BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port,
  63853                                                        &interface_info->interface));
  63854         interface_info->num_lanes = SOC_INFO(unit).port_num_lanes[port];
  63855         mapping_info->tm_port = SOC_INFO(unit).port_p2m_mapping[interface_info->phy_port];
  63856         interface_info->max_speed = SOC_INFO(unit).port_speed_max[port];
  63857         mcq = SOC_INFO(unit).port_cosq_base[port];
  63858         ucq = SOC_INFO(unit).port_uc_cosq_base[port];
  63859 #ifdef BCM_TRIDENT2_SUPPORT
  63860         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) {
  63861             mapping_info->base_mc_queue = soc_td2_logical_qnum_hw_qnum(unit, port, mcq, 0);
  63862             mapping_info->base_uc_queue = soc_td2_logical_qnum_hw_qnum(unit, port, ucq, 1);
  63863         } else
  63864 #endif
  63865         if (SOC_IS_TOMAHAWK(unit)) {
  63866             mapping_info->base_mc_queue = mcq;
  63867             mapping_info->base_uc_queue = ucq;
  63868         }
  63869         mapping_info->num_mc_queue = SOC_INFO(unit).port_num_cosq[port];
  63870         mapping_info->num_uc_queue = SOC_INFO(unit).port_num_uc_cosq[port];
  63871 
  63872         return BCM_E_NONE;
  63873     }
  63874     return BCM_E_UNAVAIL;
  63875 #else
  63876     return BCM_E_UNAVAIL;
  63877 #endif
  63878 }