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

pm4x25.c (382240B)


      1 /*
      2  *
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <soc/types.h>
     11 #include <soc/error.h>
     12 #include <soc/drv.h>
     13 #include <soc/wb_engine.h>
     14 #include <soc/portmod/portmod_internal.h>
     15 #include <soc/portmod/portmod.h>
     16 #include <soc/portmod/portmod_dispatch.h>
     17 #include <soc/portmod/portmod_chain.h>
     18 #include <soc/portmod/portmod_common.h>
     19 #include <soc/mcm/memregs.h>
     20 #include <soc/portmod/portmod_legacy_phy.h>
     21 #include <soc/portmod/portmod_system.h>
     22 
     23 #ifdef _ERR_MSG_MODULE_NAME 
     24 #error "_ERR_MSG_MODULE_NAME redefined" 
     25 #endif
     26 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     27 
     28 #ifdef PORTMOD_PM4X25_SUPPORT
     29 
     30 #include <soc/portmod/clmac.h>
     31 #include <soc/portmod/pm4x25.h>
     32 #include <soc/portmod/pm4x25_shared.h>
     33 
     34 #ifdef PORTMOD_PM4X25TD_SUPPORT
     35 #include <soc/portmod/pm4x25td_int.h>
     36 #endif /* PORTMOD_PM4X25TD_SUPPORT */
     37 
     38 
     39 #define PM_4x25_INFO(pm_info) ((pm_info)->pm_data.pm4x25_db)
     40 
     41 /* WB defines */
     42 
     43 #define PM4x25_WB_BUFFER_VERSION        (13)
     44 
     45 #define PM4x25_IS_ACTIVE_SET(unit, pm_info, is_active) \
     46     SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &is_active)
     47 #define PM4x25_IS_ACTIVE_GET(unit, pm_info, is_active) \
     48     SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], is_active)
     49 
     50 #define PM4x25_IS_INITIALIZED_SET(unit, pm_info, is_initialized) \
     51     SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInitialized], &is_initialized)
     52 #define PM4x25_IS_INITIALIZED_GET(unit, pm_info, is_initialized) \
     53     SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInitialized], is_initialized)
     54 
     55 #define PM4x25_IS_BYPASSED_SET(unit, pm_info, is_bypass) \
     56     SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &is_bypass)
     57 #define PM4x25_IS_BYPASSED_GET(unit, pm_info, is_bypass) \
     58     SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], is_bypass)
     59 
     60 #define PM4x25_LANE2PORT_SET(unit, pm_info, lane, port) \
     61     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[lane2portMap], &port, lane)
     62 #define PM4x25_LANE2PORT_GET(unit, pm_info, lane, port) \
     63     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[lane2portMap], port, lane)
     64 
     65 #define PM4x25_THREE_PORTS_MODE_SET(unit, pm_info, three_ports_mode) \
     66     SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[threePortsMode], &three_ports_mode)
     67 #define PM4x25_THREE_PORTS_MODE_GET(unit, pm_info, three_ports_mode) \
     68     SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[threePortsMode], three_ports_mode)
     69 
     70 #define PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index) \
     71     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[maxSpeed], &max_speed, port_index)
     72 #define PM4x25_MAX_SPEED_GET(unit, pm_info, max_speed, port_index) \
     73     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[maxSpeed], max_speed, port_index)
     74 
     75 #define PM4x25_INTERFACE_TYPE_SET(unit, pm_info, interface_type, port_index) \
     76     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceType], &interface_type, port_index)
     77 #define PM4x25_INTERFACE_TYPE_GET(unit, pm_info, interface_type, port_index) \
     78     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceType], interface_type, port_index)
     79 
     80 #define PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface_type, port_index) \
     81     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                                   \
     82                           pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy],          \
     83                           &interface_type, port_index)
     84 #define PM4x25_OUTMOST_PHY_INTERFACE_TYPE_GET(unit, pm_info, interface_type, port_index) \
     85     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                                   \
     86                           pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy],          \
     87                           interface_type, port_index)
     88 
     89 #define PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index) \
     90     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceModes], &interface_modes, port_index)
     91 #define PM4x25_INTERFACE_MODES_GET(unit, pm_info, interface_modes, port_index) \
     92     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceModes], interface_modes, port_index)
     93 
     94 #define PM4x25_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, port_index) \
     95     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInterfaceRestore], &is_interface_restore, port_index)
     96 #define PM4x25_IS_INTERFACE_RESTORE_GET(unit, pm_info, is_interface_restore, port_index) \
     97     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInterfaceRestore], is_interface_restore, port_index)
     98 
     99 #define PM4x25_IS_HG_SET(unit, pm_info, is_hg, port_index) \
    100     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isHg], &is_hg, port_index)
    101 #define PM4x25_IS_HG_GET(unit, pm_info, is_hg, port_index) \
    102     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isHg], is_hg, port_index)
    103 
    104 #define PM4x25_AN_MODE_SET(unit, pm_info, an_mode, port_index) \
    105     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMode], &an_mode, port_index)
    106 #define PM4x25_AN_MODE_GET(unit, pm_info, an_mode, port_index) \
    107     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMode], an_mode, port_index)
    108 
    109 #define PM4x25_FS_CL72_SET(unit, pm_info, fs_cl72, port_index) \
    110     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[fsCl72], &fs_cl72, port_index)
    111 #define PM4x25_FS_CL72_GET(unit, pm_info, fs_cl72, port_index) \
    112     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[fsCl72], fs_cl72, port_index)
    113 
    114 #define PM4x25_CX4_10G_SET(unit, pm_info, cx4_10G, port_index) \
    115     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[cx4In10G], &cx4_10G, port_index)
    116 #define PM4x25_CX4_10G_GET(unit, pm_info, cx4_10G, port_index) \
    117     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[cx4In10G], cx4_10G, port_index)
    118 
    119 #define PM4x25_AN_CL72_SET(unit, pm_info, an_cl72, port_index) \
    120     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anCl72], &an_cl72, port_index)
    121 #define PM4x25_AN_CL72_GET(unit, pm_info, an_cl72, port_index) \
    122     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anCl72], an_cl72, port_index)
    123 
    124 #define PM4x25_AN_FEC_SET(unit, pm_info, an_fec, port_index) \
    125     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anFec], &an_fec, port_index)
    126 #define PM4x25_AN_FEC_GET(unit, pm_info, an_fec, port_index) \
    127     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anFec], an_fec, port_index)
    128 
    129 #define PM4x25_AN_MASTER_LANE_SET(unit, pm_info, an_master_lane, port_index) \
    130     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMasterLane], &an_master_lane, port_index)
    131 #define PM4x25_AN_MASTER_LANE_GET(unit, pm_info, an_master_lane, port_index) \
    132     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMasterLane], an_master_lane, port_index)
    133 
    134 #define PM4x25_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, lane_connection_db, xphy_idx, lane) \
    135     SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[laneConnectionDb], \
    136         (uint8 *)lane_connection_db, lane, xphy_idx)
    137 #define PM4x25_PORT_LANE_CONNECTION_DB_GET(unit, pm_info, lane_connection_db, xphy_idx, lane) \
    138     SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[laneConnectionDb], \
    139         (uint8 *)lane_connection_db, lane, xphy_idx)
    140 
    141 #define PM4x25_PORT_NUM_PHYS_SET(unit, pm_info, nof_phys, lane)   \
    142         SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[nofPhys], &nof_phys, lane)
    143 #define PM4x25_PORT_NUM_PHYS_GET(unit, pm_info, nof_phys, lane)   \
    144         SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[nofPhys], nof_phys, lane)
    145 
    146 #define PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info, dynamic_state, \
    147                                       port_index)                   \
    148     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    149                           pm_info->wb_vars_ids[portDynamicState],   \
    150                           &dynamic_state, port_index)
    151 #define PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info, dynamic_state, \
    152                                       port_index)                   \
    153     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    154                           pm_info->wb_vars_ids[portDynamicState],   \
    155                           dynamic_state, port_index)
    156 #define PM4x25_PORT_TIME_STAMP_ADJUST_OLD_SET(unit, pm_info,                    \
    157                                               port_ts_adjust,                 \
    158                                               adjust_index,                    \
    159                                               port_index)                     \
    160           SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    161                                     pm_info->wb_vars_ids[tsAdjustOld],           \
    162                                     (uint8 *)port_ts_adjust, adjust_index, port_index)
    163 
    164 #define PM4x25_PORT_TIME_STAMP_ADJUST_OLD_GET(unit, pm_info,                    \
    165                                               port_ts_adjust,                 \
    166                                               adjust_index,                    \
    167                                               port_index)                     \
    168         SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    169                                   pm_info->wb_vars_ids[tsAdjustOld],           \
    170                                   (uint8 *)port_ts_adjust, adjust_index, port_index)
    171 
    172 #define PM4x25_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info,                    \
    173                                             port_ts_adjust,                 \
    174                                             adjust_index,                    \
    175                                             port_index)                     \
    176         SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    177                                   pm_info->wb_vars_ids[tsAdjust],           \
    178                                   (uint8 *)port_ts_adjust, adjust_index, port_index)
    179 
    180 #define PM4x25_PORT_TIME_STAMP_ADJUST_GET(unit, pm_info,                    \
    181                                             port_ts_adjust,                 \
    182                                             adjust_index,                    \
    183                                             port_index)                     \
    184         SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
    185                                   pm_info->wb_vars_ids[tsAdjust],           \
    186                                   (uint8 *)port_ts_adjust, adjust_index, port_index)
    187 
    188 #define PM4x25_PORT_PLL_DIVIDER_REQ_SET(unit, pm_info,                \
    189                                         pll_divider_req,              \
    190                                         port_index)                   \
    191     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    192                           pm_info->wb_vars_ids[pllDividerReq],        \
    193                           &pll_divider_req, port_index)
    194 #define PM4x25_PORT_PLL_DIVIDER_REQ_GET(unit, pm_info,                \
    195                                         pll_divider_req,              \
    196                                         port_index)                   \
    197     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    198                           pm_info->wb_vars_ids[pllDividerReq],        \
    199                           pll_divider_req, port_index)
    200 
    201 #define PM4x25_PORT_1000X_AT_25G_SET(unit, pm_info,                   \
    202                                         serdes_1000x_at_25g_vco,      \
    203                                         port_index)                   \
    204     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    205                           pm_info->wb_vars_ids[serdes1000xAt25gVco],  \
    206                           &serdes_1000x_at_25g_vco, port_index)
    207 #define PM4x25_PORT_1000X_AT_25G_GET(unit, pm_info,                   \
    208                                         serdes_1000x_at_25g_vco,      \
    209                                         port_index)                   \
    210     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    211                           pm_info->wb_vars_ids[serdes1000xAt25gVco],  \
    212                           serdes_1000x_at_25g_vco, port_index)
    213 
    214 #define PM4x25_PORT_10G_AT_25G_SET(unit, pm_info,                     \
    215                                         serdes_10g_at_25g_vco,        \
    216                                         port_index)                   \
    217     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    218                           pm_info->wb_vars_ids[serdes10gAt25gVco],    \
    219                           &serdes_10g_at_25g_vco, port_index)
    220 #define PM4x25_PORT_10G_AT_25G_GET(unit, pm_info,                     \
    221                                         serdes_10g_at_25g_vco,        \
    222                                         port_index)                   \
    223     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    224                           pm_info->wb_vars_ids[serdes10gAt25gVco],    \
    225                           serdes_10g_at_25g_vco, port_index)
    226 #define PM4x25_CPRI_PORT_VSD_ACTIVE_GROUP_SET(unit, pm_info, group_list, port_index) \
    227     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[cpriVsdActiveGrp], group_list, port_index)
    228 #define PM4x25_CPRI_PORT_VSD_ACTIVE_GROUP_GET(unit, pm_info, group_list, port_index) \
    229     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[cpriVsdActiveGrp], group_list, port_index)
    230 
    231 #define PM4x25_PORT_LINK_RECOVERY_SET(unit, pm_info,                  \
    232                                         link_recovery,                \
    233                                         port_index)                   \
    234     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    235                           pm_info->wb_vars_ids[linkRecovery],         \
    236                           &link_recovery, port_index)
    237 #define PM4x25_PORT_LINK_RECOVERY_GET(unit, pm_info,                  \
    238                                         link_recovery,                \
    239                                         port_index)                   \
    240     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    241                           pm_info->wb_vars_ids[linkRecovery],         \
    242                           link_recovery, port_index)
    243 
    244 
    245 
    246 typedef enum pm4x25_fabric_wb_vars{
    247     isActive = 0, /* specify the PM4x25 core is active (at least one port has been attached) */
    248     isBypassed, /*specify the PM is in Bypass mode - the MAC is not in use, some configurations do not apply*/
    249     isInitialized, /* specify initialization of all SerDes have been done */
    250     lane2portMap, /* map each lane in the PM to a logical port */
    251     threePortsMode,
    252     phy_type, /* Phy type in PHYMOD dispatch phymod_dispatch_type_t */
    253     interfaceConfig, /* portmod_port_interface_config_t **removed** */
    254     portInitConfig, /* portmod_port_init_config_t **removed** */
    255     nofPhys,/* keep track of nun of phys (including internal Serdes. */
    256     maxSpeed, /* Max Port Speed Supported */
    257     interfaceType, /* interface of type soc_port_if_t */
    258     interfaceModes, /* see PHYMOD_INTF_MODES_ */
    259     isInterfaceRestore, /* interface should be restored from DB (otherwise retrieved from HW), replace PHYMOD_INTF_F_INTF_PARAM_SET_ONLY */    
    260     isHg, /* specify wheather the port is higig port */
    261     anMode, /* spn_PHY_AN_MODE - Specify the AN mode */
    262     fsCl72, /* spn_FORCED_INIT_CL72 - if trainig should be enabled in Forced speed mode */
    263     cx4In10G, /* see PHYMOD_BAM_CL37_CAP_10G_CX4 */
    264     anCl72, /* spn_PHY_AN_C72 - Specify if the link training should be enabled */
    265     anFec, /* spn_FORCED_INIT_FEC specify if FEC should be enabled in AN mode */
    266     anMasterLane, /* spn_PHY_AUTONEG_MASTER_LANE - Specify the AN master lane */
    267     laneConnectionDb, /* represents the physical topology of the  serdes and ext phy lanes */
    268     interfaceWrittenIntoOutmostPhy, /* the interface type written into the outmost PHY */
    269     portDynamicState,
    270     tsAdjustOld, /* the time stamp adjust setting on MAC ** removed ** */
    271     pllDividerReq, /*pll_divider_req setting on the port */
    272     serdes1000xAt25gVco, /*1G working at 25g*/
    273     serdes10gAt25gVco, /*10G Base-R working at 25g*/
    274     cpriVsdActiveGrp,   /* CPRI TX VSD active group */
    275     tsAdjust, /* the time stamp adjust setting on MAC */
    276     linkRecovery /* Used by the link recovery WAR */
    277 }pm4x25_wb_vars_t;
    278 
    279 #define PM4x25_QUAD_MODE_IF(interface) \
    280     (interface == SOC_PORT_IF_CAUI || interface == SOC_PORT_IF_XLAUI)
    281 
    282 #define PM4x25_DUAL_MODE_IF(interface) \
    283     (interface == SOC_PORT_IF_XLAUI2)
    284 
    285 #define PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc) \
    286     do { \
    287         uint32 is_bypass; \
    288         phy_acc = 0; \
    289         PM4x25_IS_BYPASSED_GET(unit, pm_info, &is_bypass); \
    290         phy_acc = (is_bypass && PM_4x25_INFO(pm_info)->first_phy != -1) ? (PM_4x25_INFO(pm_info)->first_phy | SOC_REG_ADDR_PHY_ACC_MASK) : port ; \
    291     } while (0)
    292 
    293 #define PORTMOD_PM4x25_IS_GEN1(pm_version)             ((pm_version.type == PM_TYPE_PM4X25) && (pm_version.gen == PM_GEN1))
    294 #define PORTMOD_PM4x25_IS_GEN1_GEN2(pm_version)        ((pm_version.type == PM_TYPE_PM4X25) && ((pm_version.gen == PM_GEN1) || (pm_version.gen == PM_GEN2)))
    295 #define PORTMOD_PM4x25_IS_GEN2_16nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X25) && (pm_version.gen == PM_GEN2) && (pm_version.tech_process == PM_TECH_16NM))
    296 #define PORTMOD_PM4x25_IS_GEN2_28nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X25) && (pm_version.gen == PM_GEN2) && (pm_version.tech_process == PM_TECH_28NM))
    297 #define PORTMOD_PM4x25_IS_GEN3_16nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X25) && (pm_version.gen == PM_GEN3) && (pm_version.tech_process == PM_TECH_16NM))
    298 #define PORTMOD_PM4x25_IS_GEN3_28nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X25) && (pm_version.gen == PM_GEN3) && (pm_version.tech_process == PM_TECH_28NM))
    299 #define PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)       ((pm_version.type == PM_TYPE_CPM4X25) && (pm_version.gen == PM_GEN3) && (pm_version.tech_process == PM_TECH_28NM))
    300 #define PORTMOD_PM4x25_REVISION_IS_A0(pm_version)      ((pm_version.revision_letter == PM_REVISION_A) && (pm_version.revision_number == PM_REVISION_0))
    301 /* Add other revision check here */
    302 
    303 #define TXPI_DSM_VALUE_1PPM_HI (uint32) 0x29   /* 1ppm value is 1.80144E+11 (0x29F16B11C7) in register */
    304 #define TXPI_DSM_VALUE_1PPM_LO (uint32) 0xF16B11C7
    305 #define PFC_FRAME_DETECTED_RSV_MASK     0x40000
    306 
    307 #define DEFAULT_OSR2P5_SET 1
    308 
    309 STATIC
    310 int pm4x25_port_soft_reset(int unit, int port, pm_info_t pm_info, int enable);
    311 
    312 STATIC int
    313 _pm4x25_pm_ext_tsc_clk_set(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info);
    314 
    315 STATIC int
    316 _pm4x25_init_plls_get(int unit, int port, pm_info_t pm_info, portmod_vcos_speed_config_t *speed_config, int size,  phymod_dual_plls_t *init_plls);
    317 
    318 STATIC int
    319 _pm4x25_port_tsc_is_master_pll(int unit, int port, pm_info_t pm_info);
    320 
    321 
    322 STATIC
    323 int _pm4x25_pm_version_get(int unit, pm_info_t pm_info, pm_version_t *version)
    324 {
    325     uint32 raddr, reg_val, pm_type;
    326     int phy_port, block;
    327     uint8 access_type;
    328 
    329     SOC_INIT_FUNC_DEFS;
    330 
    331     version->type            = PM_TYPE_INVALID;
    332     version->gen             = PM_GEN_INVALID;
    333     version->tech_process    = PM_TECH_INVALID;
    334     version->revision_number = PM_REVISION_NUM_INVALID;
    335     version->revision_letter = PM_REVISION_LETTER_INVALID;
    336 
    337     /*
    338      * PM version ID register is not defined in PM GEN1.
    339      * PM12x10 only has gen1 now. To be fixed if support PM12X10 gen2.
    340      */
    341     if (SOC_REG_IS_VALID(unit, CLPORT_PM_VERSION_IDr) &&
    342         (!PM_4x25_INFO(pm_info)->in_pm12x10)) {
    343 
    344         /* Get the first physical port of the pm core */
    345         PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy_port) {
    346             break;
    347         }
    348 
    349         raddr = soc_reg_addr_get(unit, CLPORT_PM_VERSION_IDr, phy_port, 0,
    350                              SOC_REG_ADDR_OPTION_PRESERVE_PORT, &block, &access_type);
    351         _SOC_IF_ERR_EXIT(_soc_reg32_get(unit, block, access_type, raddr, &reg_val));
    352 
    353         pm_type  = soc_reg_field_get(unit, CLPORT_PM_VERSION_IDr, reg_val, PM_TYPEf);
    354         if (pm_type == 1) {
    355             version->type = PM_TYPE_PM4X25;
    356             version->gen  = PM_GEN2;
    357         }
    358         else if (pm_type == 6) {
    359             version->type = PM_TYPE_PM4X25;
    360             version->gen  = PM_GEN3;
    361         }
    362         else if (pm_type == 7) {
    363             version->type = PM_TYPE_CPM4X25;
    364             version->gen  = PM_GEN3;
    365         }
    366         /* The hardware value of techology/revision starts from 0 */
    367         version->tech_process    = soc_reg_field_get(unit, CLPORT_PM_VERSION_IDr, reg_val, TECH_PROCESSf) + 1;
    368         version->revision_number = soc_reg_field_get(unit, CLPORT_PM_VERSION_IDr, reg_val, REV_NUMBERf) + 1;
    369         version->revision_letter = soc_reg_field_get(unit, CLPORT_PM_VERSION_IDr, reg_val, REV_LETTERf) + 1;
    370     } else {
    371         version->type = PM_TYPE_PM4X25;
    372         version->gen  = PM_GEN1;
    373     }
    374 
    375 exit:
    376     SOC_FUNC_RETURN;
    377 }
    378 
    379 
    380 int pm4x25_pm_interface_type_is_supported(int unit, soc_port_if_t interface,
    381                                           int* is_supported)
    382 {
    383     SOC_INIT_FUNC_DEFS;
    384 
    385     switch(interface){
    386         case SOC_PORT_IF_CAUI:
    387         case SOC_PORT_IF_XLAUI2:
    388         case SOC_PORT_IF_XLAUI:
    389         case SOC_PORT_IF_XFI:
    390         case SOC_PORT_IF_SFI:
    391         case SOC_PORT_IF_RXAUI:
    392         case SOC_PORT_IF_DNX_XAUI:
    393         case SOC_PORT_IF_SR:
    394         case SOC_PORT_IF_SR2:
    395         case SOC_PORT_IF_SR4:
    396         case SOC_PORT_IF_KR:
    397         case SOC_PORT_IF_KR2:
    398         case SOC_PORT_IF_KR4:
    399         case SOC_PORT_IF_CR:
    400         case SOC_PORT_IF_CR2:
    401         case SOC_PORT_IF_CR4:
    402         case SOC_PORT_IF_SGMII:
    403         case SOC_PORT_IF_GMII:
    404         case SOC_PORT_IF_CAUI4:
    405             *is_supported = TRUE;
    406             break;
    407         default:
    408             *is_supported = FALSE;
    409             break;
    410     }
    411     SOC_FUNC_RETURN;
    412 }
    413 
    414 STATIC
    415 int _pm4x25_port_index_get(int unit, int port, pm_info_t pm_info,
    416                            int *first_index, uint32 *bitmap)
    417 {
    418    int i, rv = 0, tmp_port = 0;
    419 
    420    SOC_INIT_FUNC_DEFS;
    421 
    422    *first_index = -1;
    423    *bitmap = 0;
    424 
    425    for( i = 0 ; i < MAX_PORTS_PER_PM4X25; i++){
    426        rv = PM4x25_LANE2PORT_GET(unit, pm_info, i, &tmp_port);
    427        _SOC_IF_ERR_EXIT(rv);
    428 
    429        if(tmp_port == port){
    430            *first_index = (*first_index == -1 ? i : *first_index);
    431            SHR_BITSET(bitmap, i);
    432        }
    433    }
    434 
    435    if(*first_index == -1) {
    436        _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
    437               (_SOC_MSG("port was not found in internal DB %d"), port));
    438    }
    439 
    440 exit:
    441     SOC_FUNC_RETURN;
    442 }
    443 
    444 /*
    445  * Function:
    446  *      portmod_pm4x25_wb_upgrade_func
    447  * Purpose:
    448  *      This function will take care of the warmboot variable manipulation
    449  *      in case of upgrade case, when variable definition got change or
    450  *      unspoorted varaible from previous version.
    451  * Parameters:
    452  *      unit                -(IN) Device unit number .
    453  *      arg                 -(IN) Generic pointer for a specific module to be used.
    454  *      recovered_version   -(IN) Warmboot version of the existing data.
    455  *      new_version         -(IN) Warmboot version of new data.
    456  * Returns:
    457  *      Status
    458  */
    459 
    460 int portmod_pm4x25_wb_upgrade_func(int unit, void *arg, int recovered_version, int new_version)
    461 {
    462     pm_info_t pm_info;
    463     int i, adjust_index;
    464     int nof_phys, dynamic_state, pll_divider_req, serdes_1000x_at_25g_vco, serdes_10g_at_25g_vco;
    465     portmod_port_ts_adjust_t port_ts_adjust;
    466     soc_port_if_t interface;
    467     uint32 vsd_active_group[4]={0};
    468     portmod_link_recovery_t link_recovery;
    469     SOC_INIT_FUNC_DEFS;
    470     
    471     pm_info = arg;
    472 
    473     /*
    474      * skip the warmboot db restore, it is only needed for
    475      * upgrades for version below 7.
    476      */
    477 
    478     if (recovered_version <= 6) {
    479         PM_4x25_INFO(pm_info)->warmboot_skip_db_restore = FALSE;
    480     } else {
    481         PM_4x25_INFO(pm_info)->warmboot_skip_db_restore = TRUE;
    482     }
    483 
    484     if ((recovered_version <= 5) &&
    485         (new_version >= 6)) {
    486 
    487         /*
    488          * in version 4 or earlier, nof_phys was not populated properly.
    489          * It need to initialize to 1  to count for internal phy. 1 may not
    490          * be proper value as some port may have ext phy.
    491          */
    492         if(!PM_4x25_INFO(pm_info)->in_pm12x10){
    493         nof_phys = 1;
    494         } else {
    495             nof_phys = 0;
    496         }
    497         for(i = 0 ; i < PM4X25_LANES_PER_CORE ; i++){
    498             _SOC_IF_ERR_EXIT(PM4x25_PORT_NUM_PHYS_SET(unit, pm_info, nof_phys, i));
    499             PM_4x25_INFO(pm_info)->nof_phys[i] = nof_phys;
    500         }
    501     }
    502 
    503     if ((recovered_version <= 6) &&
    504         (new_version >= 7)) {
    505         /* interface_written_into_outmost_phy does not exist in version 6 or earlier */
    506         interface = SOC_PORT_IF_COUNT;
    507         for (i = 0 ; i < MAX_PORTS_PER_PM4X25 ; i++) {
    508             _SOC_IF_ERR_EXIT(
    509                 PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, i));
    510         }
    511     }
    512 
    513     if ((recovered_version <= 7) &&
    514         (new_version >= 8)) {
    515         dynamic_state = 0;
    516         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    517             _SOC_IF_ERR_EXIT(
    518                 PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info, dynamic_state, i));
    519         }
    520     }
    521 
    522     if ((recovered_version <= 8) &&
    523         (new_version >= 9)) {
    524         sal_memset(&port_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
    525         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    526              for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM_OLD; adjust_index++) {
    527                   _SOC_IF_ERR_EXIT(
    528                       PM4x25_PORT_TIME_STAMP_ADJUST_OLD_SET(unit, pm_info, &port_ts_adjust,
    529                                                             adjust_index, i));
    530              }
    531         }
    532     }
    533 
    534     if ((recovered_version <= 9) &&
    535         (new_version >= 10)) {
    536         pll_divider_req = 0;
    537         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    538             _SOC_IF_ERR_EXIT(
    539                 PM4x25_PORT_PLL_DIVIDER_REQ_SET(unit, pm_info, pll_divider_req, i));
    540         }
    541     }
    542 
    543     if ((recovered_version <= 10) &&
    544         (new_version >= 11)) {
    545         serdes_1000x_at_25g_vco = 0;
    546         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    547             _SOC_IF_ERR_EXIT(
    548                 PM4x25_PORT_1000X_AT_25G_SET(unit, pm_info, serdes_1000x_at_25g_vco, i));
    549         }
    550 
    551         serdes_10g_at_25g_vco = 0;
    552         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    553             _SOC_IF_ERR_EXIT(
    554                 PM4x25_PORT_10G_AT_25G_SET(unit, pm_info, serdes_10g_at_25g_vco, i));
    555         }
    556     }
    557     if ((recovered_version <= 11) &&
    558         (new_version >= 12)) {
    559         sal_memset(vsd_active_group, 0, sizeof(uint32_t)*NUM_VSD_ACTIVE_GROUP_WORD);
    560         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    561             _SOC_IF_ERR_EXIT(
    562                 PM4x25_CPRI_PORT_VSD_ACTIVE_GROUP_SET(unit, pm_info, vsd_active_group, i));
    563         }
    564     }
    565 
    566     if ((recovered_version <= 11) &&
    567         (new_version >= 12)) {
    568         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    569             /* Copy existing timestamp adjust configs from old WB variable. */
    570             for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM_OLD; adjust_index++) {
    571                 _SOC_IF_ERR_EXIT(
    572                     PM4x25_PORT_TIME_STAMP_ADJUST_OLD_GET(unit, pm_info, &port_ts_adjust,
    573                                                           adjust_index, i));
    574                 _SOC_IF_ERR_EXIT(
    575                     PM4x25_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info, &port_ts_adjust,
    576                                                       adjust_index, i));
    577             }
    578             /* Initialize new timestamp adjust configs as 0. */
    579             while (adjust_index < PORTMOD_TS_ADJUST_NUM) {
    580                 sal_memset(&port_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
    581                 _SOC_IF_ERR_EXIT(
    582                     PM4x25_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info, &port_ts_adjust,
    583                                                       adjust_index, i));
    584                 adjust_index++;
    585             }
    586         }
    587     }
    588 
    589     if ((recovered_version <= 12) &&
    590         (new_version >= 13)) {
    591         link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK;
    592         link_recovery.enabled = TRUE;
    593         link_recovery.tick_cnt = 0;
    594         for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
    595             _SOC_IF_ERR_EXIT(
    596                 PM4x25_PORT_LINK_RECOVERY_SET(unit, pm_info, link_recovery, i));
    597         }
    598     }
    599 
    600 
    601 exit:
    602     SOC_FUNC_RETURN;
    603 }
    604 
    605 /*
    606  * Initialize the buffer to support warmboot
    607  * The state of warmboot is store in the variables like
    608  * isInitialized, isActive, isBypassed, ports.. etc.,
    609  * All of these variables need to be added to warmboot
    610  * any variables added to save the state of warmboot should be 
    611  * included here.  
    612  */
    613 STATIC
    614 int pm4x25_wb_buffer_init(int unit, int wb_buffer_index, pm_info_t pm_info)
    615 {
    616     /* Declare the common variables needed for warmboot */
    617     WB_ENGINE_INIT_TABLES_DEFS;
    618     int wb_var_id, rv;
    619     int buffer_id = wb_buffer_index; /*required by SOC_WB_ENGINE_ADD_ Macros*/
    620     SOC_INIT_FUNC_DEFS;
    621 
    622     COMPILER_REFERENCE(buffer_is_dynamic);
    623 
    624     SOC_WB_ENGINE_ADD_BUFF(SOC_WB_ENGINE_PORTMOD, wb_buffer_index, "pm4x25", portmod_pm4x25_wb_upgrade_func, pm_info, PM4x25_WB_BUFFER_VERSION, 1, SOC_WB_ENGINE_PRE_RELEASE);
    625     _SOC_IF_ERR_EXIT(rv);
    626 
    627     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    628     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "lane2portMap", wb_buffer_index, sizeof(int), NULL, MAX_PORTS_PER_PM4X25, VERSION(1));
    629     _SOC_IF_ERR_EXIT(rv);
    630     pm_info->wb_vars_ids[lane2portMap] = wb_var_id;
    631 
    632     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    633     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_active", wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    634     _SOC_IF_ERR_EXIT(rv);
    635     pm_info->wb_vars_ids[isActive] = wb_var_id;
    636 
    637     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    638     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_initialized", wb_buffer_index, sizeof(uint32), NULL, VERSION(2));
    639     _SOC_IF_ERR_EXIT(rv);
    640     pm_info->wb_vars_ids[isInitialized] = wb_var_id;
    641 
    642     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    643     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_bypassed", wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    644     _SOC_IF_ERR_EXIT(rv);
    645     pm_info->wb_vars_ids[isBypassed] = wb_var_id;
    646 
    647     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    648     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "three_ports_mode", wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    649     _SOC_IF_ERR_EXIT(rv);
    650     pm_info->wb_vars_ids[threePortsMode] = wb_var_id;
    651 
    652     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    653     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "phy_type", wb_buffer_index, sizeof(int), NULL, MAX_PORTS_PER_PM4X25, VERSION(1));
    654     _SOC_IF_ERR_EXIT(rv);
    655     pm_info->wb_vars_ids[phy_type] = wb_var_id;
    656 
    657     /* Deleting the below WB structures since most likely to be added in the future in a diffrent format */
    658     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    659     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_config", wb_buffer_index, sizeof(portmod_port_interface_config_t), NULL, 1, 1, 0xffffffff, 0xffffffff, VERSION(3), VERSION(4), NULL);
    660     _SOC_IF_ERR_EXIT(rv);
    661     pm_info->wb_vars_ids[interfaceConfig] = wb_var_id;
    662 
    663     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    664     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id, "port_init_config", wb_buffer_index, sizeof(portmod_port_init_config_t), NULL, 1, 1, 0xffffffff, 0xffffffff, VERSION(3), VERSION(4), NULL);
    665     _SOC_IF_ERR_EXIT(rv);
    666     pm_info->wb_vars_ids[portInitConfig] = wb_var_id;
    667 
    668     /* Keeping the below WB arr since most likely to be used in the future */
    669     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    670     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "nof_phys", wb_buffer_index, sizeof(int), NULL, PM4X25_LANES_PER_CORE,  VERSION(3));
    671     _SOC_IF_ERR_EXIT(rv);
    672     pm_info->wb_vars_ids[nofPhys] = wb_var_id;
    673 
    674     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    675     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "max_speed", wb_buffer_index, sizeof(uint32), NULL, MAX_PORTS_PER_PM4X25, VERSION(5));
    676     _SOC_IF_ERR_EXIT(rv);
    677     pm_info->wb_vars_ids[maxSpeed] = wb_var_id;
    678 
    679     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    680     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_type", wb_buffer_index, sizeof(uint32), NULL, MAX_PORTS_PER_PM4X25, VERSION(5));
    681     _SOC_IF_ERR_EXIT(rv);
    682     pm_info->wb_vars_ids[interfaceType] = wb_var_id;
    683 
    684     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    685     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_modes", wb_buffer_index, sizeof(uint32), NULL, MAX_PORTS_PER_PM4X25, VERSION(5));
    686     _SOC_IF_ERR_EXIT(rv);
    687     pm_info->wb_vars_ids[interfaceModes] = wb_var_id;
    688 
    689     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    690     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_interface_restore", wb_buffer_index, sizeof(uint32), NULL, MAX_PORTS_PER_PM4X25, VERSION(5));
    691     _SOC_IF_ERR_EXIT(rv);
    692     pm_info->wb_vars_ids[isInterfaceRestore] = wb_var_id;
    693 
    694     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    695     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_hg", wb_buffer_index, sizeof(uint32), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    696     _SOC_IF_ERR_EXIT(rv);
    697     pm_info->wb_vars_ids[isHg] = wb_var_id;
    698 
    699     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    700     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_mode", wb_buffer_index, sizeof(int), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    701     _SOC_IF_ERR_EXIT(rv);
    702     pm_info->wb_vars_ids[anMode] = wb_var_id;
    703 
    704     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    705     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "fs_cl72", wb_buffer_index, sizeof(uint32), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    706     _SOC_IF_ERR_EXIT(rv);
    707     pm_info->wb_vars_ids[fsCl72] = wb_var_id;
    708 
    709      _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    710     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "cx4_10G", wb_buffer_index, sizeof(uint32), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    711     _SOC_IF_ERR_EXIT(rv);
    712     pm_info->wb_vars_ids[cx4In10G] = wb_var_id;
    713 
    714      _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    715     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_cl72", wb_buffer_index, sizeof(uint32), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    716     _SOC_IF_ERR_EXIT(rv);
    717     pm_info->wb_vars_ids[anCl72] = wb_var_id;
    718 
    719      _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    720     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_fec", wb_buffer_index, sizeof(uint32), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    721     _SOC_IF_ERR_EXIT(rv);
    722     pm_info->wb_vars_ids[anFec] = wb_var_id;
    723 
    724      _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    725     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_master_lane", wb_buffer_index, sizeof(int), NULL, PM4X25_LANES_PER_CORE,  VERSION(5));
    726     _SOC_IF_ERR_EXIT(rv);
    727     pm_info->wb_vars_ids[anMasterLane] = wb_var_id;
    728 
    729     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    730     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "lane_connection_db",
    731                           wb_buffer_index, sizeof(portmod_xphy_lane_connection_t), NULL,
    732                           PM4X25_LANES_PER_CORE, MAX_PHYN, VERSION(6));
    733     _SOC_IF_ERR_EXIT(rv);
    734     pm_info->wb_vars_ids[laneConnectionDb] = wb_var_id;
    735 
    736     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    737     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_written_into_outmost_phy",
    738                           wb_buffer_index, sizeof(uint32), NULL, MAX_PORTS_PER_PM4X25, VERSION(7));
    739     _SOC_IF_ERR_EXIT(rv);
    740     pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy] = wb_var_id;
    741 
    742     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    743     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    744                           "port_dynamic_state", wb_buffer_index,
    745                           sizeof(uint32_t), NULL, MAX_PORTS_PER_PM4X25,
    746                           VERSION(8));
    747     _SOC_IF_ERR_EXIT(rv);
    748     pm_info->wb_vars_ids[portDynamicState] = wb_var_id;
    749 
    750     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    751     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    752                           "time stamp adjust setting on MAC", wb_buffer_index,
    753                           sizeof(portmod_port_ts_adjust_t), NULL,
    754                           PORTMOD_TS_ADJUST_NUM_OLD, MAX_PORTS_PER_PM4X25,
    755                           VERSION(9));
    756     _SOC_IF_ERR_EXIT(rv);
    757     pm_info->wb_vars_ids[tsAdjustOld] = wb_var_id;
    758 
    759     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    760     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    761                           "pll_divider_req", wb_buffer_index,
    762                           sizeof(uint32_t), NULL, MAX_PORTS_PER_PM4X25,
    763                           VERSION(10));
    764     _SOC_IF_ERR_EXIT(rv);
    765     pm_info->wb_vars_ids[pllDividerReq] = wb_var_id;
    766 
    767     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    768     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    769                           "serdes_1000x_at_25g_vco", wb_buffer_index,
    770                           sizeof(uint32_t), NULL, MAX_PORTS_PER_PM4X25,
    771                           VERSION(11));
    772     _SOC_IF_ERR_EXIT(rv);
    773     pm_info->wb_vars_ids[serdes1000xAt25gVco] = wb_var_id;
    774 
    775     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    776     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    777                           "serdes_10g_at_25g_vco", wb_buffer_index,
    778                           sizeof(uint32_t), NULL, MAX_PORTS_PER_PM4X25,
    779                           VERSION(11));
    780     _SOC_IF_ERR_EXIT(rv);
    781     pm_info->wb_vars_ids[serdes10gAt25gVco] = wb_var_id;
    782 
    783     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    784     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    785                           "cpri_tx_vsd_active_grp", wb_buffer_index,
    786                           sizeof(uint32_t)*NUM_VSD_ACTIVE_GROUP_WORD, NULL, MAX_PORTS_PER_PM4X25,
    787                           VERSION(12));
    788     _SOC_IF_ERR_EXIT(rv);
    789     pm_info->wb_vars_ids[cpriVsdActiveGrp] = wb_var_id;
    790 
    791     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    792     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    793                           "new time stamp adjust setting on MAC", wb_buffer_index,
    794                           sizeof(portmod_port_ts_adjust_t), NULL,
    795                           PORTMOD_TS_ADJUST_NUM, MAX_PORTS_PER_PM4X25,
    796                           VERSION(12));
    797     _SOC_IF_ERR_EXIT(rv);
    798     pm_info->wb_vars_ids[tsAdjust] = wb_var_id;
    799 
    800     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    801     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    802                           "link_recovery", wb_buffer_index,
    803                           sizeof(portmod_link_recovery_t), NULL, MAX_PORTS_PER_PM4X25,
    804                           VERSION(13));
    805     _SOC_IF_ERR_EXIT(rv);
    806     pm_info->wb_vars_ids[linkRecovery] = wb_var_id;
    807 
    808     _SOC_IF_ERR_EXIT(soc_wb_engine_init_buffer(unit, SOC_WB_ENGINE_PORTMOD, wb_buffer_index, FALSE));
    809     if(!SOC_WARM_BOOT(unit)){
    810         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[lane2portMap], -1);
    811         _SOC_IF_ERR_EXIT(rv);
    812 
    813         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[maxSpeed], 0);
    814         _SOC_IF_ERR_EXIT(rv);
    815 
    816         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceType], _SHR_PORT_IF_COUNT);
    817         _SOC_IF_ERR_EXIT(rv);
    818 
    819         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceModes], 0);
    820         _SOC_IF_ERR_EXIT(rv);
    821 
    822         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInterfaceRestore], 0);
    823         _SOC_IF_ERR_EXIT(rv);
    824 
    825         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isHg], _SHR_PORT_IF_COUNT);
    826         _SOC_IF_ERR_EXIT(rv);
    827 
    828         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMode], phymod_AN_MODE_Count);
    829         _SOC_IF_ERR_EXIT(rv);
    830 
    831         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[fsCl72], 0);
    832         _SOC_IF_ERR_EXIT(rv);
    833 
    834         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[cx4In10G], 0);
    835         _SOC_IF_ERR_EXIT(rv);
    836 
    837         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anCl72], 0);
    838         _SOC_IF_ERR_EXIT(rv);
    839 
    840         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anFec], 0);
    841         _SOC_IF_ERR_EXIT(rv);
    842 
    843         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[anMasterLane], -1);
    844         _SOC_IF_ERR_EXIT(rv);
    845         
    846         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy], _SHR_PORT_IF_COUNT);
    847         _SOC_IF_ERR_EXIT(rv);
    848 
    849         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    850                                       pm_info->wb_vars_ids[portDynamicState], 0);
    851 
    852         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    853                                       pm_info->wb_vars_ids[pllDividerReq], 0);
    854 
    855         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    856                               pm_info->wb_vars_ids[serdes1000xAt25gVco], 0);
    857 
    858         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    859                               pm_info->wb_vars_ids[serdes10gAt25gVco], 0);
    860 
    861        rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    862                               pm_info->wb_vars_ids[cpriVsdActiveGrp], 0);
    863         _SOC_IF_ERR_EXIT(rv);
    864 
    865         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
    866                               pm_info->wb_vars_ids[linkRecovery], 0);
    867         _SOC_IF_ERR_EXIT(rv);
    868     }
    869 
    870 exit:
    871     SOC_FUNC_RETURN;
    872 }
    873 
    874 STATIC portmod_ucode_buf_t pm4x25_ucode_buf[SOC_MAX_NUM_DEVICES] = {{NULL, 0}};
    875 STATIC portmod_ucode_buf_t pm4x25_ucode_buf_2nd[SOC_MAX_NUM_DEVICES] = {{NULL, 0}};
    876 
    877 int pm4x25_pm_destroy(int unit, pm_info_t pm_info)
    878 {
    879     SOC_INIT_FUNC_DEFS;
    880 
    881     if(pm_info->pm_data.pm4x25_db != NULL){
    882         sal_free(pm_info->pm_data.pm4x25_db);
    883         pm_info->pm_data.pm4x25_db = NULL;
    884     }
    885 
    886     /* free pm4x25_ucode_buf */
    887     if(pm4x25_ucode_buf[unit].ucode_dma_buf != NULL){
    888         portmod_sys_dma_free(unit, pm4x25_ucode_buf[unit].ucode_dma_buf);
    889         pm4x25_ucode_buf[unit].ucode_dma_buf = NULL;
    890     }
    891     pm4x25_ucode_buf[unit].ucode_alloc_size = 0;
    892 
    893     if(pm4x25_ucode_buf_2nd[unit].ucode_dma_buf != NULL){
    894         portmod_sys_dma_free(unit, pm4x25_ucode_buf_2nd[unit].ucode_dma_buf);
    895         pm4x25_ucode_buf_2nd[unit].ucode_dma_buf = NULL;
    896     }
    897     pm4x25_ucode_buf_2nd[unit].ucode_alloc_size = 0;
    898 
    899     SOC_FUNC_RETURN; 
    900 }
    901 
    902 int
    903 pm4x25_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data)
    904 {
    905     int rv, bcast_en = 0;
    906     portmod_default_user_access_t *user_data;
    907     int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit;
    908     portmod_ucode_buf_order_t load_order;
    909     SOC_INIT_FUNC_DEFS;
    910 
    911     user_data = (portmod_default_user_access_t*)core->access.user_acc;
    912 
    913     if (PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_GET(user_data)) {
    914         load_order = portmod_ucode_buf_order_reversed;
    915     } else {
    916         load_order = portmod_ucode_buf_order_straight;
    917     }
    918 
    919 #ifdef FW_BCAST_DOWNLOAD
    920     if (PORTMOD_USER_ACCESS_FW_LOAD_BROADCAST_GET(user_data)) {
    921         bcast_en = 1;
    922     }
    923 #endif
    924 
    925     rv = portmod_firmware_set(unit,
    926                               user_data->blk_id,
    927                               data,
    928                               length,
    929                               load_order,
    930                               bcast_en,
    931                               &(pm4x25_ucode_buf[unit]),
    932                               &(pm4x25_ucode_buf_2nd[unit]),
    933                               CLPORT_WC_UCMEM_DATAm,
    934                               CLPORT_WC_UCMEM_CTRLr);
    935     _SOC_IF_ERR_EXIT(rv);
    936 
    937 exit:
    938     SOC_FUNC_RETURN;
    939 }
    940 
    941 STATIC
    942 int
    943 pm4x25_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    944 {
    945     return portmod_common_phy_sbus_reg_write(CLPORT_WC_UCMEM_DATAm, user_acc, core_addr, reg_addr, val);
    946 }
    947 
    948 STATIC
    949 int
    950 pm4x25_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    951 {
    952     return portmod_common_phy_sbus_reg_read(CLPORT_WC_UCMEM_DATAm, user_acc, core_addr, reg_addr, val);
    953 }
    954 
    955 STATIC
    956 int _pm4x25_port_soft_reset_set(int unit, int port, pm_info_t pm_info, int idx, int val)
    957 {
    958     int phy_acc;
    959     uint32 reg_val;
    960 
    961     SOC_INIT_FUNC_DEFS;
    962 
    963     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
    964 
    965     _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
    966 
    967     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT0f, val);
    968     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT1f, val);
    969     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT2f, val);
    970     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT3f, val);
    971 
    972     _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
    973 
    974 exit:
    975     SOC_FUNC_RETURN; 
    976 }
    977 int pm4x25_port_soft_reset_toggle(int unit, int port, pm_info_t pm_info, int idx)
    978 {
    979     int phy_acc;
    980     uint32 reg_val, old_val;
    981 
    982     SOC_INIT_FUNC_DEFS;
    983 
    984     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
    985 
    986     _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
    987     old_val = reg_val;
    988 
    989     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT0f, 1);
    990     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT1f, 1);
    991     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT2f, 1);
    992     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, PORT3f, 1);
    993 
    994     _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
    995     _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, old_val));
    996 
    997 exit:
    998     SOC_FUNC_RETURN; 
    999 }
   1000 
   1001 phymod_bus_t pm4x25_default_bus = {
   1002     "PM4x25 Bus",
   1003     pm4x25_default_bus_read,
   1004     pm4x25_default_bus_write,
   1005     NULL,
   1006     portmod_common_mutex_take,
   1007     portmod_common_mutex_give,
   1008     NULL,
   1009     NULL,
   1010     PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL
   1011 };
   1012 
   1013 int pm4x25_pm_init(int unit,
   1014                    const portmod_pm_create_info_internal_t* pm_add_info,
   1015                    int wb_buffer_index, pm_info_t pm_info)
   1016 {
   1017     const portmod_pm4x25_create_info_t *info = &pm_add_info->pm_specific_info.pm4x25;
   1018     pm4x25_t pm4x25_data = NULL;
   1019     int i,j, pm_is_active, rv, three_ports_mode;
   1020     int bypass_enable;
   1021     int pm_is_initialized;
   1022     portmod_xphy_lane_connection_t lane_conn;
   1023     portmod_xphy_lane_connection_t *db_lane_conn;
   1024     int lane, phyn;
   1025     SOC_INIT_FUNC_DEFS;
   1026 
   1027     pm_info->type = pm_add_info->type;
   1028     pm_info->unit = unit;
   1029     pm_info->wb_buffer_id = wb_buffer_index;
   1030 
   1031     /* PM4x25 specific info */
   1032     pm4x25_data = sal_alloc(sizeof(struct pm4x25_s), "specific_db");
   1033     SOC_NULL_CHECK(pm4x25_data);
   1034     pm_info->pm_data.pm4x25_db = pm4x25_data;
   1035 
   1036     PORTMOD_PBMP_ASSIGN(pm4x25_data->phys, pm_add_info->phys);
   1037     pm4x25_data->int_core_access.type = phymodDispatchTypeInvalid;
   1038     pm4x25_data->portmod_mac_soft_reset = pm_add_info->pm_specific_info.pm4x25.portmod_mac_soft_reset;
   1039     pm4x25_data->first_phy = -1;
   1040     pm4x25_data->warmboot_skip_db_restore = TRUE;
   1041     pm4x25_data->rescal = pm_add_info->pm_specific_info.pm4x25.rescal;
   1042 
   1043     for(i = 0 ; i < PM4X25_LANES_PER_CORE; i++){
   1044         pm4x25_data->nof_phys[i] = 0;
   1045     }
   1046 
   1047     /* init intertnal SerDes core access */
   1048     phymod_core_access_t_init(&pm4x25_data->int_core_access);
   1049 
   1050     /* initialize lane connections */
   1051     for(i = 0 ; i < MAX_PHYN ; i++){
   1052         for(j = 0 ; j < PM4X25_LANES_PER_CORE ; j++){
   1053             portmod_xphy_lane_connection_t_init(unit, &pm4x25_data->lane_conn[i][j]);
   1054         }
   1055     }
   1056 
   1057     if(!info->in_pm_12x10){
   1058         sal_memcpy(&pm4x25_data->polarity, &info->polarity, sizeof(phymod_polarity_t));
   1059         sal_memcpy(&(pm4x25_data->int_core_access.access), &info->access,
   1060                     sizeof(phymod_access_t));
   1061 
   1062         sal_memcpy(&pm4x25_data->lane_map, &info->lane_map,
   1063                     sizeof(pm4x25_data->lane_map));
   1064         pm4x25_data->ref_clk = info->ref_clk;
   1065         pm4x25_data->fw_load_method = info->fw_load_method;
   1066         pm4x25_data->external_fw_loader = info->external_fw_loader;
   1067 
   1068         if(info->access.bus == NULL) {
   1069             /* if null - use default */
   1070             pm4x25_data->int_core_access.access.bus = &pm4x25_default_bus;
   1071         }
   1072 
   1073         if(pm4x25_data->external_fw_loader == NULL) {
   1074             /* if null - use default */
   1075             pm4x25_data->external_fw_loader = pm4x25_default_fw_loader;
   1076         }
   1077 
   1078         for(i = 0 ; i < PM4X25_LANES_PER_CORE; i++){
   1079             pm4x25_data->nof_phys[i] = 1; /* Internal Phy */
   1080         }
   1081     }
   1082     pm4x25_data->in_pm12x10 = info->in_pm_12x10;
   1083     pm4x25_data->core_num   = info->core_num;
   1084     pm4x25_data->afe_pll = info->afe_pll;
   1085 
   1086     /*init wb buffer*/
   1087     _SOC_IF_ERR_EXIT(pm4x25_wb_buffer_init(unit, wb_buffer_index,  pm_info));
   1088 
   1089     if(SOC_WARM_BOOT(unit)){
   1090         rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   1091                          pm_info->wb_vars_ids[phy_type], &pm4x25_data->int_core_access.type );
   1092         _SOC_IF_ERR_EXIT(rv);
   1093 
   1094         /* restore nof_phys from wb */
   1095         for(i = 0 ; i < PM4X25_LANES_PER_CORE ; i++){
   1096             _SOC_IF_ERR_EXIT(PM4x25_PORT_NUM_PHYS_GET(unit, pm_info, &pm4x25_data->nof_phys[i], i));
   1097         }
   1098 
   1099         for(phyn = 0 ; phyn < MAX_PHYN ; phyn++){
   1100             for(lane = 0 ; lane < PM4X25_LANES_PER_CORE ; lane++){
   1101                 db_lane_conn = &(PM_4x25_INFO(pm_info)->lane_conn[phyn][lane]);
   1102                 _SOC_IF_ERR_EXIT(PM4x25_PORT_LANE_CONNECTION_DB_GET(unit, pm_info,
   1103                                  db_lane_conn, phyn, lane));
   1104             }
   1105         }
   1106     }
   1107 
   1108     if(!SOC_WARM_BOOT(unit)){
   1109         pm_is_active = 0;
   1110         rv = PM4x25_IS_ACTIVE_SET(unit, pm_info, pm_is_active);
   1111         _SOC_IF_ERR_EXIT(rv);
   1112 
   1113         pm_is_initialized = 0;
   1114         rv = PM4x25_IS_INITIALIZED_SET(unit, pm_info, pm_is_initialized);
   1115         _SOC_IF_ERR_EXIT(rv);
   1116 
   1117         bypass_enable = 0;
   1118         rv = PM4x25_IS_BYPASSED_SET(unit, pm_info, bypass_enable);
   1119         _SOC_IF_ERR_EXIT(rv);
   1120 
   1121         three_ports_mode = (info->port_mode_aux_info == portmodModeInfoThreePorts) ? 1 : 0;
   1122         rv = PM4x25_THREE_PORTS_MODE_SET(unit, pm_info, three_ports_mode);
   1123         _SOC_IF_ERR_EXIT(rv);
   1124 
   1125         rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1126             pm_info->wb_vars_ids[phy_type],
   1127             &PM_4x25_INFO(pm_info)->int_core_access.type, 0);
   1128         _SOC_IF_ERR_EXIT(rv);
   1129 
   1130         for(i = 0 ; i < PM4X25_LANES_PER_CORE ; i++){
   1131             rv = PM4x25_PORT_NUM_PHYS_SET(unit, pm_info, pm4x25_data->nof_phys[i], i);
   1132             _SOC_IF_ERR_EXIT(rv);
   1133         }
   1134 
   1135         portmod_xphy_lane_connection_t_init(unit, &lane_conn);
   1136         for(phyn = 0 ; phyn < MAX_PHYN ; phyn++){
   1137             for(lane = 0 ; lane < PM4X25_LANES_PER_CORE ; lane++){
   1138                 _SOC_IF_ERR_EXIT(PM4x25_PORT_LANE_CONNECTION_DB_SET(unit, pm_info,
   1139                                  &lane_conn, phyn, lane));
   1140             }
   1141         }
   1142     }
   1143 
   1144 exit:
   1145     if(SOC_FUNC_ERROR){
   1146         pm4x25_pm_destroy(unit, pm_info);
   1147     }
   1148     SOC_FUNC_RETURN;
   1149 }
   1150 
   1151 int pm4x25_port_tsc_reset_set(int unit, int phy_acc, int in_reset)
   1152 {
   1153     uint32 reg_val;
   1154     SOC_INIT_FUNC_DEFS;
   1155 
   1156     /* Bring Internal Phy OOR */
   1157     _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1158     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, RSTB_HWf, in_reset ? 0 : 1);
   1159     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, PWRDWNf, in_reset ? 1 : 0);
   1160     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, IDDQf, in_reset ? 1 : 0);
   1161     _SOC_IF_ERR_EXIT(WRITE_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, reg_val));
   1162 
   1163     /* Based on the feedback from SJ pmd support team, ~10-15usecs would be sufficient
   1164      * for the PLL/AFE to settle down out of IDDQ reset.
   1165      */
   1166     sal_usleep(10);
   1167 
   1168 exit:
   1169     SOC_FUNC_RETURN;
   1170 }
   1171 
   1172 STATIC
   1173 int _pm4x25_port_tsc_refclock_set(int unit, int phy_acc, int ref_in, int ref_out)
   1174 {
   1175     uint32 reg_val;
   1176     SOC_INIT_FUNC_DEFS;
   1177 
   1178     /* choose refclk into this TSC PLL : 0 - PAD or 1- LCREF */
   1179     /* enable ref_out: LCREFout which connects to other PM blocks */
   1180     _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1181     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, REFIN_ENf, ref_in ? 1 : 0);
   1182     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, REFOUT_ENf, ref_out ? 1 : 0);
   1183     _SOC_IF_ERR_EXIT(WRITE_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, reg_val));
   1184 
   1185 exit:
   1186     SOC_FUNC_RETURN;
   1187 }
   1188 
   1189 STATIC
   1190 int _pm4x25_port_tsc_refclock_get(int unit, int phy_acc, int *ref_in, int *ref_out)
   1191 {
   1192     uint32 reg_val;
   1193     SOC_INIT_FUNC_DEFS;
   1194 
   1195     /* choose refin : PAD or LCREF */
   1196     /* enable ref_out: LCREFout which connects to other PM blocks */
   1197     _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1198     *ref_in  = soc_reg_field_get(unit, CLPORT_XGXS0_CTRL_REGr, reg_val, REFIN_ENf);
   1199     *ref_out = soc_reg_field_get(unit, CLPORT_XGXS0_CTRL_REGr, reg_val, REFOUT_ENf);
   1200 
   1201 exit:
   1202     SOC_FUNC_RETURN;
   1203 }
   1204 
   1205 /*
   1206 *  Set PM TSC refer clock source and enable refer clock output to other TSC.
   1207 *  ref_in: Selects between pad and LCREF as source of refclk into this TSC PLL. 0 - PAD or 1- LCREF
   1208 *  ref_out: Enables LCREFOUT to be driven by this TSC. 0 - disable, 1 - enable
   1209 *  Note: If enable LCREF_out to other PMs TSC, this PM TSC work as master PM.
   1210 *        This TSC should be reset at in level before this port attaching.
   1211 */
   1212 int pm4x25_port_tsc_refclock_set(int unit, int port, pm_info_t pm_info, int ref_in, int ref_out)
   1213 {
   1214     int phy_acc;
   1215 
   1216     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1217 
   1218     return _pm4x25_port_tsc_refclock_set(unit, phy_acc, ref_in, ref_out);
   1219 }
   1220 
   1221 /*
   1222 *  Get PM TSC refer clock source and enable status of refer clock output to other TSC.
   1223 *  ref_in: 0 - PAD or 1- LCREF
   1224 *  ref_out: 1 - enable LCREF_out which connects to other PM blocks
   1225 */
   1226 int pm4x25_port_tsc_refclock_get(int unit, int port, pm_info_t pm_info, int *ref_in, int *ref_out)
   1227 {
   1228     int phy_acc;
   1229 
   1230     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1231 
   1232     return _pm4x25_port_tsc_refclock_get(unit, phy_acc, ref_in, ref_out);
   1233 }
   1234 
   1235 /*
   1236  *  Check the PM is a master PLL or not
   1237  *  For GEN1/GEN2, only need to check one PLL
   1238  *  For GEN3, need to check PLL0 and PLL1
   1239  */
   1240 STATIC
   1241 int _pm4x25_port_tsc_is_master_pll(int unit, int port, pm_info_t pm_info)
   1242 {
   1243    int phy_acc;
   1244    uint32 reg_val;
   1245    uint32 refclk_out_en_0 = 0, refclk_out_en_1 = 0;
   1246    pm_version_t pm_version;
   1247    SOC_INIT_FUNC_DEFS;
   1248 
   1249    PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1250 
   1251    _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   1252 
   1253    if (PORTMOD_PM4x25_IS_GEN1_GEN2(pm_version)) {
   1254         _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1255         refclk_out_en_0 = soc_reg_field_get(unit, CLPORT_XGXS0_CTRL_REGr, reg_val, REFOUT_ENf);
   1256     } else if (PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)) {
   1257         /* Valid only for G3 28nm PMD_28_FC, don't care for 16nm */
   1258         _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1259         refclk_out_en_0 = soc_reg_field_get(unit, CLPORT_XGXS0_CTRL_REGr, reg_val, PLL0_REFOUT_ENf);
   1260         refclk_out_en_1 = soc_reg_field_get(unit, CLPORT_XGXS0_CTRL_REGr, reg_val, PLL1_REFOUT_ENf);
   1261     } else {
   1262         refclk_out_en_0 = 0;
   1263         refclk_out_en_1 = 0;
   1264     }
   1265 
   1266    if (refclk_out_en_0 || refclk_out_en_1) {
   1267        return TRUE;
   1268    }
   1269 
   1270    return FALSE;
   1271 
   1272 exit:
   1273     SOC_FUNC_RETURN;
   1274 }
   1275 
   1276 static int _clport_mode_get(int unit, int phy_acc, int bindex, 
   1277                       portmod_core_port_mode_t *core_mode, int *cur_lanes)
   1278 {
   1279     uint32_t rval;
   1280 
   1281     SOC_INIT_FUNC_DEFS;
   1282 
   1283     _SOC_IF_ERR_EXIT(READ_CLPORT_MODE_REGr(unit, phy_acc, &rval));
   1284 
   1285     *core_mode = soc_reg_field_get(unit, CLPORT_MODE_REGr, rval, XPORT0_CORE_PORT_MODEf);
   1286 
   1287     switch (*core_mode) {
   1288         case portmodPortModeQuad:
   1289             *cur_lanes = 1;
   1290             break;
   1291 
   1292         case portmodPortModeTri012: 
   1293             *cur_lanes = bindex == 2 ? 2 : 1;
   1294             break;
   1295 
   1296         case portmodPortModeTri023:
   1297             *cur_lanes = bindex == 0 ? 2 : 1;
   1298             break;
   1299 
   1300         case portmodPortModeDual: 
   1301             *cur_lanes = 2;
   1302             break;
   1303 
   1304         case portmodPortModeSingle:
   1305             *cur_lanes = 4;
   1306             break;
   1307 
   1308         default:
   1309             return SOC_E_FAIL;
   1310     }
   1311 exit:
   1312     SOC_FUNC_RETURN;
   1313 }
   1314 
   1315 int pm4x25_port_cntmaxsize_get(int unit, int port, pm_info_t pm_info, int *val)
   1316 {
   1317     int phy_acc;
   1318     SOC_INIT_FUNC_DEFS;
   1319 
   1320     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1321 
   1322     _SOC_IF_ERR_EXIT(READ_CLPORT_CNTMAXSIZEr(unit, phy_acc, (uint32_t *)val));
   1323 
   1324 exit:
   1325     SOC_FUNC_RETURN;
   1326 }
   1327 
   1328 int pm4x25_port_cntmaxsize_set(int unit, int port, pm_info_t pm_info, int val)
   1329 {
   1330     uint32 reg_val;
   1331     int phy_acc;
   1332     SOC_INIT_FUNC_DEFS;
   1333 
   1334     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1335 
   1336     _SOC_IF_ERR_EXIT(READ_CLPORT_CNTMAXSIZEr(unit, phy_acc, &reg_val));
   1337 
   1338     soc_reg_field_set(unit, CLPORT_CNTMAXSIZEr, &reg_val, CNTMAXSIZEf, val);
   1339 
   1340     _SOC_IF_ERR_EXIT(WRITE_CLPORT_CNTMAXSIZEr(unit, phy_acc, reg_val));
   1341 
   1342 exit:
   1343     SOC_FUNC_RETURN;
   1344 }
   1345 
   1346 int pm4x25_port_modid_set (int unit, int port, pm_info_t pm_info, int value)
   1347 {
   1348     uint32_t rval, modid;
   1349     int      flen, phy_acc;
   1350     SOC_INIT_FUNC_DEFS;
   1351 
   1352     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1353 
   1354     flen = soc_reg_field_length(unit, CLPORT_CONFIGr, MY_MODIDf)? value : 0;
   1355     modid =  (value < (1 <<  flen))? value : 0;
   1356 
   1357     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1358     soc_reg_field_set(unit, CLPORT_CONFIGr, &rval, MY_MODIDf, modid);
   1359     _SOC_IF_ERR_EXIT(WRITE_CLPORT_CONFIGr(unit, phy_acc, rval));
   1360 
   1361 exit:
   1362     SOC_FUNC_RETURN;
   1363 }
   1364 
   1365 int pm4x25_port_higig2_mode_set (int unit, int port, pm_info_t pm_info, int mode)
   1366 {
   1367     int phy_acc;
   1368     uint32_t rval;
   1369     SOC_INIT_FUNC_DEFS;
   1370 
   1371     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1372 
   1373     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1374     soc_reg_field_set(unit, CLPORT_CONFIGr, &rval, HIGIG2_MODEf, mode);
   1375     _SOC_IF_ERR_EXIT(WRITE_CLPORT_CONFIGr(unit, phy_acc, rval));
   1376 
   1377 exit:
   1378     SOC_FUNC_RETURN;
   1379 }
   1380 
   1381 int pm4x25_port_higig2_mode_get (int unit, int port, pm_info_t pm_info, int *mode)
   1382 {
   1383     int phy_acc;
   1384     uint32_t rval;
   1385     SOC_INIT_FUNC_DEFS;
   1386 
   1387     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1388 
   1389     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1390     *(mode) = soc_reg_field_get(unit, CLPORT_CONFIGr, rval, HIGIG2_MODEf);
   1391 
   1392 exit:
   1393     SOC_FUNC_RETURN;
   1394 }
   1395 
   1396 int pm4x25_port_higig_mode_set (int unit, int port, pm_info_t pm_info, int mode)
   1397 {
   1398     int phy_acc;
   1399     uint32_t rval;
   1400     SOC_INIT_FUNC_DEFS;
   1401 
   1402     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1403 
   1404     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1405     soc_reg_field_set(unit, CLPORT_CONFIGr, &rval, HIGIG_MODEf, mode);
   1406     _SOC_IF_ERR_EXIT(WRITE_CLPORT_CONFIGr(unit, phy_acc, rval));
   1407    
   1408 exit:
   1409     SOC_FUNC_RETURN;
   1410 }
   1411 
   1412 int pm4x25_port_higig_mode_get (int unit, int port, pm_info_t pm_info, int *mode)
   1413 {
   1414     int phy_acc;
   1415     uint32_t rval;
   1416     SOC_INIT_FUNC_DEFS;
   1417 
   1418     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1419 
   1420     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1421     *(mode) = soc_reg_field_get(unit, CLPORT_CONFIGr, rval, HIGIG_MODEf);
   1422 
   1423 exit:
   1424     SOC_FUNC_RETURN;
   1425 }
   1426 
   1427 int pm4x25_port_encap_set (int unit, int port, pm_info_t pm_info, 
   1428                                 int flags, portmod_encap_t encap)
   1429 {
   1430     return (clmac_encap_set(unit, port, flags, encap));
   1431 
   1432 }
   1433 
   1434 int pm4x25_port_encap_get (int unit, int port, pm_info_t pm_info, 
   1435                             int *flags, portmod_encap_t *encap)
   1436 {
   1437     return (clmac_encap_get(unit, port, flags, encap));
   1438 }
   1439 
   1440 int pm4x25_port_config_port_type_set (int unit, int port, pm_info_t pm_info, int type)
   1441 {
   1442     int phy_acc;
   1443     uint32_t rval;
   1444     SOC_INIT_FUNC_DEFS;
   1445 
   1446     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1447 
   1448     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1449     soc_reg_field_set(unit, CLPORT_CONFIGr, &rval, PORT_TYPEf, type);
   1450     _SOC_IF_ERR_EXIT(WRITE_CLPORT_CONFIGr(unit, phy_acc, rval));
   1451 
   1452 exit:
   1453     SOC_FUNC_RETURN;
   1454 }
   1455 
   1456 int pm4x25_port_config_port_type_get (int unit, int port, pm_info_t pm_info, int *type)
   1457 {
   1458     int phy_acc;
   1459     uint32_t rval;
   1460     SOC_INIT_FUNC_DEFS;
   1461 
   1462     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1463 
   1464     _SOC_IF_ERR_EXIT(READ_CLPORT_CONFIGr(unit, phy_acc, &rval));
   1465     *(type) = soc_reg_field_get(unit, CLPORT_CONFIGr, rval, PORT_TYPEf);
   1466 
   1467 exit:
   1468     SOC_FUNC_RETURN;
   1469 }
   1470 
   1471 int pm4x25_port_led_chain_config (int unit, int port, pm_info_t pm, int value)
   1472 {
   1473     int phy_acc;
   1474     SOC_INIT_FUNC_DEFS;
   1475 
   1476     PM4x25_PHY_ACCESS_GET(unit, port, pm, phy_acc);
   1477 
   1478     _SOC_IF_ERR_EXIT(WRITE_CLPORT_LED_CHAIN_CONFIGr (unit, phy_acc, value));
   1479 
   1480 exit:
   1481     SOC_FUNC_RETURN;
   1482 }
   1483 
   1484 int pm4x25_port_phy_lane_access_get(int unit, int port, pm_info_t pm_info,
   1485                                     const portmod_access_get_params_t* params,
   1486                                     int max_phys,
   1487                                     phymod_phy_access_t* phy_access,
   1488                                     int* nof_phys,
   1489                                     int* is_most_ext)
   1490 {
   1491     int phyn = 0, rv;
   1492     uint32  iphy_lane_mask;
   1493     int port_index=0;
   1494     int serdes_lane=0;
   1495     int xphy_lane_mask=0;
   1496     uint32 xphy_id = 0;
   1497     phymod_core_access_t core_access;
   1498     uint32 lane_mask[MAX_NUM_CORES];
   1499     uint32 pm_is_bypassed = 0;
   1500     phymod_port_loc_t port_loc[MAX_NUM_CORES];
   1501     int i, is_legacy_phy;
   1502     uint32 xphy_idx;
   1503     int num_of_phys;
   1504     int done;
   1505 
   1506     SOC_INIT_FUNC_DEFS;
   1507 
   1508     if(max_phys > MAX_NUM_CORES)
   1509     {
   1510         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1511                (_SOC_MSG("max_phys parameter exceeded the MAX value. max_phys=%d, max allowed %d."),
   1512             		   max_phys, MAX_NUM_CORES));
   1513     }
   1514     
   1515     if(PM_4x25_INFO(pm_info)->in_pm12x10){
   1516         _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("phy access get cannot be called for PM4X25 which is part of PM12X10")));
   1517     }
   1518 
   1519     /* get port index and lane mask */
   1520     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index,
   1521                                             &iphy_lane_mask));
   1522 
   1523     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &pm_is_bypassed);
   1524     _SOC_IF_ERR_EXIT(rv);
   1525 
   1526     if(params->phyn >= PM_4x25_INFO(pm_info)->nof_phys[port_index]){
   1527         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1528                (_SOC_MSG("phyn exceeded. max allowed %d. got %d"),
   1529                PM_4x25_INFO(pm_info)->nof_phys[port_index] - 1, params->phyn));
   1530     }
   1531 
   1532     for( i = 0 ; i < max_phys; i++) {
   1533         lane_mask[i] = 0;
   1534         _SOC_IF_ERR_EXIT(phymod_phy_access_t_init(&phy_access[i]));
   1535     }
   1536 
   1537     phyn = params->phyn;
   1538 
   1539     /* if phyn is -1, it is looking for outer most phy.
   1540        assumption is that all lane has same phy depth. */
   1541     if(phyn < 0) {
   1542         phyn = PM_4x25_INFO(pm_info)->nof_phys[port_index] - 1;
   1543     }
   1544 
   1545 
   1546     if( phyn == 0 ) {
   1547         *nof_phys = 1;
   1548         /* internal core */
   1549         sal_memcpy (&phy_access[0], &(PM_4x25_INFO(pm_info)->int_core_access),
   1550                     sizeof(phymod_phy_access_t));
   1551         phy_access[0].access.lane_mask = iphy_lane_mask;
   1552         if (params->lane != -1) {
   1553             serdes_lane = port_index + params->lane;
   1554             phy_access[0].access.lane_mask &= (0x1 << serdes_lane );
   1555             if (phy_access[0].access.lane_mask == 0) {
   1556                 *nof_phys = 0;
   1557             }
   1558         }
   1559         phy_access[0].port_loc = phymodPortLocLine; /* only line is availabe for internal. */
   1560 
   1561         /* PCS bypass flag is set when the underlying device is DNX */
   1562         if ((pm_is_bypassed) && (!PM_4x25_INFO(pm_info)->in_pm12x10)) {
   1563             PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_SET(phy_access[0].device_op_mode);
   1564         }
   1565 
   1566         /* if it is warm boot, get probed information from wb db instead of re-probing. */
   1567         if(SOC_WARM_BOOT(unit)) {
   1568             rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phy_type], &(phy_access[0].type));
   1569             _SOC_IF_ERR_EXIT(rv);
   1570         }
   1571         
   1572     } else {
   1573 
   1574         /* external phy */
   1575         num_of_phys = 0;
   1576 
   1577         /* xphy idx is 1 less than phyn since internal core does not count */    
   1578         xphy_idx = phyn-1;
   1579     
   1580         if (params->lane != -1){ /* specific lane */
   1581             serdes_lane = port_index + params->lane;
   1582             xphy_id = PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].xphy_id;
   1583             _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   1584             sal_memcpy (&phy_access[num_of_phys], &core_access,
   1585                         sizeof(phymod_phy_access_t));
   1586             xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)? PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   1587                           PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   1588             if( xphy_lane_mask != -1 ){
   1589                 phy_access[0].access.lane_mask |= xphy_lane_mask;
   1590             }
   1591             phy_access[0].port_loc = ( params->sys_side == PORTMOD_SIDE_SYSTEM) ?
   1592                                        phymodPortLocSys : phymodPortLocLine;
   1593             *nof_phys = 1;
   1594         } else { /* all lanes */
   1595             /* go thru all the lanes related to this port. */
   1596             serdes_lane = 0;
   1597 
   1598             for (serdes_lane = 0; serdes_lane < MAX_PORTS_PER_PM4X25; serdes_lane++) 
   1599                 if (iphy_lane_mask & (1U<<serdes_lane)) {
   1600                 xphy_id = PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].xphy_id;
   1601                 if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   1602                     _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   1603                     if(num_of_phys == 0 ) {/* first one */
   1604                         sal_memcpy (&phy_access[num_of_phys], &core_access,
   1605                                     sizeof(phymod_phy_access_t));
   1606                         xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   1607                                     PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   1608                                     PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   1609                         if( xphy_lane_mask != -1) {
   1610                             lane_mask[num_of_phys] |= xphy_lane_mask;
   1611                         }
   1612                         port_loc[num_of_phys] = (params->sys_side == PORTMOD_SIDE_SYSTEM) ?
   1613                                                   phymodPortLocSys : phymodPortLocLine;
   1614                         
   1615                         num_of_phys++;
   1616                     } else {
   1617                         /* if not the first one, see if this one sharing core with other 
   1618                            lanes.  */
   1619                         done = 0;
   1620                         for( i = 0 ; (i < num_of_phys) &&(!done) ; i++) {
   1621                              if((!sal_memcmp (&phy_access[i], &core_access,
   1622                                                sizeof(phymod_phy_access_t)))) { /* found a match */
   1623                                 /* update lane */
   1624                                 xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   1625                                             PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   1626                                             PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   1627                                 if( xphy_lane_mask != -1) {
   1628                                     lane_mask[i] |= xphy_lane_mask;
   1629                                 }
   1630                                 done = 1;
   1631                             }
   1632                         }
   1633                         if((!done) && (num_of_phys < max_phys)){
   1634                             sal_memcpy (&phy_access[num_of_phys], &core_access,
   1635                             sizeof(phymod_phy_access_t));
   1636                             xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   1637                                         PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   1638                                         PM_4x25_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   1639                             if( xphy_lane_mask != -1) {
   1640                                 lane_mask[num_of_phys] |= xphy_lane_mask;
   1641                             }
   1642                             port_loc[num_of_phys] = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   1643                                                                 phymodPortLocSys : phymodPortLocLine ;
   1644                             num_of_phys++;
   1645                         } 
   1646                     }
   1647                 }
   1648             }
   1649             *nof_phys = num_of_phys;
   1650             for( i = 0 ; (i < *nof_phys) ; i++) {
   1651                 phy_access[i].access.lane_mask = lane_mask[i];
   1652                 phy_access[i].port_loc = port_loc[i];
   1653             }
   1654         }
   1655     } /* ext phys */ 
   1656        
   1657     /* assumption is that all logical port have same phy depths, that 
   1658        will not true when simplex introduced , until then we can keep 
   1659        this code. */
   1660     if (is_most_ext) {
   1661         if (phyn == PM_4x25_INFO(pm_info)->nof_phys[port_index]-1) {
   1662             *is_most_ext = 1;
   1663         } else {
   1664             *is_most_ext = 0;
   1665         }
   1666     }
   1667 exit:
   1668     SOC_FUNC_RETURN;
   1669 
   1670 }
   1671 
   1672 typedef enum clmac_port_mode_e{
   1673     CLMAC_4_LANES_SEPARATE  = 0,
   1674     CLMAC_3_TRI_0_1_2_2     = 1,
   1675     CLMAC_3_TRI_0_0_2_3     = 2,
   1676     CLMAC_2_LANES_DUAL      = 3,
   1677     CLMAC_4_LANES_TOGETHER  = 4
   1678 } clmac_port_mode_t;
   1679 
   1680 static phymod_dispatch_type_t pm4x25_serdes_list[] =
   1681 {
   1682     phymodDispatchTypeTscf,
   1683     phymodDispatchTypeTscf16,
   1684     phymodDispatchTypeTscf_gen3,
   1685     phymodDispatchTypeInvalid
   1686 };
   1687 
   1688 STATIC
   1689 int _pm4x25_pm_core_probe(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   1690 {
   1691     int     rv = SOC_E_NONE;
   1692     int     temp, phy;
   1693     portmod_pbmp_t port_phys_in_pm;
   1694     int probe =0;
   1695     uint32 xphy_id;
   1696     uint32 nof_ext_phys =0;
   1697     int i, is_legacy_phy;
   1698     portmod_xphy_lane_connection_t lane_conn;
   1699     phymod_core_access_t core_access;
   1700     int core_probed;
   1701     SOC_INIT_FUNC_DEFS;
   1702 
   1703     sal_memset(&lane_conn,0,sizeof(portmod_xphy_lane_connection_t));
   1704 
   1705     /* probe phys (both internal and external cores. */
   1706 
   1707     /* Get the first phy related to this port */
   1708     PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   1709     PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x25_INFO(pm_info)->phys);
   1710 
   1711     /* if internal core is not probe, probe it. Currently checking to type to see
   1712        phymodDispatchTypeInvalid, later need to move to WB.  */
   1713     _SOC_IF_ERR_EXIT(portmod_common_serdes_probe(pm4x25_serdes_list, &PM_4x25_INFO(pm_info)->int_core_access, &probe));
   1714 
   1715     /* save probed phy type to wb. */
   1716     if(probe) {
   1717           rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   1718                      pm_info->wb_vars_ids[phy_type],
   1719                      &PM_4x25_INFO(pm_info)->int_core_access.type);
   1720           _SOC_IF_ERR_EXIT(rv);
   1721     }
   1722 
   1723     /* probe ext core related to this logical port. */
   1724     temp = 0;
   1725     PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy) {
   1726         if(PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)) {
   1727             if( PM_4x25_INFO(pm_info)->nof_phys[temp] >= 2 ){
   1728                 nof_ext_phys = PM_4x25_INFO(pm_info)->nof_phys[temp]-1;
   1729                 for(i=0 ; i<nof_ext_phys ; i++) {
   1730                     xphy_id = PM_4x25_INFO(pm_info)->lane_conn[i][temp].xphy_id;
   1731                     if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   1732                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   1733                         _SOC_IF_ERR_EXIT(portmod_common_ext_phy_probe(unit, port, &core_access, &probe));
   1734                         if ((probe == 0) &&
   1735                             (core_access.type == phymodDispatchTypeInvalid)){
   1736                             pm4x25_xphy_lane_detach_from_pm(unit, pm_info, phy, i+1, &lane_conn);
   1737                             LOG_ERROR(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   1738                                 "Warning: EXT PHY p=%d xphy_id=%d can't be probed\n"), port, xphy_id));
   1739                         } else {
   1740                             core_probed = 1;
   1741                             _SOC_IF_ERR_EXIT(portmod_xphy_core_probed_set(unit, xphy_id, core_probed));
   1742                             /* Check if after the probe the ext phy is legacy, so we dont overrun the current value */
   1743                             _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   1744                             _SOC_IF_ERR_EXIT(portmod_xphy_core_access_set(unit, xphy_id, &core_access, is_legacy_phy));
   1745                         }
   1746                     }
   1747                 }
   1748             }
   1749         }
   1750         temp++;
   1751     }
   1752 
   1753     /*update warmboot engine*/
   1754     rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1755         pm_info->wb_vars_ids[phy_type],
   1756         &PM_4x25_INFO(pm_info)->int_core_access.type, 0);
   1757     _SOC_IF_ERR_EXIT(rv);
   1758 
   1759 exit:
   1760     SOC_FUNC_RETURN;
   1761 }
   1762 
   1763 STATIC
   1764 int _pm4x25_pm_serdes_core_init(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   1765 {
   1766     int rv;
   1767     phymod_core_init_config_t core_conf;
   1768     phymod_core_status_t core_status;
   1769     phymod_phy_access_t serdes_access;
   1770     const portmod_port_interface_config_t* config;
   1771     uint32 core_is_initialized;
   1772     soc_port_if_t interface = SOC_PORT_IF_NULL;
   1773     uint32 init_flags = 0, is_bypass;
   1774     pm_version_t pm_version;
   1775     SOC_INIT_FUNC_DEFS;
   1776 
   1777     config = &(add_info->interface_config);
   1778 
   1779     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &is_bypass);
   1780     _SOC_IF_ERR_EXIT(rv);
   1781 
   1782     _SOC_IF_ERR_EXIT(phymod_core_init_config_t_init(&core_conf));
   1783 
   1784     core_conf.firmware_load_method = PM_4x25_INFO(pm_info)->fw_load_method;
   1785     core_conf.firmware_loader = PM_4x25_INFO(pm_info)->external_fw_loader;
   1786     core_conf.lane_map = PM_4x25_INFO(pm_info)->lane_map;
   1787 
   1788     core_conf.afe_pll.afe_pll_change_default = PM_4x25_INFO(pm_info)->afe_pll.afe_pll_change_default;
   1789     core_conf.afe_pll.ams_pll_iqp = PM_4x25_INFO(pm_info)->afe_pll.ams_pll_iqp;
   1790     core_conf.afe_pll.ams_pll_en_hrz = PM_4x25_INFO(pm_info)->afe_pll.ams_pll_en_hrz;
   1791 
   1792     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&core_conf.interface));
   1793     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface));
   1794     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed,
   1795                 interface, &core_conf.interface.interface_type));
   1796     core_conf.interface.data_rate = config->speed;
   1797     core_conf.interface.interface_modes = config->interface_modes;
   1798     core_conf.interface.ref_clock = PM_4x25_INFO(pm_info)->ref_clk;
   1799     core_conf.interface.pll_divider_req = config->pll_divider_req;
   1800 
   1801     _SOC_IF_ERR_EXIT(phymod_core_status_t_init(&core_status));
   1802     core_status.pmd_active = 0;
   1803 
   1804     init_flags = PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) | PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info);
   1805 
   1806     if (PORTMOD_PORT_ADD_F_FIRMWARE_LOAD_VERIFY_GET(add_info)) {
   1807         PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_SET(&core_conf);
   1808     }
   1809     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   1810         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_SET(&core_conf);
   1811     }
   1812     if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   1813         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_SET(&core_conf);
   1814     }
   1815     if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   1816         PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_SET(&core_conf);
   1817     }
   1818 #ifdef FW_BCAST_DOWNLOAD
   1819     if (PORTMOD_PORT_ADD_F_FIRMWARE_DOWNLOAD_BCAST_GET(add_info)) {
   1820         PHYMOD_CORE_INIT_F_SERDES_FW_BCAST_SET(&core_conf);
   1821     }
   1822 #endif
   1823 
   1824     if (PORTMOD_PORT_ADD_F_IS_ENHANCED_PM4X25_GEN2_GET(add_info)) {
   1825         PHYMOD_CORE_INIT_F_CLK4PCS_3BIT_40T_SET(&core_conf);
   1826     }
   1827 #ifdef DEFAULT_OSR2P5_SET
   1828     if (PORTMOD_PORT_ADD_F_DEFAULT_OSR2P5_GET(add_info)) {
   1829         PHYMOD_CORE_INIT_F_DEFAULT_OSR2P5_SET(&core_conf);
   1830     }
   1831 #endif /* DEFAULT_OSR2P5_SET */
   1832 
   1833     core_conf.op_datapath = add_info->phy_op_datapath;
   1834 
   1835     rv = PM4x25_IS_INITIALIZED_GET(unit, pm_info, &core_is_initialized);
   1836     _SOC_IF_ERR_EXIT(rv);
   1837 
   1838     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   1839 
   1840     if ((PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version))
   1841          && PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)
   1842          && (!PORTMOD_CORE_INIT_FLAG_INITIALZIED_GET(core_is_initialized))) {
   1843         portmod_vcos_speed_config_t speed_config;
   1844         phymod_dual_plls_t init_plls;
   1845 
   1846         portmod_vcos_speed_config_t_init(unit, &speed_config);
   1847         speed_config.higig_mode = add_info->init_config.is_hg;
   1848         speed_config.speed = add_info->interface_config.speed;
   1849         speed_config.num_lanes = add_info->interface_config.port_num_lanes;
   1850         if(add_info->init_config.cpm_core_mode == portmodCpmMixEthCpri) {
   1851             speed_config.port_type = portmodCpmPrtEthOfMixedMode;
   1852         }
   1853         rv = _pm4x25_init_plls_get(unit, 0 , pm_info, &speed_config, 1, &init_plls);
   1854         _SOC_IF_ERR_EXIT(rv);
   1855         core_conf.pll0_div_init_value = init_plls.pll0_div;
   1856         core_conf.pll1_div_init_value = init_plls.pll1_div;
   1857     }
   1858 
   1859     if (!PORTMOD_CORE_INIT_FLAG_INITIALZIED_GET(core_is_initialized)) {
   1860          /* firmware load will happen after pass 1 */
   1861          if (!PORTMOD_CORE_INIT_FLAG_FIRMWARE_LOADED_GET(core_is_initialized) ||
   1862              PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   1863              if ((is_bypass) && (!PM_4x25_INFO(pm_info)->in_pm12x10)) {
   1864                  PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_SET(PM_4x25_INFO(pm_info)->int_core_access.device_op_mode);
   1865              }
   1866 
   1867             if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || init_flags == 0) {
   1868                 if (PM_4x25_INFO(pm_info)->rescal != -1) {
   1869                     sal_memcpy(&serdes_access, &(PM_4x25_INFO(pm_info)->int_core_access), sizeof(phymod_phy_access_t));
   1870                     phymod_phy_rescal_set(&serdes_access, 1, PM_4x25_INFO(pm_info)->rescal);
   1871                 }
   1872             }
   1873             if (add_info->init_config.cpm_core_mode == portmodCpmMixEthCpri) {
   1874                 PM_4x25_INFO(pm_info)->int_core_access.type = phymodDispatchTypeTscf_gen3;
   1875             }
   1876              _SOC_IF_ERR_EXIT(phymod_core_init(&PM_4x25_INFO(pm_info)->int_core_access,
   1877                                                &core_conf,
   1878                                                &core_status));
   1879 
   1880             if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || init_flags == 0) {
   1881                 PORTMOD_CORE_INIT_FLAG_FIRMWARE_LOADED_SET(core_is_initialized);
   1882                 rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   1883                                             pm_info->wb_vars_ids[isInitialized],
   1884                                             &core_is_initialized);
   1885                 _SOC_IF_ERR_EXIT(rv);
   1886             }
   1887             if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info) || init_flags == 0) {
   1888                 PORTMOD_CORE_INIT_FLAG_INITIALZIED_SET(core_is_initialized);
   1889                 rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   1890                                             pm_info->wb_vars_ids[isInitialized],
   1891                                             &core_is_initialized);
   1892                 _SOC_IF_ERR_EXIT(rv);
   1893             }
   1894 
   1895         }
   1896     }
   1897 
   1898 exit:
   1899     SOC_FUNC_RETURN;
   1900 }
   1901 
   1902 STATIC
   1903 int _pm4x25_pm_ext_phy_core_init(int unit, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   1904 {
   1905     int temp, phy;
   1906     phymod_core_init_config_t core_conf;
   1907     phymod_core_status_t core_status;
   1908     const portmod_port_interface_config_t* config;
   1909     portmod_pbmp_t port_phys_in_pm;
   1910     phymod_firmware_load_method_t fw_load_method;
   1911     phymod_lane_map_t lane_map;
   1912     phymod_core_access_t core_access;
   1913     uint32 primary_core_num;
   1914     soc_port_if_t interface = SOC_PORT_IF_NULL;
   1915     uint32 xphy_id;
   1916     int is_legacy_phy = 0;
   1917     uint32 nof_ext_phys = 0;
   1918     int force_fw_load, is_initialized = 0;
   1919     int init_all = 0, lane, i;
   1920 
   1921     SOC_INIT_FUNC_DEFS;
   1922 
   1923     config = &(add_info->interface_config);
   1924 
   1925     init_all = (!PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) &&
   1926                 !PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) &&
   1927                 !PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) ? 1 : 0;
   1928 
   1929     /* Get the first phy related to this port */
   1930     PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   1931     PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x25_INFO(pm_info)->phys);
   1932 
   1933     _SOC_IF_ERR_EXIT(phymod_core_init_config_t_init(&core_conf));
   1934 
   1935     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   1936         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_SET(&core_conf);
   1937     }
   1938 
   1939     if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   1940         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_SET(&core_conf);
   1941     }
   1942 
   1943     core_conf.afe_pll.afe_pll_change_default = PM_4x25_INFO(pm_info)->afe_pll.afe_pll_change_default;
   1944     core_conf.afe_pll.ams_pll_iqp = PM_4x25_INFO(pm_info)->afe_pll.ams_pll_iqp;
   1945     core_conf.afe_pll.ams_pll_en_hrz = PM_4x25_INFO(pm_info)->afe_pll.ams_pll_en_hrz;
   1946 
   1947     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&core_conf.interface));
   1948     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface));
   1949     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed,
   1950                 interface, &core_conf.interface.interface_type));
   1951     core_conf.interface.data_rate = config->speed;
   1952     core_conf.interface.interface_modes = config->interface_modes;
   1953     core_conf.interface.ref_clock = PM_4x25_INFO(pm_info)->ref_clk;
   1954 
   1955     core_conf.op_datapath = add_info->phy_op_datapath;
   1956 
   1957     core_conf.firmware_load_method = (PM_4x25_INFO(pm_info)->fw_load_method ==
   1958                                             phymodFirmwareLoadMethodNone) ?
   1959                                             phymodFirmwareLoadMethodNone :
   1960                                             phymodFirmwareLoadMethodInternal;
   1961     core_conf.firmware_loader = NULL;
   1962 
   1963     /* config "no swap" for external phys.set later using APIs*/
   1964     for (lane=0 ; lane < PM4X25_LANES_PER_CORE; lane++) {
   1965         core_conf.lane_map.lane_map_rx[lane] = lane;
   1966         core_conf.lane_map.lane_map_tx[lane] = lane;
   1967     }
   1968 
   1969     temp = 0;
   1970     PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy) {
   1971         if (PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)) {
   1972             if (PM_4x25_INFO(pm_info)->nof_phys[temp] >= 2 ) {
   1973                 nof_ext_phys = PM_4x25_INFO(pm_info)->nof_phys[temp]-1;
   1974                 for (i=0 ; i<nof_ext_phys; i++) {
   1975                     xphy_id = PM_4x25_INFO(pm_info)->lane_conn[i][temp].xphy_id;
   1976                     if (xphy_id != PORTMOD_XPHY_ID_INVALID) {
   1977                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   1978                         _SOC_IF_ERR_EXIT(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   1979                         _SOC_IF_ERR_EXIT(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   1980                         _SOC_IF_ERR_EXIT(portmod_xphy_lane_map_get(unit, xphy_id, &lane_map));
   1981                         _SOC_IF_ERR_EXIT(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   1982 
   1983                         _SOC_IF_ERR_EXIT(phymod_core_status_t_init(&core_status));
   1984                         core_status.pmd_active = 0;
   1985 
   1986                         if (force_fw_load == phymodFirmwareLoadForce) {
   1987                             PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_conf);
   1988                         } else if (force_fw_load == phymodFirmwareLoadAuto) {
   1989                             PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_conf);
   1990                         }
   1991 
   1992                         if ((PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || init_all) &&
   1993                             (is_initialized & PHYMOD_CORE_INIT_F_EXECUTE_PASS1))
   1994                             continue;
   1995 
   1996                         if ((PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)|| init_all) &&
   1997                             (is_initialized & PHYMOD_CORE_INIT_F_EXECUTE_PASS2))
   1998                             continue;
   1999                         
   2000                         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   2001                         if (is_legacy_phy) {
   2002                             /* Dont do a core init for legacy Phys.*/
   2003                         } else {
   2004                             _SOC_IF_ERR_EXIT(phymod_core_init(&core_access,
   2005                                     &core_conf,
   2006                                     &core_status));
   2007                         }
   2008 
   2009                         if (init_all) {
   2010                             is_initialized = (PHYMOD_CORE_INIT_F_EXECUTE_PASS2 | PHYMOD_CORE_INIT_F_EXECUTE_PASS1);
   2011                         } else if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   2012                             is_initialized |= PHYMOD_CORE_INIT_F_EXECUTE_PASS2;
   2013                         } else {
   2014                             is_initialized = PHYMOD_CORE_INIT_F_EXECUTE_PASS1;
   2015                         }
   2016 
   2017                         _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2018                     }
   2019                 }
   2020             }
   2021         }
   2022         temp++;
   2023     }
   2024 
   2025 exit:
   2026     SOC_FUNC_RETURN;
   2027 }
   2028 
   2029 STATIC
   2030 int _pm4x25_pm_core_init(int unit, int port, pm_info_t pm_info,
   2031                              const portmod_port_add_info_t* add_info, int enable)
   2032 {
   2033     SOC_INIT_FUNC_DEFS;
   2034 
   2035     if (enable) {
   2036         _SOC_IF_ERR_EXIT(_pm4x25_pm_serdes_core_init(unit, port, pm_info, add_info));
   2037         _SOC_IF_ERR_EXIT(_pm4x25_pm_ext_phy_core_init(unit, pm_info, add_info));
   2038     }
   2039 
   2040 exit:
   2041     SOC_FUNC_RETURN;
   2042 }
   2043 
   2044 STATIC
   2045 int _pm4x25_pm_enable(int unit, int port, pm_info_t pm_info, int port_index, const portmod_port_add_info_t* add_info, int enable)
   2046 {
   2047     uint32 reg_val, port_mode;
   2048     int caui_mode, three_ports_mode;
   2049     int  rv, phy_acc;
   2050     int pm_ver_is_d0 = 0;
   2051     int is_master_pll = FALSE;
   2052     pm_version_t pm_version;
   2053     SOC_INIT_FUNC_DEFS;
   2054 
   2055     /* The below code is to distinguish PM4x25, before D0 versus D0 and beyond. This is since some sequences were modified in PM4x25 D0 */
   2056     rv = READ_CLPORT_GENERAL_SPARE1_REGr(unit, port, &reg_val);
   2057     if(rv == SOC_E_NONE) {
   2058         pm_ver_is_d0 = 1;
   2059     }else if (rv != SOC_E_PARAM) { /* rv == SOC_E_PARAM is OK, since it means CLPORT_GENERAL_SPARE1_REG register doesn't exist -> pm_ver_is_d0=FALSE */
   2060         _SOC_EXIT_WITH_ERR(rv, (_SOC_MSG("Port %d: We were trying to read CLPORT_GENERAL_SPARE1_REG but recieved an error that is not SOC_E_PARAM!\n"),
   2061                                 port));
   2062     }
   2063 
   2064     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   2065 
   2066 #ifdef PORTMOD_PM4X25TD_SUPPORT
   2067     if (pm_info->type == portmodDispatchTypePm4x25td) {
   2068         rv = _pm4x25td_pm_enable(unit, port, pm_info, port_index, add_info, enable);
   2069         _SOC_IF_ERR_EXIT(rv);
   2070     } else 
   2071 #endif /* PORTMOD_PM4X25TD_SUPPORT */
   2072     {
   2073         is_master_pll = _pm4x25_port_tsc_is_master_pll(unit, port, pm_info);
   2074 
   2075         _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   2076 
   2077         if(enable) {
   2078             /* Power Save */
   2079             _SOC_IF_ERR_EXIT(READ_CLPORT_POWER_SAVEr(unit, phy_acc, &reg_val));
   2080             soc_reg_field_set(unit, CLPORT_POWER_SAVEr, &reg_val, XPORT_CORE0f, 0);
   2081             _SOC_IF_ERR_EXIT(WRITE_CLPORT_POWER_SAVEr(unit, phy_acc, reg_val));
   2082 
   2083             /* Port configuration */
   2084             rv = PM4x25_THREE_PORTS_MODE_GET(unit, pm_info, &three_ports_mode);
   2085             _SOC_IF_ERR_EXIT(rv);
   2086 
   2087             caui_mode = (add_info->interface_config.interface == SOC_PORT_IF_CAUI ? 1 : 0);
   2088             /* if(PM4x25_QUAD_MODE_IF(add_info->interface_config.interface)) */
   2089             if(add_info->interface_config.port_num_lanes >= 4) {
   2090                 port_mode = CLMAC_4_LANES_TOGETHER;
   2091             /*} else if(PM4x25_DUAL_MODE_IF(add_info->interface_config.interface)){ */
   2092             } else if(add_info->interface_config.port_num_lanes == 2){
   2093                 if(!three_ports_mode) {
   2094                     port_mode = CLMAC_2_LANES_DUAL;
   2095                 } else {
   2096                     if(port_index < 2) {
   2097                         port_mode = CLMAC_3_TRI_0_0_2_3;
   2098                     } else {
   2099                         port_mode = CLMAC_3_TRI_0_1_2_2;
   2100                     }
   2101                 }
   2102             } else { /*single mode*/
   2103                 if(!three_ports_mode) {
   2104                     port_mode = CLMAC_4_LANES_SEPARATE;
   2105                 } else {
   2106                     if(port_index < 2) {
   2107                         port_mode = CLMAC_3_TRI_0_1_2_2;
   2108                     } else {
   2109                         port_mode = CLMAC_3_TRI_0_0_2_3;
   2110                     }
   2111                 }
   2112             }
   2113 
   2114             _SOC_IF_ERR_EXIT(READ_CLPORT_MODE_REGr(unit, phy_acc, &reg_val));
   2115             if (SOC_REG_FIELD_VALID(unit, CLPORT_MODE_REGr, FIELD_10_10f)) {
   2116                 soc_reg_field_set(unit, CLPORT_MODE_REGr, &reg_val, FIELD_10_10f, caui_mode);
   2117             } else if (SOC_REG_FIELD_VALID(unit, CLPORT_MODE_REGr, SINGLE_PORT_MODE_SPEED_100Gf)) {
   2118                 soc_reg_field_set(unit, CLPORT_MODE_REGr, &reg_val, SINGLE_PORT_MODE_SPEED_100Gf, caui_mode);
   2119             }
   2120             soc_reg_field_set(unit, CLPORT_MODE_REGr, &reg_val, XPORT0_CORE_PORT_MODEf, port_mode);
   2121             soc_reg_field_set(unit, CLPORT_MODE_REGr, &reg_val, XPORT0_PHY_PORT_MODEf,  port_mode);
   2122             soc_reg_field_set(unit, CLPORT_MODE_REGr, &reg_val, EGR_1588_TIMESTAMPING_MODEf,
   2123                 add_info->flags & PORTMOD_PORT_ADD_F_EGR_1588_TIMESTAMP_MODE_48BIT ? 1 : 0);
   2124             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MODE_REGr(unit, phy_acc, reg_val));
   2125 
   2126             if(PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)){
   2127                 /* Set txpi sdm scheme */
   2128                 _SOC_IF_ERR_EXIT(_pm4x25_txpi_sdm_scheme_set(unit, port, pm_info, add_info->init_config.txpi_sdm_scheme));
   2129                 /* Set txpi lane select */
   2130                 _SOC_IF_ERR_EXIT(_pm4x25_txpi_lane_select_set(unit, port, pm_info, (uint32 *)add_info->init_config.lane_map[0].lane_map_tx));
   2131              }
   2132 
   2133             if (PM_4x25_INFO(pm_info)->nof_phys[0] > 0) { 
   2134                 /* Get Serdes OOR */
   2135                 if(is_master_pll != TRUE) {  /* This PM is not master PM, reset it. */
   2136                     _SOC_IF_ERR_EXIT(pm4x25_port_tsc_reset_set(unit, phy_acc, 1));
   2137                     _SOC_IF_ERR_EXIT(pm4x25_port_tsc_reset_set(unit, phy_acc, 0));
   2138                 }
   2139             }
   2140 
   2141             /* Bring MAC OOR */
   2142             _SOC_IF_ERR_EXIT(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   2143             soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 0);
   2144             if (PORTMOD_PORT_ADD_F_SYS_16B_INTF_MODE_GET(add_info)) {
   2145                 if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr,
   2146                                         SYS_16B_INTF_MODEf)) {
   2147                     soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &reg_val,
   2148                                       SYS_16B_INTF_MODEf, 1);
   2149                 }
   2150                 _SOC_IF_ERR_EXIT(WRITE_CLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   2151             }
   2152             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   2153         } else { /* disable */
   2154             /* put MAC in reset */
   2155             _SOC_IF_ERR_EXIT(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   2156             soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 1);
   2157             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   2158 
   2159             if (pm_ver_is_d0 == 1){ /* At PM4x25 D0 and beyond - put MAC in reset - here */
   2160                 /* put MAC in reset */
   2161                 _SOC_IF_ERR_EXIT(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   2162                 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 1);
   2163                 _SOC_IF_ERR_EXIT(WRITE_CLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   2164             }
   2165 
   2166             /* Put Serdes in reset*/
   2167             if(is_master_pll != TRUE) {  /* This PM is not master PM, reset it. */
   2168                 _SOC_IF_ERR_EXIT(pm4x25_port_tsc_reset_set(unit, phy_acc, 1));
   2169             }
   2170 
   2171             /* Turn on Power Save */
   2172             _SOC_IF_ERR_EXIT(READ_CLPORT_POWER_SAVEr(unit, phy_acc, &reg_val));
   2173             soc_reg_field_set(unit, CLPORT_POWER_SAVEr, &reg_val, XPORT_CORE0f, 1);
   2174             _SOC_IF_ERR_EXIT(WRITE_CLPORT_POWER_SAVEr(unit, phy_acc, reg_val));
   2175         }
   2176     }
   2177 
   2178 exit:
   2179     SOC_FUNC_RETURN;
   2180 }
   2181 
   2182 int pm4x25_to_cpm_pm_enable(int unit, int port, pm_info_t pm_info, int port_index,
   2183                             const portmod_port_add_info_t* add_info,
   2184                             int enable) {
   2185     int rv;
   2186     SOC_INIT_FUNC_DEFS;
   2187     rv = _pm4x25_pm_enable(unit, port, pm_info, port_index, add_info, enable);
   2188     _SOC_IF_ERR_EXIT(rv);
   2189 
   2190 exit:
   2191     SOC_FUNC_RETURN;
   2192 }
   2193 
   2194 STATIC
   2195 int _pm4x25_pm_port_init(int unit, int port, pm_info_t pm_info, int internal_port,
   2196                          const portmod_port_add_info_t* add_info, int enable)
   2197 {
   2198     int rv, phy_acc;
   2199     uint32 reg_val, flags;
   2200     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   2201     uint32 rsv_mask, rsv_pfc_mask;
   2202     pm_version_t pm_version;
   2203     SOC_INIT_FUNC_DEFS;
   2204 
   2205     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   2206     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   2207 
   2208 #ifdef PORTMOD_PM4X25TD_SUPPORT
   2209     if (pm_info->type == portmodDispatchTypePm4x25td) {
   2210         rv = _pm4x25td_pm_port_init(unit, port, internal_port, add_info, enable);
   2211         _SOC_IF_ERR_EXIT(rv);
   2212     } else 
   2213 #endif /* PORTMOD_PM4X25TD_SUPPORT */
   2214     {
   2215         if (internal_port == -1)  {
   2216             _SOC_EXIT_WITH_ERR(SOC_E_PORT, (_SOC_MSG("Invalid internal Port %d"), 
   2217                                     internal_port));
   2218         }   
   2219         if(enable) {
   2220 
   2221             /* RSV Mask */
   2222             rsv_mask = 0;
   2223             rsv_pfc_mask = 0;
   2224             _SOC_IF_ERR_EXIT(READ_CLPORT_MAC_RSV_MASKr(unit, phy_acc, &rsv_pfc_mask));
   2225             if (rsv_pfc_mask & PFC_FRAME_DETECTED_RSV_MASK) {
   2226                 rsv_mask |= PFC_FRAME_DETECTED_RSV_MASK;
   2227             }
   2228             SHR_BITSET(&rsv_mask, 3); /* Receive terminate/code error */
   2229             SHR_BITSET(&rsv_mask, 4); /* CRC error */
   2230             SHR_BITSET(&rsv_mask, 6); /* Truncated/Frame out of Range */
   2231             SHR_BITSET(&rsv_mask, 17); /* RUNT detected*/
   2232             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MAC_RSV_MASKr(unit, phy_acc, rsv_mask));
   2233 
   2234             /* Soft reset */
   2235             _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   2236             soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, port_fields[internal_port], 1);
   2237             _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2238 
   2239             soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, port_fields[internal_port], 0);
   2240             _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2241 
   2242             /* Port enable */
   2243             _SOC_IF_ERR_EXIT(READ_CLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   2244             soc_reg_field_set(unit, CLPORT_ENABLE_REGr, &reg_val, port_fields[internal_port], 1);
   2245             _SOC_IF_ERR_EXIT(WRITE_CLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   2246 
   2247             /* Init MAC */
   2248             flags = 0;
   2249             if(PORTMOD_PORT_ADD_F_RX_SRIP_CRC_GET(add_info)) {
   2250                 flags |= CLMAC_INIT_F_RX_STRIP_CRC;
   2251             }
   2252 
   2253             if(PORTMOD_PORT_ADD_F_TX_APPEND_CRC_GET(add_info)) {
   2254                 flags |= CLMAC_INIT_F_TX_APPEND_CRC;
   2255             }
   2256 
   2257             if(PORTMOD_PORT_ADD_F_TX_REPLACE_CRC_GET(add_info)) {
   2258                 flags |= CLMAC_INIT_F_TX_REPLACE_CRC;
   2259             }
   2260 
   2261             if(PORTMOD_PORT_ADD_F_TX_PASS_THROUGH_CRC_GET(add_info)) {
   2262                 flags |= CLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE;
   2263             }
   2264 
   2265             if (IS_HG_PORT(unit, port)){
   2266                 flags |= CLMAC_INIT_F_IPG_CHECK_DISABLE;
   2267             } else {
   2268                 flags &= ~CLMAC_INIT_F_IPG_CHECK_DISABLE;
   2269             }
   2270 
   2271             if(PHYMOD_INTF_MODES_HIGIG_GET(&(add_info->interface_config))) {
   2272                 flags |= CLMAC_INIT_F_IS_HIGIG;
   2273             }
   2274             rv = clmac_init(unit, port, flags);
   2275             _SOC_IF_ERR_EXIT(rv);
   2276 
   2277             /* LSS */
   2278             _SOC_IF_ERR_EXIT(READ_CLPORT_FAULT_LINK_STATUSr(unit, phy_acc, &reg_val));
   2279             soc_reg_field_set(unit, CLPORT_FAULT_LINK_STATUSr, &reg_val, REMOTE_FAULTf, 1);
   2280             soc_reg_field_set(unit, CLPORT_FAULT_LINK_STATUSr, &reg_val, LOCAL_FAULTf, 1);
   2281             _SOC_IF_ERR_EXIT(WRITE_CLPORT_FAULT_LINK_STATUSr(unit, phy_acc, reg_val)); 
   2282 
   2283             /* Counter MAX size */ 
   2284             _SOC_IF_ERR_EXIT(READ_CLPORT_CNTMAXSIZEr(unit, phy_acc, &reg_val));
   2285             soc_reg_field_set(unit, CLPORT_CNTMAXSIZEr, &reg_val, CNTMAXSIZEf, 1518);
   2286             _SOC_IF_ERR_EXIT(WRITE_CLPORT_CNTMAXSIZEr(unit, phy_acc, reg_val));
   2287             
   2288             /* Reset MIB counters */ 
   2289             _SOC_IF_ERR_EXIT(READ_CLPORT_MIB_RESETr(unit, phy_acc, &reg_val));
   2290             /* coverity[ptr_arith:FALSE] */
   2291             SHR_BITSET(&reg_val, internal_port);
   2292             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MIB_RESETr(unit, phy_acc, reg_val));
   2293             SHR_BITCLR((uint32 *)&reg_val, internal_port);
   2294             _SOC_IF_ERR_EXIT(WRITE_CLPORT_MIB_RESETr(unit, phy_acc, reg_val));
   2295 
   2296             /* Disable MAC timestamp by default */
   2297             if (PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)) {
   2298                 _SOC_IF_ERR_EXIT(pm4x25_port_mac_timestamp_enable_set(unit, port, pm_info, 0));
   2299             }
   2300         } else {
   2301             /* Port disable */
   2302             _SOC_IF_ERR_EXIT(READ_CLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   2303             soc_reg_field_set(unit, CLPORT_ENABLE_REGr, &reg_val, port_fields[internal_port], 0);
   2304             _SOC_IF_ERR_EXIT(WRITE_CLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   2305 
   2306              /* Soft reset */
   2307             _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   2308             soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, port_fields[internal_port], 1);
   2309             _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2310         }
   2311     }
   2312 
   2313 exit:
   2314     SOC_FUNC_RETURN;
   2315 }
   2316 
   2317 STATIC
   2318 int _pm4x25_an_mode_update (int unit, int port, pm_info_t pm_info, int port_index, int num_lanes, int an_cl73)
   2319 {
   2320     int is_hg, rv;
   2321     phymod_an_mode_type_t an_mode;
   2322 
   2323     SOC_INIT_FUNC_DEFS;
   2324 
   2325     rv = PM4x25_IS_HG_GET(unit, pm_info, &is_hg, port_index);
   2326     _SOC_IF_ERR_EXIT(rv);
   2327     rv = PM4x25_AN_MODE_GET(unit, pm_info, &an_mode, port_index);
   2328     _SOC_IF_ERR_EXIT(rv);
   2329 
   2330     if(is_hg) {
   2331         an_mode = phymod_AN_MODE_CL73BAM;
   2332     } else if (an_cl73) {
   2333         switch (an_cl73) {
   2334             case PORTMOD_CL73_W_BAM:
   2335                 an_mode = phymod_AN_MODE_CL73BAM;
   2336                 break ;
   2337             case PORTMOD_CL73_WO_BAM:
   2338                 an_mode = phymod_AN_MODE_CL73;
   2339                 break ;
   2340             case PORTMOD_CL73_HPAM_VS_SW:
   2341                 an_mode = phymod_AN_MODE_HPAM;
   2342                 break ;  /* against TD+ */
   2343             case PORTMOD_CL73_HPAM:
   2344                 an_mode = phymod_AN_MODE_HPAM;
   2345                 break ;  /* against TR3 */
   2346             case PORTMOD_CL73_CL37:
   2347                 an_mode = phymod_AN_MODE_CL73;
   2348                 break ;
   2349             case PORTMOD_MSA:
   2350                 an_mode = phymod_AN_MODE_MSA;
   2351                 break;
   2352             case PORTMOD_CL73_MSA:
   2353                 an_mode = phymod_AN_MODE_CL73_MSA;
   2354             default:
   2355                 break;
   2356         }
   2357     } else {
   2358         an_mode = phymod_AN_MODE_CL73;  /* default mode */
   2359     }
   2360 
   2361     rv = PM4x25_AN_MODE_SET(unit, pm_info, an_mode, port_index);
   2362     _SOC_IF_ERR_EXIT(rv);
   2363 
   2364 exit:
   2365     SOC_FUNC_RETURN;
   2366 }
   2367 
   2368 STATIC
   2369 int _pm4x25_ext_phy_interface_check(int unit, int port, pm_info_t pm_info, phymod_phy_access_t *phy_acc,
   2370                                const portmod_port_interface_config_t *interface_config,
   2371                                soc_port_if_t interface, int *is_valid)
   2372 {
   2373     int rv = 0;
   2374     int num_lanes = 0, data_rate = 0;
   2375     uint32_t interface_mode = 0;
   2376     phymod_interface_t  phymod_intf;
   2377     int is_legacy_phy = 0;
   2378     int xphy_id;
   2379     SOC_INIT_FUNC_DEFS;
   2380 
   2381     _SOC_IF_ERR_EXIT
   2382         (pm4x25_port_lane_count_get(unit, port, pm_info,
   2383                                     PORTMOD_SIDE_LINE, &num_lanes));
   2384     interface_mode = interface_config->interface_modes;
   2385     data_rate      = interface_config->speed;
   2386 
   2387     xphy_id = phy_acc->access.addr;
   2388     _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   2389 
   2390     if (is_legacy_phy) {
   2391         /* if its a legacy PHY let the PHY driver decide the valid interface types */
   2392         *is_valid = 1;
   2393         rv = SOC_E_NONE;
   2394         SOC_EXIT;
   2395     }
   2396 
   2397     /* convert portmod interface tophymod interface */
   2398     rv = portmod_intf_to_phymod_intf(unit, data_rate, interface, &phymod_intf);
   2399     _SOC_IF_ERR_EXIT(rv);
   2400 
   2401     rv = portmod_port_line_interface_is_valid(unit, phy_acc, port, data_rate, phymod_intf,
   2402                                             num_lanes, interface_mode, is_valid);
   2403     _SOC_IF_ERR_EXIT(rv);
   2404 
   2405     if (!*is_valid) {
   2406         LOG_ERROR(BSL_LS_BCM_PORT,
   2407               (BSL_META_UP(unit, port,
   2408                "ERROR: u=%d p=%d interface type %d not supported by external PHY for this speed %d \n"),
   2409                unit, port, interface, data_rate));
   2410         rv = SOC_E_PARAM;
   2411         _SOC_IF_ERR_EXIT(rv);
   2412     }
   2413 
   2414 exit:
   2415     SOC_FUNC_RETURN;
   2416 }
   2417 
   2418 STATIC
   2419 int _pm4x25_interface_check(int unit, int port,
   2420                                const portmod_port_interface_config_t *interface_config,
   2421                                soc_port_if_t interface, int *is_valid)
   2422 {
   2423     int is_higig;
   2424     int num_lanes, nof_cores = 0;
   2425     phymod_core_info_t   core_info;
   2426     uint32_t rev_letter = 0;
   2427     phymod_core_access_t core_acc[1+MAX_NUM_CORES];
   2428     SOC_INIT_FUNC_DEFS;
   2429 
   2430     *is_valid = 0;
   2431     num_lanes = interface_config->port_num_lanes;
   2432     is_higig = ((interface_config->encap_mode == SOC_ENCAP_HIGIG2) ||
   2433                  (interface_config->encap_mode == SOC_ENCAP_HIGIG) ||
   2434                  PHYMOD_INTF_MODES_HIGIG_GET(interface_config)) ? 1 : 0;
   2435 
   2436     if (SOC_PORT_IF_ILKN == interface) {
   2437         *is_valid = 1;
   2438         return SOC_E_NONE;
   2439     }
   2440 
   2441     switch (interface_config->speed) {
   2442         case 0:
   2443             /* When AN=1 the input speed to portmod may be 0. At
   2444              * this moment the speed is still undecided so there
   2445              * is no reason to invalidate the interface type.
   2446              */
   2447             *is_valid = 1;
   2448             break;
   2449         case 1000:
   2450             if (num_lanes == 1) {
   2451                 if ((SOC_PORT_IF_SGMII == interface) ||
   2452                     (SOC_PORT_IF_GMII == interface) ||
   2453                     (SOC_PORT_IF_KX == interface)) {
   2454                     *is_valid = 1;
   2455                 }
   2456             }
   2457             break;
   2458          case 2500:
   2459             if (num_lanes == 1) {
   2460                 if ((SOC_PORT_IF_SGMII == interface) ||
   2461                     (SOC_PORT_IF_GMII == interface)) {
   2462                     *is_valid = 1;
   2463                 }
   2464             }
   2465             break;
   2466         case 5000:
   2467             if (num_lanes == 1) {
   2468                 if ((SOC_PORT_IF_KR == interface) ||
   2469                      (SOC_PORT_IF_CR == interface)) {
   2470                     *is_valid = 1;
   2471                 }
   2472             }
   2473             break;
   2474         case 10000:
   2475         case 11000:
   2476         case 12000:
   2477             if (is_higig) {
   2478                 if (num_lanes == 1) {
   2479                     if ((SOC_PORT_IF_XFI == interface) ||
   2480                         (SOC_PORT_IF_KR == interface) ||
   2481                         (SOC_PORT_IF_CR == interface)) {
   2482                         *is_valid = 1;
   2483                     }
   2484                 }
   2485             } else {
   2486                 if (num_lanes == 1) {
   2487                     if ((SOC_PORT_IF_SFI == interface) ||
   2488                         (SOC_PORT_IF_XFI == interface) ||
   2489                         (SOC_PORT_IF_KR == interface) ||
   2490                         (SOC_PORT_IF_CR == interface) ||
   2491                         (SOC_PORT_IF_SR == interface) ||
   2492                         (SOC_PORT_IF_LR == interface)) {
   2493                         *is_valid = 1;
   2494                     }
   2495                 } else if (num_lanes == 4) {
   2496                     _SOC_IF_ERR_EXIT
   2497                         (portmod_port_core_access_get(unit, port, 0,
   2498                                                       (1+MAX_NUM_CORES),
   2499                                                       core_acc, &nof_cores, NULL));
   2500                     _SOC_IF_ERR_EXIT(phymod_core_info_get(core_acc, &core_info));
   2501                     rev_letter = (core_info.serdes_id & 0xc000) >> 14;
   2502                     /* 10G XAUI is only avialable in TSCF Rev C0 of the PM4x25. */
   2503                     if (((core_info.serdes_id & 0x3f) == 0x14) && (rev_letter == 2)) {
   2504                         if ((SOC_PORT_IF_DNX_XAUI == interface) ||
   2505                             (SOC_PORT_IF_XAUI == interface)) {
   2506                             *is_valid = 1;
   2507                         }
   2508                     }
   2509                 }
   2510             }
   2511             break;
   2512         case 20000:
   2513         case 21000:
   2514             if (is_higig) {
   2515                 if (num_lanes == 1) {
   2516                     if ((SOC_PORT_IF_KR == interface) ||
   2517                         (SOC_PORT_IF_CR == interface)) {
   2518                         *is_valid = 1;
   2519                     }
   2520                 } else if (num_lanes == 2) {
   2521                     if ((SOC_PORT_IF_KR2 == interface) ||
   2522                         (SOC_PORT_IF_CR2 == interface)) {
   2523                         *is_valid = 1;
   2524                     }
   2525                 }
   2526             } else {
   2527                 if (num_lanes == 1) {
   2528                     if ((SOC_PORT_IF_KR == interface) ||
   2529                         (SOC_PORT_IF_CR == interface) ||
   2530                         (SOC_PORT_IF_SR == interface) ||
   2531                         (SOC_PORT_IF_LR == interface)) {
   2532                         *is_valid = 1;
   2533                     }
   2534                 } else if (num_lanes == 2) {
   2535                     if ((SOC_PORT_IF_KR2 == interface) ||
   2536                         (SOC_PORT_IF_CR2 == interface) ||
   2537                         (SOC_PORT_IF_SR2 == interface) ||
   2538                         (SOC_PORT_IF_LR2 == interface)) {
   2539                         *is_valid = 1;
   2540                     }
   2541                 }
   2542             }
   2543             break;
   2544         case 25000:
   2545         case 27000:
   2546             if (is_higig) {
   2547                 if (num_lanes == 1) {
   2548                     if ((SOC_PORT_IF_KR == interface) ||
   2549                         (SOC_PORT_IF_CR == interface)) {
   2550                         *is_valid = 1;
   2551                     }
   2552                 }
   2553             } else {
   2554                 if (num_lanes == 1) {
   2555                     if ((SOC_PORT_IF_KR == interface) ||
   2556                         (SOC_PORT_IF_CR == interface) ||
   2557                         (SOC_PORT_IF_SR == interface) ||
   2558                         (SOC_PORT_IF_LR == interface) ||
   2559                         (SOC_PORT_IF_XFI == interface) ||
   2560                         (SOC_PORT_IF_SFI == interface)) {
   2561                         *is_valid = 1;
   2562                     }
   2563                 }
   2564             }
   2565             break;
   2566         case 40000:
   2567         case 42000:
   2568             if (is_higig) {
   2569                 if (num_lanes == 4) {
   2570                     if ((SOC_PORT_IF_KR4 == interface) ||
   2571                         (SOC_PORT_IF_CR4 == interface)) {
   2572                         *is_valid = 1;
   2573                     }
   2574                 } else if (num_lanes == 2) {
   2575                     if ((SOC_PORT_IF_KR2 == interface) ||
   2576                         (SOC_PORT_IF_CR2 == interface)) {
   2577                         *is_valid = 1;
   2578                     }
   2579                 }
   2580             } else {
   2581                 if (num_lanes == 4) {
   2582                     if ((SOC_PORT_IF_KR4 == interface) ||
   2583                         (SOC_PORT_IF_CR4 == interface) ||
   2584                         (SOC_PORT_IF_SR4 == interface) ||
   2585                         (SOC_PORT_IF_XLAUI == interface) ||
   2586                         (SOC_PORT_IF_LR4 == interface)) {
   2587                         *is_valid = 1;
   2588                     }
   2589                 } else if (num_lanes == 2) {
   2590                     if ((SOC_PORT_IF_KR2 == interface) ||
   2591                         (SOC_PORT_IF_CR2 == interface) ||
   2592                         (SOC_PORT_IF_SR2 == interface) ||
   2593                         (SOC_PORT_IF_XLAUI2 == interface) ||
   2594                         (SOC_PORT_IF_LR2 == interface)) {
   2595                         *is_valid = 1;
   2596                     }
   2597                 }
   2598             }
   2599             break;
   2600         case 48000:
   2601             if (!is_higig && num_lanes == 4) {
   2602                 if ((SOC_PORT_IF_XLAUI == interface) ||
   2603                     (SOC_PORT_IF_CR4 == interface) ||
   2604                     (SOC_PORT_IF_KR4 == interface)) {
   2605                     *is_valid = 1;
   2606                 }
   2607             }
   2608             break;
   2609         case 50000:
   2610         case 53000:
   2611             if (is_higig) {
   2612                 if (num_lanes == 2) {
   2613                     if ((SOC_PORT_IF_KR2 == interface) ||
   2614                         (SOC_PORT_IF_CR2 == interface)) {
   2615                         *is_valid = 1;
   2616                     }
   2617                 } else if (num_lanes == 4) {
   2618                     if ((SOC_PORT_IF_KR4 == interface) ||
   2619                         (SOC_PORT_IF_CR4 == interface)) {
   2620                         *is_valid = 1;
   2621                     }
   2622                 } else {
   2623                     LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_UP(unit, port,
   2624                                "ERROR: u=%d p=%d number of lane %d not supported at speed %d\n"),
   2625                                 unit, port, num_lanes, interface_config->speed));
   2626                     return SOC_E_PARAM;
   2627                 }
   2628             } else {
   2629                 if (num_lanes == 2) {
   2630                     if ((SOC_PORT_IF_KR2 == interface) ||
   2631                         (SOC_PORT_IF_CR2 == interface) ||
   2632                         (SOC_PORT_IF_SR2 == interface) ||
   2633                         (SOC_PORT_IF_XLAUI2 == interface) ||
   2634                         (SOC_PORT_IF_LR2 == interface)) {
   2635                         *is_valid = 1;
   2636                     }
   2637                 } else if (num_lanes == 4) {
   2638                     if ((SOC_PORT_IF_KR4 == interface) ||
   2639                         (SOC_PORT_IF_CR4 == interface)) {
   2640                         *is_valid = 1;
   2641                     }
   2642                 } else {
   2643                     LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_UP(unit, port,
   2644                                "ERROR: u=%d p=%d number of lane %d not supported at speed %d\n"),
   2645                                 unit, port, num_lanes, interface_config->speed));
   2646                     return SOC_E_PARAM;
   2647                 }
   2648             }
   2649             break;
   2650         case 100000:
   2651         case 106000:
   2652             if (is_higig) {
   2653                 if (num_lanes == 4) {
   2654                     if ((SOC_PORT_IF_KR4 == interface) ||
   2655                         (SOC_PORT_IF_CR4 == interface)) {
   2656                         *is_valid = 1;
   2657                     }
   2658                 }
   2659             } else {
   2660                 if (num_lanes == 4) {
   2661                     if ((SOC_PORT_IF_KR4 == interface) ||
   2662                         (SOC_PORT_IF_CR4 == interface) ||
   2663                         (SOC_PORT_IF_SR4 == interface) ||
   2664                         (SOC_PORT_IF_CAUI4 == interface) ||
   2665                         (SOC_PORT_IF_CAUI == interface) ||
   2666                         (SOC_PORT_IF_LR4 == interface)) {
   2667                         *is_valid = 1;
   2668                     }
   2669                 }
   2670             }
   2671             break;
   2672         default:
   2673             break;
   2674     }
   2675 
   2676 exit:
   2677     SOC_FUNC_RETURN;
   2678 }
   2679 
   2680 STATIC
   2681 int _pm4x25_default_interface_get(int unit, int port,
   2682                                const portmod_port_interface_config_t *interface_config,
   2683                                soc_port_if_t *interface)
   2684 {
   2685     int is_higig;
   2686     int num_lanes;
   2687 
   2688     *interface = SOC_PORT_IF_NULL;
   2689     num_lanes = interface_config->port_num_lanes;
   2690     is_higig = ((interface_config->encap_mode == SOC_ENCAP_HIGIG2) ||
   2691                  (interface_config->encap_mode == SOC_ENCAP_HIGIG)) ? 1 : 0;
   2692 
   2693     switch (interface_config->speed) {
   2694         case 1000:
   2695             *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2696                                     SOC_PORT_IF_GMII: SOC_PORT_IF_SGMII;
   2697             break;
   2698         case 2500:
   2699             *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2700                                         SOC_PORT_IF_GMII: SOC_PORT_IF_SGMII;
   2701             break;
   2702         case 5000:
   2703             *interface = SOC_PORT_IF_KR;
   2704             break;
   2705         case 10000:
   2706             if (is_higig) {
   2707                 *interface = SOC_PORT_IF_CR;
   2708             } else {
   2709                 *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2710                                         SOC_PORT_IF_SFI : SOC_PORT_IF_XFI;
   2711             }
   2712             break;
   2713         case 11000:
   2714         case 12000:
   2715             *interface = SOC_PORT_IF_XFI;
   2716             break;
   2717         case 20000:
   2718         case 21000:
   2719             if (is_higig) {
   2720                 if (num_lanes == 2) {
   2721                     *interface = SOC_PORT_IF_CR2;
   2722                 } else {
   2723                     *interface = SOC_PORT_IF_CR;
   2724                 }
   2725             } else {
   2726                 if (num_lanes == 2) {
   2727                     *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2728                                         SOC_PORT_IF_SR2 : SOC_PORT_IF_CR2;
   2729                 } else {
   2730                     *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2731                                         SOC_PORT_IF_SR : SOC_PORT_IF_CR;
   2732                 }
   2733             }
   2734             break;
   2735         case 25000:
   2736         case 27000:
   2737             if (is_higig) {
   2738                 *interface = SOC_PORT_IF_CR;
   2739             } else {
   2740                 *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2741                                     SOC_PORT_IF_SR : SOC_PORT_IF_CR;
   2742             }
   2743             break;
   2744         case 40000:
   2745         case 42000:
   2746             if (is_higig) {
   2747                 if (num_lanes == 4) {
   2748                     *interface = SOC_PORT_IF_KR4;
   2749                 } else {
   2750                     *interface = SOC_PORT_IF_CR2;
   2751                 }
   2752             } else {
   2753                 if (num_lanes == 4) {
   2754                     *interface = SOC_PORT_IF_XLAUI;
   2755                 } else {
   2756                     *interface = SOC_PORT_IF_XLAUI2;
   2757                 }
   2758             }
   2759             break;
   2760         case 50000:
   2761         case 53000:
   2762             if (is_higig) {
   2763                 if (num_lanes == 4) {
   2764                     *interface = SOC_PORT_IF_KR4;
   2765                 } else if (num_lanes == 2){
   2766                     *interface = SOC_PORT_IF_CR2;
   2767                 } else {
   2768                     LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_UP(unit, port,
   2769                                "ERROR: u=%d p=%d number of lane %d not supported at speed %d\n"),
   2770                                 unit, port, num_lanes, interface_config->speed));
   2771                     return SOC_E_PARAM;
   2772                 }
   2773             } else {
   2774                 *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2775                                     SOC_PORT_IF_SR2 : SOC_PORT_IF_CR2;
   2776                 if (num_lanes == 4) {
   2777                     *interface = SOC_PORT_IF_CR4;
   2778                 }
   2779             }
   2780             break;
   2781         case 100000:
   2782         case 106000:
   2783             if (is_higig) {
   2784                 *interface = SOC_PORT_IF_CR4;
   2785             } else {
   2786                 *interface = SOC_PORT_IF_CAUI4;
   2787             }
   2788             break;
   2789         default:
   2790             if (num_lanes == 1) {
   2791                 if (interface_config->speed >= 10000) {
   2792                     *interface = SOC_PORT_IF_CR;
   2793                 } else {
   2794                     *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2795                                     SOC_PORT_IF_GMII: SOC_PORT_IF_SGMII;
   2796                 }
   2797             } else if (num_lanes == 2) {
   2798                 *interface = SOC_PORT_IF_CR2;
   2799             } else if (num_lanes == 4) {
   2800                 if (interface_config->speed >= 100000) {
   2801                     if (is_higig){
   2802                         *interface = SOC_PORT_IF_CR4;
   2803                     } else{
   2804                         *interface = SOC_PORT_IF_CAUI4;
   2805                     }
   2806                 } else {
   2807                     *interface = SOC_PORT_IF_CR4;
   2808                 }
   2809             } else {
   2810                 *interface = SOC_PORT_IF_ILKN;
   2811             }
   2812             break;
   2813     }
   2814 
   2815     return SOC_E_NONE;
   2816 }
   2817 
   2818 /* Argument phy_init_flags indicates whether this function is called during the
   2819  * port attach process or not. When phy_init_flags == PORTMOD_INIT_F_ALL_PHYS 
   2820  * it means that this function is being called during the port attach process.
   2821  * In this case the default interface type of a pm4x25 port can be changed here.
   2822  */
   2823 STATIC
   2824 int _pm4x25_line_side_phymod_interface_get(int unit, int port, 
   2825                                    pm_info_t pm_info, int phy_init_flags,
   2826                                    const portmod_port_interface_config_t *config,
   2827                                    phymod_interface_t *interface_type)
   2828 {
   2829     int port_index = 0;
   2830     int is_valid = 0, nof_phys = 0;
   2831     uint32 bitmap;
   2832     soc_port_if_t interface = SOC_PORT_IF_NULL;
   2833     phymod_phy_access_t phy_access_arr[1+MAX_PHYN];
   2834     pm_version_t pm_version;
   2835     SOC_INIT_FUNC_DEFS;
   2836 
   2837    
   2838     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index,
   2839                                             &bitmap));
   2840 
   2841     _SOC_IF_ERR_EXIT
   2842             (portmod_port_chain_phy_access_get(unit, port, pm_info,
   2843                                                phy_access_arr ,(1+MAX_PHYN),
   2844                                                &nof_phys));
   2845 
   2846     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface));
   2847 
   2848     /* 5G is 64b/66b encoding in pm4x25 Gen3 */
   2849     /* Change 5G default inteface to SOC_PORT_IF_KR */
   2850     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   2851     if (PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)) {
   2852         if (config->speed == 5000) {
   2853             if (interface == SOC_PORT_IF_GMII) {
   2854                 interface = SOC_PORT_IF_KR;
   2855             }
   2856         }
   2857     }
   2858 
   2859     if (nof_phys > 1) {
   2860         /* EXT PHY interface */
   2861         _SOC_IF_ERR_EXIT
   2862             (_pm4x25_ext_phy_interface_check(unit, port, pm_info, &phy_access_arr[nof_phys-1], config, interface,
   2863                                                  &is_valid));
   2864     } else {
   2865         _SOC_IF_ERR_EXIT
   2866             (_pm4x25_interface_check(unit, port, config, interface, &is_valid));
   2867     }
   2868 
   2869     if (!is_valid) {
   2870          /* interface check validation for internal sedes failed */ 
   2871         LOG_ERROR(BSL_LS_BCM_PORT,
   2872               (BSL_META_UP(unit, port,
   2873                "ERROR: u=%d p=%d interface type %d not supported by internal SERDES for this speed %d \n"),
   2874                unit, port, interface, config->speed));
   2875         _SOC_IF_ERR_EXIT(SOC_E_PARAM);    
   2876     }
   2877 
   2878 
   2879     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed,
   2880                             interface, interface_type));
   2881 
   2882 
   2883 exit:
   2884     SOC_FUNC_RETURN;
   2885 }
   2886 
   2887 int _pm4x25_phymod_interface_mode_set(int unit, int port,pm_info_t pm_info,
   2888                                    const portmod_port_interface_config_t *config,
   2889                                    phymod_phy_inf_config_t *phy_config,
   2890                                    int is_legacy_phy_callback)
   2891 {
   2892     int port_index = 0;
   2893     uint32 bitmap;
   2894     soc_port_if_t interface = SOC_PORT_IF_NULL;
   2895     SOC_INIT_FUNC_DEFS;
   2896 
   2897     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index,
   2898                                             &bitmap));
   2899     _SOC_IF_ERR_EXIT(PM4x25_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index));
   2900 
   2901     phy_config->interface_modes = config->interface_modes;
   2902 
   2903     /*
   2904      * tsce/tscf relies on the interface type and interface mode specified in phy_config
   2905      * to determine the exact interface type written into or read from the registers. For
   2906      * instance, SR4 and KR4 share the same speed ID (reg value) from TSCE's perspective
   2907      * and their difference is the medium type specified in the interface mode. SR4 is
   2908      * optical while KR4 is not. Below we prevent updating the medium type in the port
   2909      * mode provided to the internal PHY if phy_config is to be provided to the internal
   2910      * PHY in the legacy ext PHY callback scenario. Reason is because interface used in
   2911      * the function call below is meant for the outmost PHY instead of the internal PHY.
   2912      * portmod_port_phychain_interface_config_set() has a similar protection mechanism
   2913      * to change the medium type of the port mode based on internal PHY's interface type.
   2914      * However, that only works when the config property "serdes_if_type" is specified.
   2915      */
   2916     if (!is_legacy_phy_callback) {
   2917     _SOC_IF_ERR_EXIT(portmod_media_type_from_port_intf(unit, interface,
   2918                                                        phy_config));
   2919     }
   2920 exit:
   2921     SOC_FUNC_RETURN;
   2922 }
   2923 
   2924 STATIC
   2925 int _pm4x25_port_timestamp_adjust_wb_get(int unit, int port, pm_info_t pm_info,
   2926                                             int speed, portmod_port_ts_adjust_t *ts_adjust)
   2927 {
   2928     int rv = 0;
   2929     int port_index, adjust_index;
   2930     uint32_t bitmap;
   2931     portmod_port_ts_adjust_t port_ts_adjust;
   2932 
   2933     SOC_INIT_FUNC_DEFS;
   2934     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   2935                                              &bitmap));
   2936     for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM; adjust_index++) {
   2937          rv = PM4x25_PORT_TIME_STAMP_ADJUST_GET(unit, pm_info, &port_ts_adjust, adjust_index, port_index);
   2938          if ((port_ts_adjust.speed == speed) ||
   2939               (port_ts_adjust.speed == -1)) {
   2940              sal_memcpy(ts_adjust, &port_ts_adjust, sizeof(portmod_port_ts_adjust_t));
   2941              break;
   2942          }
   2943     }
   2944 
   2945     _SOC_IF_ERR_EXIT(rv);
   2946 exit:
   2947     SOC_FUNC_RETURN;
   2948 }
   2949 
   2950 int pm4x25_port_attach(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   2951 {
   2952     int port_index = -1, init_all=0;
   2953     int rv = 0, port_i, my_i, found_first_active_lane;
   2954     int phy, ii, nof_phys, fec_enable = 0;
   2955     int phys_count = 0, first_phy = -1, is_interface_restore;
   2956     uint32 pm_is_active = 0;
   2957     uint32 pm_is_bypassed = 0, port_dynamic_state;
   2958     portmod_pbmp_t port_phys_in_pm;
   2959     phymod_phy_init_config_t init_config;
   2960     phymod_phy_inf_config_t *phy_config = &init_config.interface;
   2961     portmod_access_get_params_t params;
   2962     phymod_phy_access_t phy_access[1+MAX_PHYN];
   2963     phymod_phy_access_t phy_access_lane;
   2964     portmod_port_ability_t port_ability;
   2965     const portmod_port_interface_config_t *config = &add_info->interface_config;
   2966     portmod_port_interface_config_t local_config = add_info->interface_config;
   2967     phymod_interface_t phymod_interface = phymodInterfaceCount;
   2968     soc_port_if_t local_default_interface;
   2969     int is_higig, itf_update = 0, usr_cfg_idx, three_ports_mode;
   2970     int adjust_index = 0;
   2971     pm_version_t pm_version;
   2972     uint32 interface_modes;
   2973     uint32 vsd_active_group[NUM_VSD_ACTIVE_GROUP_WORD]={0};
   2974     portmod_link_recovery_t link_recovery;
   2975     SOC_INIT_FUNC_DEFS;
   2976 
   2977     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &pm_is_bypassed);
   2978     _SOC_IF_ERR_EXIT(rv);
   2979 
   2980 
   2981     /* Get the first phy related to this port */
   2982     if (PM_4x25_INFO(pm_info)->in_pm12x10) {
   2983         port_index = 0;
   2984         rv = PM4x25_LANE2PORT_SET(unit, pm_info, port_index, port);
   2985         _SOC_IF_ERR_EXIT(rv);
   2986         PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, PM_4x25_INFO(pm_info)->first_phy){break;} /*just get first phy*/
   2987     } else {
   2988         PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   2989         PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x25_INFO(pm_info)->phys);
   2990         PORTMOD_PBMP_COUNT(port_phys_in_pm, phys_count);
   2991     
   2992         ii = 0;
   2993         PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy){
   2994             if(PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)){
   2995                 rv = PM4x25_LANE2PORT_SET(unit, pm_info, ii, port);
   2996                 _SOC_IF_ERR_EXIT(rv);
   2997                 first_phy = (first_phy == -1) ? phy : first_phy;
   2998                 port_index = (port_index == -1 ? ii : port_index);
   2999             }
   3000             ii++;
   3001         }
   3002         PM_4x25_INFO(pm_info)->first_phy = first_phy;
   3003     }
   3004 
   3005     if(port_index<0 || port_index>=PM4X25_LANES_PER_CORE) {
   3006         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   3007                            (_SOC_MSG("can't attach port %d. can't find relevant phy"), port));
   3008     }
   3009 
   3010     /* init data for port configuration */
   3011     rv = PM4x25_IS_HG_SET(unit, pm_info, add_info->init_config.is_hg, port_index);
   3012     _SOC_IF_ERR_EXIT(rv);
   3013 
   3014     rv = PM4x25_AN_MODE_SET(unit, pm_info, add_info->init_config.an_mode, port_index);
   3015     _SOC_IF_ERR_EXIT(rv);
   3016 
   3017     rv = PM4x25_FS_CL72_SET(unit, pm_info, add_info->init_config.fs_cl72, port_index);
   3018     _SOC_IF_ERR_EXIT(rv);
   3019 
   3020     rv = PM4x25_CX4_10G_SET(unit, pm_info, add_info->init_config.cx4_10g, port_index);
   3021     _SOC_IF_ERR_EXIT(rv);
   3022 
   3023     rv = PM4x25_AN_CL72_SET(unit, pm_info, add_info->init_config.an_cl72, port_index);
   3024     _SOC_IF_ERR_EXIT(rv);
   3025 
   3026     rv = PM4x25_AN_FEC_SET(unit, pm_info, add_info->init_config.an_fec, port_index);
   3027     _SOC_IF_ERR_EXIT(rv);
   3028 
   3029     rv = PM4x25_AN_MASTER_LANE_SET(unit, pm_info, add_info->init_config.an_master_lane, port_index);
   3030     _SOC_IF_ERR_EXIT(rv);
   3031 
   3032     rv = PM4x25_MAX_SPEED_SET(unit, pm_info, add_info->interface_config.max_speed, port_index);
   3033     _SOC_IF_ERR_EXIT(rv);
   3034 
   3035     rv = PM4x25_INTERFACE_TYPE_SET(unit, pm_info, add_info->interface_config.interface, port_index);
   3036     _SOC_IF_ERR_EXIT(rv);
   3037     
   3038     rv = PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, add_info->interface_config.interface, port_index);
   3039     _SOC_IF_ERR_EXIT(rv);
   3040 
   3041     rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, add_info->interface_config.interface_modes, port_index);
   3042     _SOC_IF_ERR_EXIT(rv);
   3043 
   3044     rv = PM4x25_PORT_PLL_DIVIDER_REQ_SET(unit, pm_info, add_info->init_config.pll_divider_req, port_index);
   3045     _SOC_IF_ERR_EXIT(rv);
   3046 
   3047     rv = PM4x25_PORT_1000X_AT_25G_SET(unit, pm_info, add_info->init_config.serdes_1000x_at_25g_vco, port_index);
   3048     _SOC_IF_ERR_EXIT(rv);
   3049 
   3050     rv = PM4x25_PORT_10G_AT_25G_SET(unit, pm_info, add_info->init_config.serdes_10g_at_25g_vco, port_index);
   3051     _SOC_IF_ERR_EXIT(rv);
   3052 
   3053     rv = PM4x25_CPRI_PORT_VSD_ACTIVE_GROUP_SET(unit, pm_info, vsd_active_group, port_index);
   3054     _SOC_IF_ERR_EXIT(rv);
   3055 
   3056     is_interface_restore = (add_info->interface_config.flags & PHYMOD_INTF_F_INTF_PARAM_SET_ONLY) ? 1 : 0 ;
   3057     rv = PM4x25_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, port_index);
   3058     _SOC_IF_ERR_EXIT(rv);
   3059 
   3060      for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM; adjust_index++) {
   3061           rv = PM4x25_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info,
   3062                                       &add_info->init_config.port_ts_adjust[adjust_index],
   3063                                       adjust_index, port_index);
   3064           _SOC_IF_ERR_EXIT(rv);
   3065      }
   3066 
   3067      link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK;
   3068      link_recovery.enabled = TRUE;
   3069      link_recovery.tick_cnt = 0;
   3070      rv = PM4x25_PORT_LINK_RECOVERY_SET(unit, pm_info, link_recovery, port_index);
   3071      _SOC_IF_ERR_EXIT(rv);
   3072 
   3073     if (PM_4x25_INFO(pm_info)->in_pm12x10) {
   3074         if (add_info->init_config.fw_load_method_overwrite == 1) {
   3075             PM_4x25_INFO(pm_info)->fw_load_method = phymodFirmwareLoadMethodNone;
   3076         }
   3077     } else {
   3078         if (add_info->init_config.polarity_overwrite == 1) {
   3079             sal_memcpy(&PM_4x25_INFO(pm_info)->polarity,
   3080                 &add_info->init_config.polarity[0], sizeof(phymod_polarity_t));
   3081         }
   3082         if (add_info->init_config.lane_map_overwrite == 1) {
   3083             sal_memcpy(&PM_4x25_INFO(pm_info)->lane_map,
   3084                 &add_info->init_config.lane_map[0], sizeof(phymod_lane_map_t));
   3085         }
   3086         if (add_info->init_config.fw_load_method_overwrite == 1) {
   3087             PM_4x25_INFO(pm_info)->fw_load_method =
   3088                 add_info->init_config.fw_load_method[0];
   3089         }
   3090     }
   3091 
   3092     if (add_info->init_config.ref_clk_overwrite == 1) {
   3093         PM_4x25_INFO(pm_info)->ref_clk = add_info->init_config.ref_clk;
   3094     }
   3095 
   3096     rv = PM4x25_IS_ACTIVE_GET(unit, pm_info, &pm_is_active);
   3097     _SOC_IF_ERR_EXIT(rv);
   3098 
   3099     init_all = (!PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) &&
   3100                 !PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) &&
   3101                 !PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) ? 1 : 0;
   3102 
   3103 
   3104     if (!PORTMOD_PORT_ADD_F_AUTONEG_CONFIG_SKIP_GET(add_info))
   3105     {
   3106         /* update an information before proceeding further */
   3107         SOC_IF_ERROR_RETURN(_pm4x25_an_mode_update (unit, port, pm_info, port_index, add_info->interface_config.port_num_lanes, add_info->init_config.an_cl73));
   3108     }
   3109 
   3110     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   3111 
   3112     /* if not active - initalize PM */
   3113     if(!pm_is_active){
   3114         if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) || (init_all)) {
   3115             three_ports_mode = (add_info->init_config.port_mode_aux_info == portmodModeInfoThreePorts) ? 1 : 0;
   3116             rv = PM4x25_THREE_PORTS_MODE_SET(unit, pm_info, three_ports_mode);
   3117             _SOC_IF_ERR_EXIT(rv);
   3118 
   3119             /*init the PM*/
   3120             rv = _pm4x25_pm_enable(unit, port, pm_info, port_index, add_info, 1);
   3121             _SOC_IF_ERR_EXIT(rv);
   3122         }
   3123 
   3124         pm_is_active = 1;
   3125 
   3126         if(PORTMOD_PM4x25_IS_GEN3_28nm(pm_version)){
   3127             /* Set tsc and fclk */
   3128            _SOC_IF_ERR_EXIT(_pm4x25_pm_ext_tsc_clk_set(unit, port, pm_info, add_info));
   3129         }
   3130 
   3131         rv = PM4x25_IS_ACTIVE_SET(unit, pm_info, pm_is_active);
   3132         _SOC_IF_ERR_EXIT(rv);
   3133     }
   3134 
   3135 
   3136     if ((pm_is_active) && (PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)) &&
   3137         (PM_4x25_INFO(pm_info)->int_core_access.type == phymodDispatchTypeInvalid)){
   3138         _SOC_IF_ERR_EXIT(_pm4x25_pm_ext_tsc_clk_set(unit, port, pm_info, add_info));
   3139     }
   3140 
   3141     /* probe core internal serdes and ext phys if there is any. */
   3142     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] > 0){
   3143         /* only at  CORE PROBE phase need probe */
   3144         if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) || init_all) {
   3145             rv = _pm4x25_pm_core_probe(unit, port, pm_info, add_info);
   3146             _SOC_IF_ERR_EXIT(rv);
   3147         }
   3148     }
   3149 
   3150     if (!(PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) && 
   3151         (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info))) {
   3152         return (rv);
   3153     }
   3154 
   3155     /* probe core and core config internal serdes and ext phys if there is any. */
   3156     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] > 0 ){
   3157         rv = _pm4x25_pm_core_init(unit, port, pm_info, add_info, 1);
   3158         _SOC_IF_ERR_EXIT(rv);
   3159     }
   3160 
   3161     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   3162         return (rv);
   3163     }
   3164 
   3165     /* initalize port */
   3166     rv = _pm4x25_pm_port_init(unit, port, pm_info, port_index, add_info, 1);
   3167     _SOC_IF_ERR_EXIT(rv);
   3168 
   3169     /* initialze phys */
   3170     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] > 0) {
   3171 
   3172         _SOC_IF_ERR_EXIT(phymod_phy_init_config_t_init(&init_config));
   3173         _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   3174 
   3175         params.phyn = 0;
   3176         _SOC_IF_ERR_EXIT(pm4x25_port_phy_lane_access_get(unit, port, pm_info,
   3177                                     &params, 1, &phy_access_lane, &nof_phys, NULL));
   3178 
   3179         init_config.an_en = add_info->autoneg_en;
   3180         init_config.cl72_en = add_info->link_training_en;
   3181         init_config.op_mode = add_info->interface_config.port_op_mode;
   3182 
   3183         _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   3184                                                            phy_access ,(1+MAX_PHYN),
   3185                                                            &nof_phys));
   3186 
   3187         my_i = 0, usr_cfg_idx = 0;
   3188         found_first_active_lane = 0;
   3189         for(ii=0 ; ii<PM4X25_LANES_PER_CORE ; ii++) {
   3190             rv = PM4x25_LANE2PORT_GET(unit, pm_info, ii, &port_i);
   3191             _SOC_IF_ERR_EXIT(rv);
   3192 
   3193             if(port_i != port) {
   3194                 /* There is a difference between XGS and DNX devices. For DNX, a port can consist inconsecutive physical lanes.
   3195                  * For example, a port can consist lane 1 and 3 of the same core. For XGS, on the other hand, a port always consist
   3196                  * consecutive physical lanes. Therefore my_i below needs not be incremented for XGS devices.
   3197                  */
   3198                 if(PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy_access[0].device_op_mode) && found_first_active_lane){
   3199                     my_i++;
   3200                 }
   3201                 continue;
   3202             } else{
   3203                 found_first_active_lane = 1;
   3204             }
   3205 
   3206             if(SHR_BITGET(&(PM_4x25_INFO(pm_info)->polarity.tx_polarity),ii)) {
   3207                 SHR_BITSET(&init_config.polarity.tx_polarity, my_i);
   3208             }
   3209 
   3210             if(SHR_BITGET(&(PM_4x25_INFO(pm_info)->polarity.rx_polarity),ii)) {
   3211                 SHR_BITSET(&init_config.polarity.rx_polarity, my_i);
   3212             }
   3213 
   3214             _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(&phy_access_lane, phymodMediaTypeChipToChip, &init_config.tx[my_i]));
   3215 
   3216             if (PORTMOD_USER_SET_TX_PREEMPHASIS_BY_CONFIG_GET(add_info->init_config.tx_params_user_flag[usr_cfg_idx])) {
   3217                 init_config.tx[my_i].pre = add_info->init_config.tx_params[usr_cfg_idx].pre;
   3218                 init_config.tx[my_i].main = add_info->init_config.tx_params[usr_cfg_idx].main;
   3219                 init_config.tx[my_i].post = add_info->init_config.tx_params[usr_cfg_idx].post;
   3220             }
   3221 
   3222             if (PORTMOD_USER_SET_TX_AMP_BY_CONFIG_GET(add_info->init_config.tx_params_user_flag[usr_cfg_idx])) {
   3223                 init_config.tx[my_i].amp = add_info->init_config.tx_params[usr_cfg_idx].amp;
   3224             }
   3225 
   3226             if (PORTMOD_USER_SET_TX_PREEMPHASIS_BY_CONFIG_GET(add_info->init_config.tx_params_user_flag[usr_cfg_idx])
   3227                 || PORTMOD_USER_SET_TX_AMP_BY_CONFIG_GET(add_info->init_config.tx_params_user_flag[usr_cfg_idx])) {
   3228                 port_dynamic_state = 0;
   3229                 PORTMOD_PORT_DEFAULT_TX_PARAMS_UPDATED_SET(port_dynamic_state);
   3230 
   3231                 PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info, port_dynamic_state, port_index);
   3232             }
   3233 
   3234             usr_cfg_idx++;
   3235             my_i++;
   3236             
   3237         }
   3238 
   3239         phy_config->data_rate = config->speed;
   3240         phy_config->pll_divider_req = add_info->init_config.pll_divider_req;
   3241         phy_config->ref_clock = PM_4x25_INFO(pm_info)->ref_clk;
   3242 
   3243         _SOC_IF_ERR_EXIT(_pm4x25_line_side_phymod_interface_get(unit, port, pm_info, PORTMOD_INIT_F_ALL_PHYS, config, &phymod_interface));
   3244         phy_config->interface_type = phymod_interface;
   3245         _SOC_IF_ERR_EXIT(_pm4x25_phymod_interface_mode_set(unit, port, pm_info, config, phy_config, 0));
   3246         rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   3247         _SOC_IF_ERR_EXIT(rv);
   3248         if (PHYMOD_INTF_MODES_FIBER_GET(phy_config)) {
   3249             interface_modes &= ~(PHYMOD_INTF_MODES_COPPER | PHYMOD_INTF_MODES_BACKPLANE);
   3250             interface_modes |= PHYMOD_INTF_MODES_FIBER;
   3251         } else if (PHYMOD_INTF_MODES_COPPER_GET(phy_config)){
   3252             interface_modes &= ~(PHYMOD_INTF_MODES_FIBER | PHYMOD_INTF_MODES_BACKPLANE);
   3253             interface_modes |= PHYMOD_INTF_MODES_COPPER;
   3254         } else if (PHYMOD_INTF_MODES_BACKPLANE_GET(phy_config)){
   3255             interface_modes &= ~(PHYMOD_INTF_MODES_COPPER | PHYMOD_INTF_MODES_FIBER);
   3256             interface_modes |= PHYMOD_INTF_MODES_BACKPLANE;
   3257         }
   3258         rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   3259         _SOC_IF_ERR_EXIT(rv);
   3260  
   3261         _SOC_IF_ERR_EXIT(portmod_port_phychain_phy_init(unit, phy_access, nof_phys,
   3262                                                             &init_config));
   3263     }
   3264 
   3265     /* enable fec if set, should be done before setting the speed */
   3266     fec_enable = add_info->init_config.serdes_fec_enable;
   3267 
   3268     if (fec_enable) {
   3269         int value = 0;
   3270 
   3271         if ((fec_enable != PORTMOD_PORT_FEC_CL91) &&
   3272             (fec_enable != PORTMOD_PORT_FEC_CL74) &&
   3273             (fec_enable != PORTMOD_PORT_FEC_CL108)) {
   3274             return (SOC_E_PARAM);
   3275         }
   3276 
   3277         if (fec_enable == PORTMOD_PORT_FEC_CL91) {
   3278             PHYMOD_FEC_CL91_SET(value);
   3279         } else if (fec_enable == PORTMOD_PORT_FEC_CL108) {
   3280             PHYMOD_FEC_CL108_SET(value);
   3281         }
   3282 
   3283         value |= TRUE;
   3284         rv = portmod_port_fec_enable_set(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, value);
   3285         _SOC_IF_ERR_EXIT(rv);
   3286     }
   3287 
   3288     /* The default interface type given by add_info is filled by soc_esw_portctrl_config_get()
   3289      * and should be updated here locally since soc_esw_portctrl_config_get() only gives coarse-
   3290      * grained default interface type without considering whether the underlying device is
   3291      * pm4x10 or pm4x25, with or without ext PHY, etc.
   3292      */
   3293     if (nof_phys == 1) {
   3294         if (config->serdes_interface != SOC_PORT_IF_NULL) {
   3295             _SOC_IF_ERR_EXIT(_pm4x25_interface_check(unit, port, config, config->serdes_interface, &itf_update));
   3296             if (itf_update) {
   3297                 local_config.interface = config->serdes_interface;
   3298             }
   3299         }
   3300 
   3301     is_higig = ((config->encap_mode == SOC_ENCAP_HIGIG2) ||
   3302                (config->encap_mode == SOC_ENCAP_HIGIG) ||
   3303                PHYMOD_INTF_MODES_HIGIG_GET(config)) ? 1 : 0;
   3304 
   3305         if ((config->speed == 42000 || config->speed == 40000) && is_higig && !itf_update) {
   3306         local_default_interface = SOC_PORT_IF_NULL;
   3307         _SOC_IF_ERR_EXIT(
   3308                 pm4x25_port_default_interface_get(unit, port, pm_info, config,
   3309                                                   &local_default_interface));
   3310         if(local_default_interface != SOC_PORT_IF_NULL){
   3311             local_config.interface = local_default_interface;
   3312                 itf_update = 1;
   3313             }
   3314         }
   3315 
   3316         if (itf_update) {
   3317             _SOC_IF_ERR_EXIT(
   3318                 PM4x25_INTERFACE_TYPE_SET(unit, pm_info, local_config.interface, port_index));
   3319             _SOC_IF_ERR_EXIT(
   3320                 PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, local_config.interface, port_index));
   3321         }
   3322     }
   3323     if (add_info->init_config.cpm_core_mode == portmodCpmMixEthCpri) {
   3324         local_config.flags |= PHYMOD_INTF_F_SINGLE_PLL_ONLY;
   3325     }
   3326     rv = pm4x25_port_interface_config_set(unit, port, pm_info, &local_config, PORTMOD_INIT_F_ALL_PHYS);
   3327     _SOC_IF_ERR_EXIT(rv);
   3328 
   3329     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] > 0) {
   3330         if(add_info->init_config.fs_cl72) {
   3331             /* config port_init_cl72 is used to enable fs cl72 only in the serdes,
   3332              * do not enable cl72 on external phys. Set the no of phys argument to
   3333              * 1 to avoid setting cl72 enable on ext phys
   3334              */
   3335             _SOC_IF_ERR_EXIT(portmod_port_phychain_cl72_set(unit, port, phy_access, 1, 1));
   3336         }
   3337     }
   3338 
   3339     if(!(PM_4x25_INFO(pm_info)->in_pm12x10)) {
   3340         /* set the default advert ability */
   3341         _SOC_IF_ERR_EXIT
   3342             (pm4x25_port_ability_local_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &port_ability));
   3343         _SOC_IF_ERR_EXIT
   3344             (pm4x25_port_ability_advert_set(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &port_ability));
   3345     }
   3346 
   3347     if (PORTMOD_PM4x25_IS_GEN3_28nm(pm_version) || PORTMOD_CPM4x25_IS_GEN3_28nm(pm_version)) {
   3348         /* Set PMD TXPI mode */
   3349         _SOC_IF_ERR_EXIT(_pm4x25_port_phy_txpi_mode_set(unit, port, pm_info, add_info->init_config.txpi_mode));
   3350     }
   3351 
   3352     /* De-Assert SOFT_RESET */
   3353     _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 0));
   3354     
   3355     
   3356 exit:
   3357     SOC_FUNC_RETURN;   
   3358 }
   3359 
   3360 int pm4x25_port_detach(int unit, int port, pm_info_t pm_info)
   3361 {
   3362     int enable; 
   3363     int invalid_port = -1;
   3364     int tmp_port;
   3365     int i = 0, flags = 0;
   3366     int rv = 0;
   3367     int is_last_one = TRUE;
   3368     int port_index = -1;
   3369     int phytype = 0, nof_phys;
   3370     uint32 inactive = 0;
   3371     phymod_phy_access_t serdes_acc;
   3372     portmod_access_get_params_t params;
   3373     phymod_phy_reset_t phy_reset;
   3374     SOC_INIT_FUNC_DEFS;
   3375 
   3376     if (PM_4x25_INFO(pm_info)->nof_phys[0] == 0) {
   3377         /* There are no phys.., so only mac needs to be checked */
   3378         PORTMOD_PORT_ENABLE_MAC_SET(flags);
   3379     } 
   3380 
   3381     _SOC_IF_ERR_EXIT(pm4x25_port_enable_get(unit, port, pm_info, flags, &enable));
   3382     if(enable){
   3383         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("can't detach active port %d"), port));
   3384     }
   3385     
   3386     if (!PM_4x25_INFO(pm_info)->in_pm12x10) {
   3387         _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   3388         params.phyn = 0;
   3389         _SOC_IF_ERR_EXIT(pm4x25_port_phy_lane_access_get(unit, port, pm_info,
   3390                                                      &params, 1, &serdes_acc, &nof_phys, NULL));
   3391     }
   3392 
   3393     /*remove from array and check if it was the last one*/
   3394     for( i = 0 ; i < MAX_PORTS_PER_PM4X25; i++){
   3395         rv = PM4x25_LANE2PORT_GET(unit, pm_info, i, &tmp_port);
   3396         _SOC_IF_ERR_EXIT(rv);
   3397         if(tmp_port == port){
   3398             port_index = (port_index == -1 ? i : port_index);
   3399             rv = PM4x25_LANE2PORT_SET(unit, pm_info, i, invalid_port);
   3400             _SOC_IF_ERR_EXIT(rv);
   3401         } else if (tmp_port != -1){
   3402             is_last_one = FALSE;
   3403         }
   3404     }
   3405 
   3406     if ((PM_4x25_INFO(pm_info)->nof_phys[0]) && (port_index == -1))  {
   3407         _SOC_EXIT_WITH_ERR(SOC_E_PORT, (_SOC_MSG("Port %d wasn't found"), port));
   3408     }   
   3409 
   3410     rv = _pm4x25_pm_port_init(unit, port, pm_info, port_index, NULL, 0);
   3411     _SOC_IF_ERR_EXIT(rv);
   3412 
   3413     if (!PM_4x25_INFO(pm_info)->in_pm12x10 && (PM_4x25_INFO(pm_info)->int_core_access.type == phymodDispatchTypeTscf16)) {
   3414         phymod_phy_reset_t_init(&phy_reset);
   3415         _SOC_IF_ERR_EXIT(phymod_phy_reset_set(&serdes_acc, &phy_reset));
   3416     }
   3417 
   3418     /*deinit PM in case of last one*/
   3419     if(is_last_one){
   3420        rv = _pm4x25_pm_enable(unit, port, pm_info, port_index, NULL, 0);
   3421        _SOC_IF_ERR_EXIT(rv);
   3422 
   3423        PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_CLR(PM_4x25_INFO(pm_info)->int_core_access.device_op_mode);
   3424 
   3425        rv = PM4x25_IS_ACTIVE_SET(unit, pm_info, inactive);
   3426        _SOC_IF_ERR_EXIT(rv);
   3427 
   3428        rv = PM4x25_IS_INITIALIZED_SET(unit, pm_info, inactive);
   3429        _SOC_IF_ERR_EXIT(rv);
   3430 
   3431        rv = PM4x25_IS_BYPASSED_SET(unit, pm_info, inactive);
   3432        _SOC_IF_ERR_EXIT(rv);
   3433 
   3434        /* Updating phymod type in pm_info structure and warmboot engine */
   3435        phytype = phymodDispatchTypeInvalid;
   3436        rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phy_type], &phytype, 0);
   3437        _SOC_IF_ERR_EXIT(rv);
   3438        PM_4x25_INFO(pm_info)->int_core_access.type = phymodDispatchTypeInvalid;
   3439 
   3440     }    
   3441 
   3442 exit:
   3443     SOC_FUNC_RETURN;
   3444 }
   3445 
   3446 int pm4x25_port_replace(int unit, int port, pm_info_t pm_info, int new_port)
   3447 {
   3448     int i, tmp_port;
   3449     int rv = 0;       
   3450     SOC_INIT_FUNC_DEFS;
   3451     
   3452 
   3453     /* replace old port with new port */
   3454     for(i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
   3455         rv = PM4x25_LANE2PORT_GET(unit, pm_info, i, &tmp_port);
   3456         _SOC_IF_ERR_EXIT(rv);
   3457         if (tmp_port == port) {
   3458             rv = PM4x25_LANE2PORT_SET(unit, pm_info, i, new_port);
   3459             _SOC_IF_ERR_EXIT(rv);
   3460         }
   3461     }
   3462 
   3463 exit:
   3464     SOC_FUNC_RETURN; 
   3465     
   3466 }
   3467 
   3468 int pm4x25_pm_bypass_set(int unit, pm_info_t pm_info, int bypass_enable)
   3469 {
   3470     int rv = 0, bypass_enable_get;
   3471     uint32 pm_is_active = 0;
   3472     SOC_INIT_FUNC_DEFS;
   3473 
   3474     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &bypass_enable_get);
   3475     _SOC_IF_ERR_EXIT(rv);
   3476 
   3477     if (bypass_enable_get != bypass_enable) {
   3478         rv = PM4x25_IS_ACTIVE_GET(unit, pm_info, &pm_is_active);
   3479         _SOC_IF_ERR_EXIT(rv);
   3480 
   3481         if(pm_is_active) {
   3482             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("can't chenge bypass mode for active pm")));
   3483         }
   3484 
   3485         rv = PM4x25_IS_BYPASSED_SET(unit, pm_info, bypass_enable);
   3486         _SOC_IF_ERR_EXIT(rv);
   3487     }
   3488     
   3489 exit:
   3490     SOC_FUNC_RETURN; 
   3491     
   3492 }
   3493 
   3494 int pm4x25_pm_core_info_get(int unit, pm_info_t pm_info, int phyn, portmod_pm_core_info_t* core_info)
   3495 {   
   3496     SOC_INIT_FUNC_DEFS;
   3497     
   3498     if(PM_4x25_INFO(pm_info)->in_pm12x10){
   3499         _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("core access get cannot be called for PM4X25 which is part of PM12X10")));
   3500     }
   3501 
   3502     if(phyn >= PM_4x25_INFO(pm_info)->nof_phys[0]){ 
   3503         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("phyn exceeded. max allowed %d. got %d"), PM_4x25_INFO(pm_info)->nof_phys[0]-1, phyn));
   3504     }
   3505     if(phyn < 0) {
   3506         phyn = PM_4x25_INFO(pm_info)->nof_phys[0] - 1; /* last one */
   3507     }
   3508     core_info->ref_clk = PM_4x25_INFO(pm_info)->ref_clk;
   3509     sal_memcpy(&core_info->lane_map, &(PM_4x25_INFO(pm_info)->lane_map), sizeof(phymod_lane_map_t));
   3510 
   3511 exit:
   3512     SOC_FUNC_RETURN; 
   3513 }
   3514 
   3515 int pm4x25_pm_phys_get(int unit, pm_info_t pm_info, portmod_pbmp_t* phys)
   3516 {
   3517 	SOC_INIT_FUNC_DEFS;
   3518 	PORTMOD_PBMP_ASSIGN(*phys, PM_4x25_INFO(pm_info)->phys);
   3519 	SOC_FUNC_RETURN;
   3520 }
   3521 
   3522 int pm4x25_port_enable_set(int unit, int port, pm_info_t pm_info, int flags, int enable)
   3523 {
   3524 
   3525     uint32 is_bypassed = 0, phychain_flag;  
   3526     int rv = 0, rst_flags = 0;
   3527     int actual_flags = flags;
   3528     phymod_phy_access_t phy_access[1+MAX_PHYN];
   3529     phymod_phy_power_t phy_power; 
   3530     int nof_phys = 0, clmac_flags = 0;
   3531     SOC_INIT_FUNC_DEFS;
   3532 
   3533 
   3534     /* If no RX\TX flags - set both*/
   3535     if((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && (!PORTMOD_PORT_ENABLE_RX_GET(flags))){
   3536         PORTMOD_PORT_ENABLE_RX_SET(actual_flags);
   3537         PORTMOD_PORT_ENABLE_TX_SET(actual_flags);
   3538     }
   3539 
   3540     /* if no MAC\Phy flags - set both*/
   3541     if((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) && (!PORTMOD_PORT_ENABLE_MAC_GET(flags))){
   3542         PORTMOD_PORT_ENABLE_PHY_SET(actual_flags);
   3543         PORTMOD_PORT_ENABLE_MAC_SET(actual_flags);
   3544     }
   3545 
   3546      /* if MAC is set and either RX or TX set is invalid combination */
   3547     if( (PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) ) {
   3548         if((!PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) || (!PORTMOD_PORT_ENABLE_RX_GET(actual_flags))){
   3549             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("MAC RX and TX can't be enabled separately")));
   3550         }
   3551     }
   3552     /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/
   3553     phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 
   3554         PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 
   3555         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ;
   3556 
   3557     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &is_bypassed);
   3558     _SOC_IF_ERR_EXIT(rv);
   3559 
   3560     _SOC_IF_ERR_EXIT(phymod_phy_power_t_init(&phy_power));
   3561     phy_power.rx = phymodPowerNoChange;
   3562     phy_power.tx = phymodPowerNoChange;
   3563 
   3564     if(PORTMOD_PORT_ENABLE_RX_GET(actual_flags)){
   3565         phy_power.rx = (enable) ? phymodPowerOn : phymodPowerOff;
   3566         clmac_flags |= CLMAC_ENABLE_SET_FLAGS_RX_EN;
   3567     }
   3568     if(PORTMOD_PORT_ENABLE_TX_GET(actual_flags)){
   3569         phy_power.tx = (enable) ? phymodPowerOn : phymodPowerOff;
   3570         clmac_flags |= CLMAC_ENABLE_SET_FLAGS_TX_EN;
   3571     }
   3572 
   3573     if(enable){
   3574         if((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!is_bypassed)){
   3575             if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   3576                 rst_flags |= CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
   3577             }
   3578             rv = clmac_enable_set(unit, port, rst_flags, 1);
   3579             _SOC_IF_ERR_EXIT(rv);
   3580             if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   3581                 _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 0));
   3582             }
   3583         }
   3584         if((PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) && (!(PM_4x25_INFO(pm_info)->in_pm12x10))){
   3585             _SOC_IF_ERR_EXIT
   3586                 (portmod_port_chain_phy_access_get(unit, port, pm_info,
   3587                                                   phy_access ,(1+MAX_PHYN),
   3588                                                   &nof_phys));
   3589 
   3590             _SOC_IF_ERR_EXIT (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power));
   3591 
   3592                 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   3593                 _SOC_IF_ERR_EXIT
   3594                     (portmod_port_phychain_tx_lane_control_set(unit, port,  phy_access, nof_phys, phychain_flag,
   3595                                                            phymodTxSquelchOff));
   3596                 }
   3597                 if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   3598                 _SOC_IF_ERR_EXIT
   3599                     (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag,
   3600                                                           phymodRxSquelchOff));
   3601                 }
   3602             }
   3603 
   3604     }
   3605     else{
   3606         if((PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) && (!(PM_4x25_INFO(pm_info)->in_pm12x10))){
   3607 
   3608             _SOC_IF_ERR_EXIT
   3609                 (portmod_port_chain_phy_access_get(unit, port, pm_info,
   3610                                                   phy_access ,(1+MAX_PHYN),
   3611                                                   &nof_phys));
   3612 
   3613                 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   3614                 _SOC_IF_ERR_EXIT
   3615                     (portmod_port_phychain_tx_lane_control_set(unit, port,  phy_access, nof_phys, phychain_flag, 
   3616                                                            phymodTxSquelchOn));
   3617                 }
   3618                 if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   3619                 _SOC_IF_ERR_EXIT
   3620                     (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag, 
   3621                                                           phymodRxSquelchOn));  
   3622                 }
   3623 
   3624             _SOC_IF_ERR_EXIT (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power));
   3625         }  
   3626         if((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags))  && (!is_bypassed)){
   3627             rv = clmac_enable_set(unit, port, clmac_flags, 0);
   3628             _SOC_IF_ERR_EXIT(rv);
   3629         }
   3630     }
   3631         
   3632 exit:
   3633     SOC_FUNC_RETURN; 
   3634     
   3635 }
   3636 
   3637 int pm4x25_port_enable_get(int unit, int port, pm_info_t pm_info, int flags, int* enable)
   3638 {
   3639     phymod_phy_access_t phy_access[1+MAX_PHYN];
   3640     int nof_phys = 0;
   3641     phymod_phy_tx_lane_control_t tx_control = phymodTxSquelchOn;
   3642     phymod_phy_rx_lane_control_t rx_control = phymodRxSquelchOn;
   3643     int phy_enable = 1, mac_enable = 1;
   3644     int mac_rx_enable = 0, mac_tx_enable = 0;
   3645     uint32 is_bypassed = 0, phychain_flag;
   3646     int rv;
   3647     int actual_flags = flags;
   3648     SOC_INIT_FUNC_DEFS;
   3649     SOC_NULL_CHECK(pm_info);
   3650 
   3651     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &is_bypassed);
   3652     _SOC_IF_ERR_EXIT(rv);
   3653 
   3654     /* If no RX\TX flags - set both*/
   3655     if((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && (!PORTMOD_PORT_ENABLE_RX_GET(flags))){
   3656         PORTMOD_PORT_ENABLE_RX_SET(actual_flags);
   3657         PORTMOD_PORT_ENABLE_TX_SET(actual_flags);
   3658     }
   3659 
   3660     /* if no MAC\Phy flags - set both*/
   3661     if((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) && (!PORTMOD_PORT_ENABLE_MAC_GET(flags))){
   3662         PORTMOD_PORT_ENABLE_PHY_SET(actual_flags);
   3663         PORTMOD_PORT_ENABLE_MAC_SET(actual_flags);
   3664     }
   3665 
   3666     /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/
   3667     phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 
   3668         PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 
   3669         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ;
   3670 
   3671     if (PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) {
   3672 
   3673         _SOC_IF_ERR_EXIT
   3674             (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys));
   3675 
   3676         _SOC_IF_ERR_EXIT
   3677             (portmod_port_phychain_tx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &tx_control));
   3678         _SOC_IF_ERR_EXIT
   3679             (portmod_port_phychain_rx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &rx_control));
   3680 
   3681         phy_enable = 0;
   3682 
   3683         if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   3684             phy_enable |= (rx_control == phymodRxSquelchOn) ? 0 : 1;
   3685         } 
   3686         if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   3687             phy_enable |= (tx_control == phymodTxSquelchOn) ? 0 : 1;
   3688         }
   3689     }
   3690 
   3691     if ((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!is_bypassed)) {
   3692 
   3693         mac_enable = 0;
   3694 
   3695         if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   3696             _SOC_IF_ERR_EXIT(clmac_enable_get(unit, port, CLMAC_ENABLE_SET_FLAGS_RX_EN, &mac_rx_enable));
   3697             mac_enable |= (mac_rx_enable) ? 1 : 0;
   3698         }
   3699         if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   3700             _SOC_IF_ERR_EXIT(clmac_enable_get(unit, port, CLMAC_ENABLE_SET_FLAGS_TX_EN, &mac_tx_enable));
   3701             mac_enable |= (mac_tx_enable) ? 1 : 0;
   3702         }
   3703     }
   3704 
   3705     *enable = (mac_enable && phy_enable); 
   3706 
   3707 exit:
   3708     SOC_FUNC_RETURN; 
   3709     
   3710 }
   3711 
   3712 int pm4x25_port_interface_check(int unit, int port, pm_info_t pm_info,
   3713                                 const portmod_port_interface_config_t* config,
   3714                                 int is_ext_phy, soc_port_if_t interface,
   3715                                 int* is_valid)
   3716 {
   3717     int nof_phys = 0;
   3718     phymod_phy_access_t phy_access[1+MAX_PHYN];
   3719     SOC_INIT_FUNC_DEFS;
   3720 
   3721     _SOC_IF_ERR_EXIT
   3722         (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys));
   3723 
   3724     if (is_ext_phy && nof_phys < 2) {
   3725         return SOC_E_PARAM;
   3726     }
   3727 
   3728     if (is_ext_phy) {
   3729         _SOC_IF_ERR_EXIT(_pm4x25_ext_phy_interface_check(unit, port, pm_info, &phy_access[nof_phys-1],
   3730                                                          config, interface, is_valid));
   3731     } else {
   3732         _SOC_IF_ERR_EXIT(_pm4x25_interface_check(unit, port, config, interface, is_valid));
   3733     }
   3734 
   3735 exit:
   3736     SOC_FUNC_RETURN;
   3737 }
   3738 
   3739 int pm4x25_port_interface_config_set(int unit, int port, pm_info_t pm_info, 
   3740                                      const portmod_port_interface_config_t* config,
   3741                                      int phy_init_flags)
   3742 {
   3743     uint32 pm_is_bypassed = 0;
   3744     phymod_phy_inf_config_t phy_config, cur_phy_config;
   3745     phymod_phy_access_t phy_access[1+MAX_PHYN];
   3746     int nof_phys = 0;
   3747     int rv = 0, flags = 0;
   3748     int port_index=0;
   3749     int is_higig = 0;
   3750     uint32 bitmap;
   3751     uint32 is_interface_restore, interface_modes;
   3752     soc_port_if_t interface = SOC_PORT_IF_NULL;
   3753     phymod_interface_t   phymod_serdes_interface = phymodInterfaceCount;
   3754     phymod_interface_t   phymod_interface = phymodInterfaceCount;
   3755     phymod_tx_t updated_tx_params[PHYMOD_MAX_LANES_PER_CORE];
   3756     int is_legacy_phy_callback = 0, i;
   3757     portmod_port_ts_adjust_t ts_adjust;
   3758     int pll_divider_req = 0;
   3759     int serdes_10g_at_25g_vco = 0;
   3760     int serdes_1000x_at_25g_vco = 0;
   3761     pm_version_t pm_version;
   3762     uint32 port_dynamic_state;
   3763     int mac_ts_enable;
   3764     SOC_INIT_FUNC_DEFS;
   3765 
   3766     sal_memset(&ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   3767 
   3768     rv = PM4x25_IS_BYPASSED_GET(unit, pm_info, &pm_is_bypassed);
   3769     _SOC_IF_ERR_EXIT(rv);
   3770 
   3771     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   3772     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   3773     _SOC_IF_ERR_EXIT(PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info, &port_dynamic_state, port_index));
   3774     if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, CLMAC_TS_DISABLEf)) {
   3775         _SOC_IF_ERR_EXIT
   3776                 (pm4x25_port_mac_timestamp_enable_get(unit, port, pm_info, &mac_ts_enable));
   3777     } else {
   3778         mac_ts_enable = 1;
   3779     }
   3780 
   3781     if (config->flags & PHYMOD_INTF_F_UPDATE_SPEED_LINKUP) {
   3782         int serdes_speed = 0, mac_only = 0;
   3783 
   3784         _SOC_IF_ERR_EXIT(portmod_port_speed_get(unit, port, &serdes_speed));
   3785         if (config->speed == serdes_speed) {
   3786             mac_only = 1;
   3787         }
   3788 
   3789         flags = CLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   3790         _SOC_IF_ERR_EXIT(clmac_speed_set(unit, port, flags, config->speed));
   3791 
   3792         if (mac_ts_enable) {
   3793             /*Set MAC Timestamp Delay*/
   3794             if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   3795                 _SOC_IF_ERR_EXIT(_pm4x25_port_timestamp_adjust_wb_get(unit, port, pm_info, config->speed, &ts_adjust));
   3796                 _SOC_IF_ERR_EXIT(clmac_timestamp_delay_set(unit, port, ts_adjust));
   3797             }
   3798             /* PM VERSION and CLMAC BYTE ADJUST aren't valid before TH2 */
   3799             if (!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   3800                 _SOC_IF_ERR_EXIT(clmac_timestamp_byte_adjust_set(unit, port, 0, config->speed));
   3801             }
   3802         }
   3803         if (mac_only) {
   3804             /* line side speed and SerDes speed are equal, no need update SerDes configuration */
   3805             SOC_FUNC_RETURN;
   3806         }
   3807 
   3808         phy_init_flags = PORTMOD_INIT_F_ALL_PHYS;
   3809     }
   3810 
   3811 
   3812     if(!(PM_4x25_INFO(pm_info)->in_pm12x10)) {
   3813         _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   3814                                          &bitmap));
   3815         if ((config->encap_mode == SOC_ENCAP_HIGIG2) ||
   3816             (config->encap_mode == SOC_ENCAP_HIGIG)  ||
   3817             (PHYMOD_INTF_MODES_HIGIG_GET(config))) {
   3818             rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   3819             _SOC_IF_ERR_EXIT(rv);
   3820             interface_modes |= PHYMOD_INTF_MODES_HIGIG;
   3821             rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   3822             _SOC_IF_ERR_EXIT(rv);
   3823         } else if ((config->encap_mode == SOC_ENCAP_IEEE)) {
   3824             rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   3825             _SOC_IF_ERR_EXIT(rv);
   3826             interface_modes &= ~PHYMOD_INTF_MODES_HIGIG;
   3827             rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   3828             _SOC_IF_ERR_EXIT(rv);
   3829         }
   3830 
   3831         /* Will skip when init, only called when executing command "port xe<n> if=xxxx" */
   3832         if (config->flags & PHYMOD_INTF_F_INTF_PARAM_SET_ONLY) {
   3833             /* only flag saved by interface_config->flags */
   3834             interface = config->interface;
   3835 
   3836             /* Update the software state of the interface type. Note that currently
   3837              * the legacy ext PHY does not raise the PHYMOD_INTF_F_INTF_PARAM_SET_ONLY
   3838              * flag so that the following function call cannot be reached when a legacy
   3839              * ext PHY uses the portmod callback function to set the interface type
   3840              * of the internal PHY.
   3841              */
   3842                 rv = PM4x25_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index);
   3843                 _SOC_IF_ERR_EXIT(rv);
   3844 
   3845                 is_interface_restore = 1;
   3846                 rv = PM4x25_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, port_index);
   3847                 _SOC_IF_ERR_EXIT(rv);
   3848 
   3849             SOC_FUNC_RETURN;
   3850         }
   3851 
   3852         rv = PM4x25_IS_INTERFACE_RESTORE_GET(unit, pm_info, &is_interface_restore, port_index);
   3853         _SOC_IF_ERR_EXIT(rv);
   3854         _SOC_IF_ERR_EXIT
   3855             (portmod_port_chain_phy_access_get(unit, port, pm_info,
   3856                                            phy_access,(1+MAX_PHYN),
   3857                                            &nof_phys));
   3858         /*
   3859          * if the interface is already set with PARAM_SET_ONLY
   3860          * h/w interface needs to be updated during speed set.
   3861          * So load the interface information and clear the flag;
   3862          */
   3863         /* After command "port xe<n> if=xxxx; port xe<x> sp=xxx" is issued, the following segment of code will be called
   3864          * If ext phy is present, then target interface is retrieved and passed into ext phy interface_set function
   3865          * is_legacy_phy_callback is set as 1 when we want ext phy to update interface, which relays on interface_type;
   3866          * If ext phy is not present, the target interface is retrieved and passed into internal phy interface_config_set function
   3867          * is_legacy_phy_callback is set as 0 when we want internal phy to update interface, which relays on interface_mode
   3868          */
   3869         if(is_interface_restore) {
   3870             rv = PM4x25_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index);
   3871             _SOC_IF_ERR_EXIT(rv);
   3872             ((portmod_port_interface_config_t*)config)->interface = interface;
   3873             is_interface_restore = 0;
   3874             rv = PM4x25_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, port_index);
   3875             _SOC_IF_ERR_EXIT(rv);
   3876              if ((phy_init_flags == PORTMOD_INIT_F_ALL_PHYS) && (nof_phys > 1)) {
   3877                   is_legacy_phy_callback = 1;
   3878              } else if (nof_phys == 1) {
   3879                  is_legacy_phy_callback = 0;
   3880              }
   3881         } else {
   3882              /* Speed change only */
   3883              if ((phy_init_flags == PORTMOD_INIT_F_ALL_PHYS) && (nof_phys > 1)) {
   3884                   is_legacy_phy_callback = 1;
   3885              }
   3886              /* Internal PHY speed change */
   3887              if (phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) {
   3888                  is_legacy_phy_callback = 1;
   3889              }
   3890         }
   3891     }
   3892 
   3893     if (!pm_is_bypassed){
   3894         rv =  portmod_port_higig2_mode_set(unit, port, PHYMOD_INTF_MODES_HIGIG_GET(config));
   3895         _SOC_IF_ERR_EXIT(rv);
   3896 
   3897         flags = CLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   3898         rv = clmac_speed_set(unit, port, flags, config->speed);
   3899         _SOC_IF_ERR_EXIT(rv);
   3900 
   3901         if (mac_ts_enable) {
   3902             /*Set MAC Timestamp Delay*/
   3903             if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   3904                 _SOC_IF_ERR_EXIT(_pm4x25_port_timestamp_adjust_wb_get(unit, port, pm_info, config->speed, &ts_adjust));
   3905                 _SOC_IF_ERR_EXIT(clmac_timestamp_delay_set(unit, port, ts_adjust));
   3906             }
   3907             if (!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   3908                 _SOC_IF_ERR_EXIT(clmac_timestamp_byte_adjust_set(unit, port, 0, config->speed));
   3909             }
   3910         }
   3911 
   3912         flags = CLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS;
   3913 
   3914         rv = clmac_encap_set(unit, port, 0, PHYMOD_INTF_MODES_HIGIG_GET(config) ? SOC_ENCAP_HIGIG2 : SOC_ENCAP_IEEE);
   3915         _SOC_IF_ERR_EXIT(rv);
   3916 
   3917         is_higig =  PHYMOD_INTF_MODES_HIGIG_GET(config) ? SOC_ENCAP_HIGIG2 : SOC_ENCAP_IEEE;
   3918         rv = clmac_strict_preamble_set(unit, port, (!is_higig && (config->speed >= 10000)));
   3919         _SOC_IF_ERR_EXIT(rv);
   3920 
   3921         /* De-Assert SOFT_RESET */
   3922         rv = pm4x25_port_soft_reset(unit, port, pm_info, 0);
   3923         _SOC_IF_ERR_EXIT(rv);
   3924     }
   3925 
   3926     if(!(PM_4x25_INFO(pm_info)->in_pm12x10)){
   3927         _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_config));
   3928         _SOC_IF_ERR_EXIT(_pm4x25_line_side_phymod_interface_get(unit, port, pm_info, phy_init_flags, config, &phymod_interface));
   3929         phy_config.interface_type = phymod_interface;
   3930         /* If is_legacy_phy_callback = 0, then interface mode will be set based on inerface type, which is needed for tscf */
   3931         _SOC_IF_ERR_EXIT(_pm4x25_phymod_interface_mode_set(unit, port, pm_info, config, &phy_config, is_legacy_phy_callback));
   3932 
   3933         /* interface_mode is updated with phy_config->interface_mode */
   3934         rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   3935         _SOC_IF_ERR_EXIT(rv);
   3936         if (PHYMOD_INTF_MODES_FIBER_GET(&phy_config)) {
   3937             interface_modes &= ~(PHYMOD_INTF_MODES_COPPER | PHYMOD_INTF_MODES_BACKPLANE);
   3938             interface_modes |= PHYMOD_INTF_MODES_FIBER;
   3939         } else if (PHYMOD_INTF_MODES_COPPER_GET(&phy_config)){
   3940             interface_modes &= ~(PHYMOD_INTF_MODES_FIBER | PHYMOD_INTF_MODES_BACKPLANE);
   3941             interface_modes |= PHYMOD_INTF_MODES_COPPER;
   3942         } else if (PHYMOD_INTF_MODES_BACKPLANE_GET(&phy_config)){
   3943             interface_modes &= ~(PHYMOD_INTF_MODES_COPPER | PHYMOD_INTF_MODES_FIBER);
   3944             interface_modes |= PHYMOD_INTF_MODES_BACKPLANE;
   3945         }
   3946         rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   3947         _SOC_IF_ERR_EXIT(rv);
   3948 
   3949         phy_config.data_rate = config->speed;
   3950         phy_config.ref_clock = PM_4x25_INFO(pm_info)->ref_clk;
   3951         rv = PM4x25_PORT_PLL_DIVIDER_REQ_GET(unit, pm_info, &pll_divider_req, port_index);
   3952         _SOC_IF_ERR_EXIT(rv);
   3953         rv = PM4x25_PORT_10G_AT_25G_GET(unit, pm_info, &serdes_10g_at_25g_vco, port_index);
   3954         _SOC_IF_ERR_EXIT(rv);
   3955         rv = PM4x25_PORT_1000X_AT_25G_GET(unit, pm_info, &serdes_1000x_at_25g_vco, port_index);
   3956         _SOC_IF_ERR_EXIT(rv);
   3957         /*The pll div is set to 165 when 10G working at 25G is supported*/
   3958         if (phy_config.data_rate == 10000) {
   3959             if (serdes_10g_at_25g_vco) {
   3960                 pll_divider_req = 165;
   3961             } else {
   3962                 pll_divider_req = 132;
   3963             }
   3964         }
   3965         if (phy_config.data_rate == 1000) {
   3966             if (serdes_1000x_at_25g_vco) {
   3967                 pll_divider_req = 165;
   3968             } else {
   3969                 pll_divider_req = 132;
   3970             }
   3971         }
   3972         phy_config.pll_divider_req = pll_divider_req;
   3973 
   3974         if (config->serdes_interface != SOC_PORT_IF_NULL) {
   3975             _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit,
   3976                              config->speed,
   3977                              config->serdes_interface,
   3978                              &phymod_serdes_interface));
   3979         }
   3980 
   3981         /* internal phy preemphasis and current */
   3982         if (!(config->flags & (PHYMOD_INTF_F_SET_SPD_TRIGGER | PHYMOD_INTF_F_UPDATE_SPEED_LINKUP))) {
   3983 
   3984             /* if the tx params are updated from non default value read the non dflt value from the HW and update it */
   3985             rv = PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   3986                                           &port_dynamic_state, port_index);
   3987             _SOC_IF_ERR_EXIT(rv);
   3988 
   3989             if (!PORTMOD_PORT_IS_DEFAULT_TX_PARAMS_UPDATED(port_dynamic_state)) {
   3990                 _SOC_IF_ERR_EXIT
   3991                     (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   3992                                                                 0, PM_4x25_INFO(pm_info)->ref_clk,
   3993                                                                 &cur_phy_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   3994                 if ((phy_config.data_rate != cur_phy_config.data_rate) ||
   3995                     (phy_config.interface_modes != cur_phy_config.interface_modes)) {
   3996                     for(i=0; i<PHYMOD_MAX_LANES_PER_CORE; i++){
   3997                         _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(&phy_access[0], phymodMediaTypeChipToChip,
   3998                                                                       &(updated_tx_params[i])));
   3999                     }
   4000                     _SOC_IF_ERR_EXIT(portmod_port_phychain_tx_set(unit, phy_access, 1, updated_tx_params));
   4001                 }
   4002             }
   4003         }
   4004 
   4005        _SOC_IF_ERR_EXIT
   4006            (portmod_port_phychain_interface_config_set(unit, port, phy_access, nof_phys,
   4007                                                     config->flags,
   4008                                                     &phy_config,
   4009                                                     phymod_serdes_interface,
   4010                                                     PM_4x25_INFO(pm_info)->ref_clk,
   4011                                                     phy_init_flags));
   4012 
   4013         /* The interface type software state needs to be stored even if the config flags
   4014          * does not include PHYMOD_INTF_F_INTF_PARAM_SET_ONLY. For example, when changing
   4015          * the encap, portctrl tries to config the PHY interface type and speed in one
   4016          * shot without setting the PHYMOD_INTF_F_INTF_PARAM_SET_ONLY flag. However,
   4017          * when the current function is called by the legacy ext PHY through the portmod
   4018          * callback function, the interface type software state should not be modified
   4019          * since PM4x10_INTERFACE_TYPE_GET() should return the outmost PHY interface type.
   4020          */
   4021         if (!(nof_phys > 1 && phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY)) {
   4022             _SOC_IF_ERR_EXIT
   4023                 (portmod_intf_from_phymod_intf(unit, phy_config.interface_type, &interface)); 
   4024             _SOC_IF_ERR_EXIT
   4025                 (PM4x25_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   4026             _SOC_IF_ERR_EXIT
   4027                 (PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   4028         }
   4029     }
   4030 
   4031 exit:
   4032     SOC_FUNC_RETURN;    
   4033 }
   4034 
   4035 int pm4x25_port_interface_config_get(int unit, int port, pm_info_t pm_info, portmod_port_interface_config_t* config, int phy_init_flags)
   4036 {
   4037     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4038     soc_port_if_t interface;
   4039     phymod_phy_inf_config_t phy_config;
   4040     int           flags = 0, nof_phys = 0, rv, port_index, max_speed;
   4041     uint32_t      bitmap;
   4042     phymod_interface_t           prev_phymod_if;
   4043     SOC_INIT_FUNC_DEFS;
   4044 
   4045     if(PM_4x25_INFO(pm_info)->in_pm12x10){
   4046         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("can't get interface config for PM4X25 within PM12X10")));
   4047     }
   4048 
   4049     if (_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap))
   4050         return (SOC_E_PARAM);
   4051    
   4052     rv = PM4x25_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index);
   4053     _SOC_IF_ERR_EXIT(rv);
   4054     rv = PM4x25_OUTMOST_PHY_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index);
   4055     _SOC_IF_ERR_EXIT(rv);
   4056 
   4057     _SOC_IF_ERR_EXIT
   4058         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4059                                           phy_access ,(1+MAX_PHYN),
   4060                                            &nof_phys));
   4061 
   4062     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_config));
   4063 
   4064     phy_config.data_rate = max_speed;
   4065 
   4066     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, max_speed, interface, &prev_phymod_if));
   4067 
   4068     _SOC_IF_ERR_EXIT
   4069         (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   4070                                                     0, PM_4x25_INFO(pm_info)->ref_clk,
   4071                                                     &phy_config, phy_init_flags));
   4072 
   4073     /* It is possible that the underlying phymod interface get API does not
   4074      * distinguish among certain interface types. For example, CR4 and KR4
   4075      * are treated the same from TSCF's perspective. In these cases portmod
   4076      * has to rely on the software state to retrieve the most-recently used
   4077      * interface type written into phymod.
   4078      */
   4079     if (phy_config.interface_type != prev_phymod_if &&
   4080         prev_phymod_if != phymodInterfaceCount &&
   4081         phy_init_flags != PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) {
   4082         phy_config.interface_type = prev_phymod_if;
   4083     }
   4084 
   4085     config->speed = phy_config.data_rate;
   4086     config->interface_modes = phy_config.interface_modes;
   4087     config->flags = 0;
   4088 
   4089     rv = portmod_intf_from_phymod_intf(unit, phy_config.interface_type, &(config->interface));
   4090     _SOC_IF_ERR_EXIT(rv);
   4091 
   4092     rv = clmac_encap_get (unit, port, &flags, &config->encap_mode);
   4093     _SOC_IF_ERR_EXIT(rv);
   4094 
   4095     /* coverity[Out-of-bounds access:FALSE] */
   4096     SHR_BITCOUNT_RANGE(&bitmap, config->port_num_lanes, 0, PM4X25_LANES_PER_CORE);
   4097     rv = PM4x25_MAX_SPEED_GET(unit, pm_info, &config->max_speed, port_index);
   4098     _SOC_IF_ERR_EXIT(rv);
   4099     rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &config->interface_modes, port_index);
   4100     _SOC_IF_ERR_EXIT(rv);
   4101 
   4102 
   4103 exit:
   4104     SOC_FUNC_RETURN;
   4105 }
   4106 
   4107 int pm4x25_port_default_interface_get(int unit, int port, pm_info_t pm_info,
   4108                                       const portmod_port_interface_config_t* config,
   4109                                       soc_port_if_t* interface)
   4110 {
   4111     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4112     int nof_phys = 0;
   4113     int is_legacy_phy;
   4114     int xphy_id;
   4115     portmod_port_interface_config_t interface_config;
   4116     SOC_INIT_FUNC_DEFS;
   4117 
   4118     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   4119                                            phy_access ,(1+MAX_PHYN),
   4120                                            &nof_phys));
   4121 
   4122     if (nof_phys==1) {
   4123         _SOC_IF_ERR_EXIT
   4124             (_pm4x25_default_interface_get(unit, port, config, interface));
   4125     } else {
   4126         xphy_id = phy_access[nof_phys-1].access.addr;
   4127         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   4128 
   4129         if (!is_legacy_phy) {
   4130             _SOC_IF_ERR_EXIT
   4131                 (portmod_port_phymod_xphy_default_interface_get(unit, &(phy_access[nof_phys-1]),
   4132                                                                 config, interface));
   4133         } else {
   4134             interface_config = *config;
   4135             _SOC_IF_ERR_EXIT
   4136                 (portmod_common_default_interface_get(&interface_config));
   4137             *interface = interface_config.interface;
   4138         }
   4139     }
   4140 
   4141 exit:
   4142     SOC_FUNC_RETURN;
   4143 }
   4144 
   4145 int pm4x25_port_cl72_set(int unit, int port, pm_info_t pm_info, uint32 enable)
   4146 {
   4147     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4148     int   nof_phys = 0;
   4149 
   4150     SOC_INIT_FUNC_DEFS;
   4151 
   4152     _SOC_IF_ERR_EXIT
   4153         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4154                                           phy_access ,(1+MAX_PHYN),
   4155                                            &nof_phys));
   4156 
   4157     if (!SAL_BOOT_SIMULATION) {
   4158         _SOC_IF_ERR_EXIT
   4159             (portmod_port_phychain_cl72_set(unit, port, phy_access, nof_phys, enable));
   4160     }
   4161 
   4162 exit:
   4163     SOC_FUNC_RETURN;
   4164 }
   4165 
   4166 int pm4x25_port_cl72_get(int unit, int port, pm_info_t pm_info, uint32* enable)
   4167 {
   4168     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4169     int   nof_phys = 0;
   4170 
   4171     SOC_INIT_FUNC_DEFS;
   4172 
   4173     _SOC_IF_ERR_EXIT
   4174         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4175                                           phy_access ,(1+MAX_PHYN),
   4176                                            &nof_phys));
   4177 
   4178     if (!SAL_BOOT_SIMULATION) {
   4179         _SOC_IF_ERR_EXIT
   4180             (portmod_port_phychain_cl72_get(unit, phy_access, nof_phys, enable));
   4181     }
   4182 
   4183 exit:
   4184     SOC_FUNC_RETURN;
   4185 }
   4186 
   4187 int pm4x25_port_cl72_status_get(int unit, int port, pm_info_t pm_info, phymod_cl72_status_t* status)
   4188 {
   4189     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4190     int   nof_phys = 0;
   4191 
   4192     SOC_INIT_FUNC_DEFS;
   4193 
   4194     _SOC_IF_ERR_EXIT
   4195         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4196                                           phy_access ,(1+MAX_PHYN),
   4197                                            &nof_phys));
   4198 
   4199     if (!SAL_BOOT_SIMULATION) {
   4200         _SOC_IF_ERR_EXIT
   4201             (portmod_port_phychain_cl72_status_get(unit, phy_access, nof_phys, status));
   4202     }
   4203 
   4204 exit:
   4205     SOC_FUNC_RETURN;
   4206 }
   4207 
   4208 
   4209 int pm4x25_port_loopback_get(int unit, int port, pm_info_t pm_info,
   4210                  portmod_loopback_mode_t loopback_type, int* enable)
   4211 {   
   4212     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4213     int                 nof_phys;
   4214     uint32_t tmp_enable=0;
   4215     phymod_loopback_mode_t phymod_lb_type;
   4216     int rv = PHYMOD_E_NONE;
   4217     int port_index;
   4218     uint32 bitmap;
   4219 
   4220     SOC_INIT_FUNC_DEFS;
   4221 
   4222     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   4223                                              &bitmap));
   4224 
   4225     switch(loopback_type){
   4226         case portmodLoopbackMacOuter:
   4227             _SOC_IF_ERR_EXIT(clmac_loopback_get(unit, port, loopback_type, enable));
   4228             break;
   4229 
   4230         case portmodLoopbackPhyGloopPMD:
   4231         case portmodLoopbackPhyRloopPMD: /*slide*/
   4232         case portmodLoopbackPhyGloopPCS: /*slide*/
   4233              if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   4234                 (*enable) = 0; /* No phy --> no phy loopback*/
   4235              } else {
   4236                 _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit,
   4237                                                 loopback_type, &phymod_lb_type));
   4238                 _SOC_IF_ERR_EXIT
   4239                     (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4240                                                       phy_access ,(1+MAX_PHYN),
   4241                                                       &nof_phys));
   4242 
   4243                 rv = portmod_port_phychain_loopback_get(unit, port, phy_access,
   4244                                                     nof_phys,
   4245                                                     phymod_lb_type,
   4246                                                     &tmp_enable);
   4247                 if (rv == PHYMOD_E_UNAVAIL) {
   4248                     rv = PHYMOD_E_NONE;
   4249                     tmp_enable = 0;
   4250                 }
   4251 
   4252                 _SOC_IF_ERR_EXIT(rv);
   4253                 *enable = tmp_enable;
   4254 
   4255              }
   4256              break;
   4257         default:
   4258             (*enable) = 0; /* not supported --> no loopback */
   4259             break;
   4260     }
   4261 
   4262 exit:
   4263     SOC_FUNC_RETURN;
   4264 }
   4265 
   4266 int pm4x25_port_loopback_set(int unit, int port, pm_info_t pm_info, portmod_loopback_mode_t loopback_type, int enable)
   4267 {
   4268     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4269     int                 nof_phys;
   4270     int                 is_clmac_in_soft_reset;
   4271     phymod_loopback_mode_t phymod_lb_type;
   4272     int port_index;
   4273     uint32 bitmap;
   4274     portmod_dispatch_type_t pm_type = portmodDispatchTypeCount;
   4275 
   4276     SOC_INIT_FUNC_DEFS;
   4277 
   4278     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   4279                                              &bitmap));
   4280 
   4281     /* loopback type validation*/
   4282     switch(loopback_type){
   4283     case portmodLoopbackMacOuter:
   4284 
   4285         /*Get SOFT_RESET status*/
   4286         _SOC_IF_ERR_EXIT(clmac_soft_reset_get(unit, port, &is_clmac_in_soft_reset));
   4287 
   4288         _SOC_IF_ERR_EXIT(portmod_port_pm_type_get(unit, port, &port, &pm_type));
   4289 
   4290         /* According to MAC designer - Do MAC SOFT RESET before loopback change */
   4291         if (!is_clmac_in_soft_reset){
   4292             if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   4293                 /* Since SOFT_RESET sends credits which might cause FIFO overflow, we need to do a procedural pm4x25_port_soft_reset
   4294                  * (with in_out = 1 to put CLMAC in-to SOFT_RESET) */
   4295                 _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 1));
   4296             } else {
   4297 #ifdef PORTMOD_PM12X10_SUPPORT
   4298                 if (enable && (pm_type == portmodDispatchTypePm12x10)) {
   4299                    /*
   4300                     * CLMAC loopback enable
   4301                     * CLMAC_CTRL.SOFT_RESET=1
   4302                     * CLMAC_CTRL.SOFT_RESET=0
   4303                     * CLMAC_CTRL.LOCAL_LPBK=0
   4304                     * CLMAC_CTRL.LOCAL_LPBK=1
   4305                     */
   4306                     _SOC_IF_ERR_EXIT(clmac_soft_reset_set(unit, port, 1));
   4307                     _SOC_IF_ERR_EXIT(clmac_soft_reset_set(unit, port, 0));
   4308                     _SOC_IF_ERR_EXIT(clmac_loopback_set(unit, port, loopback_type, 0));
   4309                 }
   4310 #endif
   4311             }
   4312         }
   4313         /*Open / close loopback*/
   4314         _SOC_IF_ERR_EXIT(clmac_loopback_set(unit, port, loopback_type, enable));
   4315 
   4316 
   4317         if (!is_clmac_in_soft_reset){
   4318             if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   4319                 /* Get SOFT_RESET out-of-reset, using procedural pm4x25_port_soft_reset with in_out = 0 to get CLMAC out-of SOFT_RESET */
   4320                 _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 0));
   4321             } else {
   4322 #ifdef PORTMOD_PM12X10_SUPPORT
   4323                 if ((!enable) && (pm_type == portmodDispatchTypePm12x10)) {
   4324                    /*
   4325                     * CLMAC loopback disable
   4326                     * CLMAC_CTRL.LOCAL_LPBK=0
   4327                     * CLMAC_CTRL.SOFT_RESET=1
   4328                     * CLMAC_CTRL.SOFT_RESET=0
   4329                     */
   4330                     _SOC_IF_ERR_EXIT(clmac_soft_reset_set(unit, port, 1));
   4331                     _SOC_IF_ERR_EXIT(clmac_soft_reset_set(unit, port, 0));
   4332                 }
   4333 #endif
   4334             }
   4335         }
   4336         break;
   4337 
   4338     case portmodLoopbackPhyRloopPCS:
   4339     case portmodLoopbackPhyRloopPMD: /*slide*/
   4340     case portmodLoopbackPhyGloopPMD:
   4341     case portmodLoopbackPhyGloopPCS: /*slide*/
   4342         if(PM_4x25_INFO(pm_info)->nof_phys[port_index] != 0) {
   4343             if (enable) {
   4344                 _SOC_IF_ERR_EXIT(clmac_loopback_set(unit, port, portmodLoopbackMacOuter, 0));
   4345             }
   4346 
   4347             _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit,
   4348                                                 loopback_type, &phymod_lb_type));
   4349 
   4350             _SOC_IF_ERR_EXIT
   4351                 (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4352                                                   phy_access ,(1+MAX_PHYN),
   4353                                                   &nof_phys));
   4354 
   4355             _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_set(unit, port, phy_access,
   4356                                                                 nof_phys,
   4357                                                                 phymod_lb_type,
   4358                                                                 enable));
   4359          }
   4360          break;
   4361     default:
   4362         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (
   4363                   _SOC_MSG("unsupported loopback type %d"), loopback_type));
   4364             break;
   4365     }
   4366     if (enable)
   4367         _SOC_IF_ERR_EXIT(PM_DRIVER(pm_info)->f_portmod_port_lag_failover_status_toggle(unit, port, pm_info));
   4368 
   4369 exit:
   4370     SOC_FUNC_RETURN; 
   4371 }
   4372 
   4373 int pm4x25_port_rx_mac_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   4374 {
   4375     SOC_INIT_FUNC_DEFS;
   4376 
   4377     _SOC_IF_ERR_EXIT(clmac_rx_enable_set(unit, port, enable));
   4378 exit:
   4379     SOC_FUNC_RETURN; 
   4380 }
   4381 
   4382 int pm4x25_port_rx_mac_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   4383 {
   4384     SOC_INIT_FUNC_DEFS;
   4385 
   4386     _SOC_IF_ERR_EXIT(clmac_rx_enable_get(unit, port, enable));
   4387 exit:
   4388     SOC_FUNC_RETURN;
   4389 }
   4390 
   4391 int pm4x25_port_tx_mac_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   4392 {
   4393     SOC_INIT_FUNC_DEFS;
   4394 
   4395     _SOC_IF_ERR_EXIT(clmac_tx_enable_set(unit, port, enable));
   4396 
   4397 exit:
   4398     SOC_FUNC_RETURN;
   4399 }
   4400 
   4401 int pm4x25_port_tx_mac_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   4402 {
   4403     SOC_INIT_FUNC_DEFS;
   4404 
   4405     _SOC_IF_ERR_EXIT(clmac_tx_enable_get(unit, port, enable));
   4406 
   4407 exit:
   4408     SOC_FUNC_RETURN;
   4409 }
   4410 
   4411 int pm4x25_port_ability_local_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, portmod_port_ability_t* ability)
   4412 {
   4413     int                 rv;
   4414     portmod_port_ability_t legacy_phy_ability;
   4415     int                 port_index;
   4416     int                 max_speed = 100000;
   4417     int                 num_of_lanes = 0;
   4418     int                 loopback = SOC_PA_LB_PHY | SOC_PA_LB_MAC;
   4419     uint32              bitmap, tmpbit, interface_modes;
   4420     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4421     int nof_phys, xphy_id, is_legacy_phy;
   4422 
   4423     SOC_INIT_FUNC_DEFS;
   4424     SOC_NULL_CHECK(pm_info);
   4425 
   4426     sal_memset(ability, 0, sizeof(portmod_port_ability_t));
   4427     sal_memset(&legacy_phy_ability, 0, sizeof(portmod_port_ability_t));
   4428 
   4429     _SOC_IF_ERR_EXIT
   4430         (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,
   4431                                            (1+MAX_PHYN), &nof_phys));
   4432 
   4433     _SOC_IF_ERR_EXIT
   4434         (_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   4435    
   4436     rv = PM4x25_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index);
   4437     _SOC_IF_ERR_EXIT(rv);
   4438     rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   4439     _SOC_IF_ERR_EXIT(rv);
   4440 
   4441     tmpbit = bitmap;
   4442     while(tmpbit) {
   4443         num_of_lanes += ((tmpbit&1)?1:0) ;
   4444         tmpbit >>= 1 ;
   4445     }
   4446 
   4447 
   4448     if (SAL_BOOT_SIMULATION) {
   4449         loopback = SOC_PA_LB_MAC;
   4450     }
   4451     ability->loopback  = loopback;
   4452     ability->medium    = SOC_PA_MEDIUM_FIBER | SOC_PA_MEDIUM_COPPER | SOC_PA_MEDIUM_BACKPLANE;
   4453     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   4454     ability->fec       = SOC_PA_FEC_NONE | SOC_PA_FEC_CL74 | SOC_PA_FEC_CL91;
   4455     ability->flags     = SOC_PA_AUTONEG;
   4456     ability->speed_half_duplex  = SOC_PA_ABILITY_NONE;
   4457     ability->encap     = SOC_PA_ENCAP_IEEE | SOC_PA_ENCAP_HIGIG | SOC_PA_ENCAP_HIGIG2;
   4458     ability->channel   = SOC_PA_CHANNEL_LONG | SOC_PA_CHANNEL_SHORT;
   4459 
   4460     if (num_of_lanes == 1) {
   4461         if (interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   4462             switch(max_speed) {
   4463                 case 10000: max_speed = 11000 ; break ;
   4464                 case 20000: max_speed = 21000 ; break ;
   4465                 case 25000: max_speed = 27000 ; break ;
   4466                 default:  break ;
   4467             }
   4468             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4469             _SOC_IF_ERR_EXIT(rv);
   4470         } else {
   4471             ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   4472             switch(max_speed) {
   4473                 case 11000: max_speed = 10000 ; break ;
   4474                 case 21000: max_speed = 20000 ; break ;
   4475                 case 27000: max_speed = 25000 ; break ;
   4476                 default:  break ;
   4477             }
   4478             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4479             _SOC_IF_ERR_EXIT(rv);
   4480         }
   4481         switch(max_speed) {  /* must include all the supported speedss */
   4482             case 27000:
   4483             case 26500:
   4484                 ability->speed_full_duplex |= SOC_PA_SPEED_27GB;
   4485             case 25000:
   4486                 ability->speed_full_duplex |= SOC_PA_SPEED_25GB;
   4487             case 21000:
   4488                 ability->speed_full_duplex |= SOC_PA_SPEED_21GB;
   4489             case 20000:
   4490                 ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   4491             case 11000:
   4492                 ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   4493             case 10000:
   4494                 ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   4495             case 5000:
   4496                 ability->speed_full_duplex |= SOC_PA_SPEED_5000MB;
   4497             case 2500:
   4498                 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB;
   4499             default:
   4500                 break;
   4501         }
   4502         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   4503         ability->interface = SOC_PA_INTF_GMII | SOC_PA_INTF_SGMII;
   4504         if (max_speed >= 10000) {
   4505             ability->interface |= SOC_PA_INTF_XGMII;
   4506         }
   4507         ability->loopback  = loopback;
   4508         ability->flags = SOC_PA_AUTONEG;
   4509     } else if (num_of_lanes == 2) {
   4510         if (interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   4511             switch(max_speed) {
   4512                 case 20000: max_speed = 21000 ; break ;
   4513                 case 40000: max_speed = 42000 ; break ;
   4514                 case 50000: max_speed = 53000 ; break ;
   4515                 default:  break ;
   4516             }
   4517             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4518             _SOC_IF_ERR_EXIT(rv);
   4519         } else {
   4520             switch(max_speed) {
   4521                 case 21000: max_speed = 20000 ; break ;
   4522                 case 42000: max_speed = 40000 ; break ;
   4523                 case 53000: max_speed = 50000 ; break ;
   4524                 default:  break ;
   4525             }
   4526             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4527             _SOC_IF_ERR_EXIT(rv);
   4528         }
   4529         switch(max_speed) {  /* must include all the supported speedss */
   4530             case 53000:
   4531                 ability->speed_full_duplex |= SOC_PA_SPEED_53GB;
   4532             case 50000:
   4533                 ability->speed_full_duplex |= SOC_PA_SPEED_50GB;
   4534             case 42000:
   4535                 ability->speed_full_duplex |= SOC_PA_SPEED_42GB;
   4536             case 40000:
   4537                 ability->speed_full_duplex |= SOC_PA_SPEED_40GB;
   4538             case 21000:
   4539                 ability->speed_full_duplex |= SOC_PA_SPEED_21GB;
   4540             case 20000:
   4541                 ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   4542             default:
   4543                 break;
   4544         }
   4545         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   4546         ability->interface = SOC_PA_INTF_XGMII;
   4547         ability->loopback  = loopback;
   4548         ability->flags = 0;
   4549     } else {
   4550         if (interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   4551             switch(max_speed) {
   4552                 case 40000: max_speed = 42000 ; break ;
   4553                 case 50000: max_speed = 53000 ; break ;
   4554                 case 100000: max_speed = 106000 ; break ;
   4555                 case 120000: max_speed = 127000 ; break ;
   4556                 default:  break ;
   4557             }
   4558             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4559             _SOC_IF_ERR_EXIT(rv);
   4560         } else {
   4561             switch(max_speed) {
   4562                 case 42000: max_speed = 40000 ; break ;
   4563                 case 53000: max_speed = 50000 ; break ;
   4564                 case 106000: max_speed = 100000 ; break ;
   4565                 case 127000: max_speed = 120000 ; break ;
   4566                 default:  break ;
   4567             }
   4568             rv = PM4x25_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   4569             _SOC_IF_ERR_EXIT(rv);
   4570         }
   4571         switch(max_speed) {
   4572             case 127000:
   4573                 ability->speed_full_duplex |= SOC_PA_SPEED_127GB;
   4574             case 120000:
   4575                 ability->speed_full_duplex |= SOC_PA_SPEED_120GB;
   4576             case 106000:
   4577                 ability->speed_full_duplex |= SOC_PA_SPEED_106GB;
   4578             case 100000:
   4579                 ability->speed_full_duplex |= SOC_PA_SPEED_100GB;
   4580             case 53000:
   4581                 ability->speed_full_duplex |= SOC_PA_SPEED_53GB;
   4582             case 50000:
   4583                 ability->speed_full_duplex |= SOC_PA_SPEED_50GB;
   4584             case 42000:
   4585                 ability->speed_full_duplex |= SOC_PA_SPEED_42GB;
   4586             case 40000:
   4587                 ability->speed_full_duplex |= SOC_PA_SPEED_40GB;
   4588             default:
   4589                 break; 
   4590         }
   4591         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   4592         ability->interface = SOC_PA_INTF_XGMII;
   4593         ability->loopback  = loopback;
   4594         ability->flags     = SOC_PA_AUTONEG;
   4595     }
   4596 
   4597     /* If legacy external phy presents, retrieve the local ability from the
   4598      * external phy as it has more variants and the ability might vary for each.
   4599      * However, if this function is called by the legacy ext PHY driver through
   4600      * the PORTMOD callback function portmod_ext_to_int_cmd_get(), the returned
   4601      * data should be of the internal SERDES. portmod_ext_to_int_cmd_get() uses
   4602      * PORTMOD_USER_ACC_CMD_FOR_PHY_SET() to hint its callees that the target
   4603      * of data retrieving is the internal SERDES.
   4604      */
   4605     if (nof_phys > 1 && !(phy_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY)) {
   4606         /* check if the legacy phy present */
   4607         xphy_id = phy_access[nof_phys-1].access.addr;
   4608         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   4609         if(is_legacy_phy) {
   4610             /* call portmod phy chain function to retrieve the ability */
   4611             _SOC_IF_ERR_EXIT
   4612                 (portmod_port_phychain_local_ability_get(unit, port, phy_access,
   4613                                                          nof_phys, &legacy_phy_ability));
   4614             /* PHY driver returns all the speeds supported by PHY
   4615              * Advertise only the speeds supported by both PortMacro and the PHY
   4616              */
   4617             legacy_phy_ability.speed_full_duplex &= ability->speed_full_duplex;
   4618             /* PHY driver may not return all supported encap modes
   4619              * Advertise encap modes supported by both PortMacro and the PHY
   4620              */
   4621             legacy_phy_ability.encap |= ability->encap;
   4622             *ability = legacy_phy_ability;
   4623         } else {
   4624             /* We might need to consider calling portmod phy chain for
   4625              * non legacy phys as well*/
   4626         }
   4627     }
   4628 
   4629     LOG_INFO(BSL_LS_SOC_PHY,
   4630              (BSL_META_U(unit,
   4631                          "phy_tscf_ability_local_get:unit=%d p=%d sp=%08x\n"),
   4632               unit, port, ability->speed_full_duplex));
   4633 
   4634 exit:
   4635     SOC_FUNC_RETURN;
   4636 }
   4637 
   4638 static int _pm4x25_nof_lanes_get(int unit, int port, pm_info_t pm_info)
   4639 {
   4640     int port_index, rv;
   4641     uint32_t bitmap, bcnt = 0;
   4642 
   4643     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index,
   4644                                              &bitmap);
   4645     if (rv) return (0); /* bit count is zero will flag error */
   4646 
   4647     while (bitmap) {
   4648         if (bitmap & 0x1) bcnt++;
   4649         bitmap >>= 1;
   4650     }
   4651     return (bcnt);
   4652 }
   4653 
   4654 int pm4x25_port_autoneg_set(int unit, int port, pm_info_t pm_info, uint32 phy_flags, 
   4655                             const phymod_autoneg_control_t* an)
   4656 {
   4657     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4658     int nof_phys, rv;
   4659     int port_index, fs_cl72;
   4660     uint32_t bitmap, an_done, port_dynamic_state;
   4661     phymod_autoneg_control_t  *pAn = (phymod_autoneg_control_t*)an;
   4662 
   4663     SOC_INIT_FUNC_DEFS;
   4664 
   4665     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   4666                                              &bitmap));
   4667 
   4668     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   4669         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("AN isn't supported")));
   4670     } else {
   4671         if (pAn->num_lane_adv == 0) {
   4672             pAn->num_lane_adv = _pm4x25_nof_lanes_get(unit, port, pm_info);
   4673         }
   4674 
   4675         if (pAn->an_mode == phymod_AN_MODE_NONE) {
   4676             rv = PM4x25_AN_MODE_GET(unit, pm_info, &pAn->an_mode, port_index);
   4677             _SOC_IF_ERR_EXIT(rv);
   4678         }
   4679 
   4680         if (pAn->an_mode == phymod_AN_MODE_NONE) {
   4681             pAn->an_mode = phymod_AN_MODE_SGMII;
   4682         }
   4683 
   4684         rv = PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   4685                                            &port_dynamic_state, port_index);
   4686         _SOC_IF_ERR_EXIT(rv);
   4687 
   4688         if (PORTMOD_PORT_IS_AUTONEG_MODE_UPDATED(port_dynamic_state)) {
   4689             rv = PM4x25_AN_MODE_GET(unit, pm_info, &pAn->an_mode, port_index);
   4690             _SOC_IF_ERR_EXIT(rv);
   4691 
   4692             PORTMOD_PORT_AUTONEG_MODE_UPDATED_CLR(port_dynamic_state);
   4693             rv = PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info,
   4694                                                port_dynamic_state, port_index);
   4695             _SOC_IF_ERR_EXIT(rv);
   4696         }
   4697 
   4698         /* next chenck if cl72 force bit is set, if set, don't allow AN to */
   4699         /* change cl72 config */
   4700         rv = PM4x25_FS_CL72_GET(unit, pm_info, &fs_cl72, port_index);
   4701         _SOC_IF_ERR_EXIT(rv);
   4702         if (fs_cl72) {
   4703             PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_CLR(pAn);
   4704         } else {
   4705             PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_SET(pAn);
   4706         }
   4707 
   4708         _SOC_IF_ERR_EXIT
   4709             (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4710                                               phy_access ,(1+MAX_PHYN),
   4711                                               &nof_phys));
   4712 
   4713         /* In case of warm boot, get autoneg informaton from hardware */
   4714         if(SOC_WARM_BOOT(unit)) {
   4715             if (pAn->an_mode >= phymod_AN_MODE_Count) {
   4716                 _SOC_IF_ERR_EXIT
   4717                     (portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, phy_flags, pAn, &an_done));
   4718             }
   4719         }
   4720 
   4721         rv = portmod_port_phychain_autoneg_set(unit, port, phy_access, nof_phys, phy_flags, an);
   4722         /* Because the returned value PHYMOD_E_UNAVAIL is -12 from tscf phymod driver */
   4723         if (rv == PHYMOD_E_UNAVAIL) {
   4724             rv = SOC_E_UNAVAIL;
   4725         }
   4726         _SOC_IF_ERR_EXIT(rv);
   4727     }
   4728     
   4729 exit:
   4730     SOC_FUNC_RETURN;
   4731 }
   4732 
   4733 int pm4x25_port_autoneg_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, phymod_autoneg_control_t* an)
   4734 {      
   4735     int rv, port_index, nof_phys;
   4736     uint32_t bitmap, an_done;
   4737     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4738 
   4739     SOC_INIT_FUNC_DEFS;
   4740     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   4741                                              &bitmap));
   4742 
   4743     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   4744         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("AN isn't supported")));
   4745     } else {
   4746 
   4747         if (an->num_lane_adv == 0) {
   4748             an->num_lane_adv = _pm4x25_nof_lanes_get(unit, port, pm_info);
   4749         }
   4750         rv = PM4x25_AN_MODE_GET(unit, pm_info, &an->an_mode, port_index);
   4751         _SOC_IF_ERR_EXIT(rv);
   4752         if (an->an_mode == phymod_AN_MODE_NONE) {
   4753             an->an_mode = phymod_AN_MODE_SGMII;
   4754         }
   4755 
   4756         _SOC_IF_ERR_EXIT
   4757             (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4758                                                phy_access ,(1+MAX_PHYN),
   4759                                                &nof_phys));
   4760         _SOC_IF_ERR_EXIT
   4761             (portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, phy_flags, an, &an_done));
   4762     }
   4763 
   4764 exit:
   4765     SOC_FUNC_RETURN;
   4766 }
   4767 
   4768 int pm4x25_port_autoneg_status_get (int unit, int port, pm_info_t pm_info, 
   4769                                     phymod_autoneg_status_t* an_status)
   4770 {
   4771     int port_index;
   4772     uint32 bitmap;
   4773     portmod_port_interface_config_t port_intf_config;
   4774     phymod_interface_t phy_intf;
   4775 
   4776     SOC_INIT_FUNC_DEFS;
   4777     
   4778     _SOC_IF_ERR_EXIT
   4779         (_pm4x25_port_index_get(unit, port, pm_info, &port_index, &bitmap));
   4780     
   4781 
   4782     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   4783         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("Invalid number of Phys")));
   4784     }
   4785 
   4786     _SOC_IF_ERR_EXIT
   4787         (portmod_phy_port_autoneg_status_get (unit, port, pm_info, an_status));
   4788    
   4789     _SOC_IF_ERR_EXIT
   4790         (pm4x25_port_interface_config_get(unit, port, pm_info, &port_intf_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   4791 
   4792     _SOC_IF_ERR_EXIT
   4793         (portmod_intf_to_phymod_intf(unit, port_intf_config.speed, port_intf_config.interface, &phy_intf));
   4794     
   4795     if (an_status->enabled && an_status->locked) {
   4796         an_status->data_rate = port_intf_config.speed;
   4797         an_status->interface = phy_intf;
   4798     } else {
   4799         /* upper layer should not rely on the 
   4800          *  data rate and interface if the AN is not locked
   4801          */
   4802         an_status->data_rate = 0;
   4803         an_status->interface = SOC_PORT_IF_NULL;        
   4804     }
   4805 exit:
   4806     SOC_FUNC_RETURN;
   4807 }
   4808 
   4809 int pm4x25_port_link_get(int unit, int port, pm_info_t pm_info, int flags, int* link)
   4810 {
   4811     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4812     int nof_phys;
   4813     uint32_t cl91_enable = 0, cl108_enable = 0, an_done = 0;
   4814     uint32 bitmap;
   4815     int port_index=0;
   4816     uint32 interface_modes;
   4817     phymod_autoneg_control_t an;
   4818     portmod_link_recovery_t link_recovery;
   4819     int rv_cl91 = 0, rv_cl108 = 0;
   4820     uint32_t prbs_enable = 0;
   4821 
   4822     SOC_INIT_FUNC_DEFS;
   4823 
   4824     _SOC_IF_ERR_EXIT
   4825         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4826                                            phy_access ,(1+MAX_PHYN),
   4827                                            &nof_phys));
   4828 
   4829     _SOC_IF_ERR_EXIT
   4830             (portmod_port_phychain_link_status_get(unit, port, phy_access, nof_phys, flags, (uint32_t*) link));
   4831     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   4832     _SOC_IF_ERR_EXIT(PM4x25_PORT_LINK_RECOVERY_GET(unit, pm_info, &link_recovery, port_index));
   4833 
   4834     if ((nof_phys == 1) && (link_recovery.enabled)) {
   4835         /* link recovery for internal serdes only for optical application MLD based */
   4836         uint32_t signal_detect;
   4837 
   4838         /* first get the medium type from internal serdes */
   4839         _SOC_IF_ERR_EXIT(PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index));
   4840 
   4841         if ((interface_modes & (PHYMOD_INTF_MODES_FIBER | PHYMOD_INTF_MODES_BACKPLANE))) {
   4842             /* Get CL91 */
   4843             PHYMOD_FEC_CL91_SET(cl91_enable);
   4844             rv_cl91 = phymod_phy_fec_enable_get(&phy_access[0], &cl91_enable);
   4845             /* Get CL108 */
   4846             PHYMOD_FEC_CL108_SET(cl108_enable);
   4847             rv_cl108 = phymod_phy_fec_enable_get(&phy_access[0], &cl108_enable);
   4848             if (((rv_cl91 == PHYMOD_E_NONE) && cl91_enable) || ((rv_cl108 == PHYMOD_E_NONE) && cl108_enable)) {
   4849                 /* Get AN */
   4850                 _SOC_IF_ERR_EXIT
   4851                     (phymod_phy_autoneg_get(&phy_access[0], &an, &an_done));
   4852                 /* Pcs link is impacted once prbs test is enabled.
   4853                  * The WAR could be triggered to do link recovery to reset PMA/PMD.
   4854                  * The prbs test may fail in this condition. Make sure this WAR won't be triggered when prbs is enabled.
   4855                  */
   4856                 _SOC_IF_ERR_EXIT
   4857                     (phymod_phy_prbs_enable_get(&phy_access[0], 0, &prbs_enable));
   4858                 if ((!an.enable) && (!prbs_enable)) {
   4859                     switch (link_recovery.state) {
   4860 
   4861                             case PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK:
   4862                                 /* link is good */
   4863                                 if (*link) {
   4864                                     link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD;
   4865                                 } else {
   4866                                     /* no link yet, keep wait for link */
   4867                                     link_recovery.tick_cnt += 1;
   4868                                     if ((link_recovery.tick_cnt) > PORTMOD_LINK_RECOVERY_LINK_WAIT_CNT_LIMIT) {
   4869                                         /* no link after all the try, reset the rx patha again */
   4870                                         link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_RESET_RX;
   4871                                     }
   4872                                 }
   4873                                 break;
   4874                             case PORTMOD_LINK_RECOVERY_STATE_RESET_RX:
   4875                                  link_recovery.tick_cnt = 0;
   4876                                 /*first check link status */
   4877                                 if (*link) {
   4878                                     link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD;
   4879                                 } else {
   4880                                     /* first reset the rx path */
   4881                                     signal_detect = 0;
   4882 
   4883                                     /* check if there is signal detect */
   4884                                     _SOC_IF_ERR_EXIT(phymod_phy_rx_signal_detect_get(&phy_access[0], &signal_detect));
   4885 
   4886                                     /* only toggle rx reset path only if there is signal on the line */
   4887                                     if (signal_detect) {
   4888                                          /* first put the rx into reset */
   4889                                          _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxDisable));
   4890 
   4891                                         /* add some delay */
   4892                                         sal_usleep(5000);
   4893 
   4894                                          /* toggle CDR lock */
   4895                                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxSquelchOn));
   4896                                         /* add some delay */
   4897                                         sal_usleep(5000);
   4898                                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxSquelchOff));
   4899 
   4900                                         sal_usleep(10000);
   4901                                         /* release the rx reset */
   4902                                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxReset));
   4903 
   4904                                         sal_usleep(10000);
   4905                                     }
   4906                                     link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK;
   4907                                 }
   4908                                 break;
   4909 
   4910                             case PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD:
   4911                                 /* no link, need to reset the rx path */
   4912                                 if (*link == 0) {
   4913                                     link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_RESET_RX;
   4914                                 }
   4915                                 break;
   4916                     }
   4917                     _SOC_IF_ERR_EXIT(PM4x25_PORT_LINK_RECOVERY_SET(unit, pm_info, link_recovery, port_index));
   4918                 }
   4919             }
   4920         }
   4921     }/* end of link recovery */
   4922 
   4923 
   4924 exit:
   4925     SOC_FUNC_RETURN;
   4926 }
   4927 
   4928 int pm4x25_port_link_latch_down_get(int unit, int port, pm_info_t pm_info, uint32 flags, int* link)
   4929 {
   4930     int first_index, rv;
   4931     uint32 reg32_val, bitmap;
   4932     soc_field_t status_field, clear_field;
   4933     SOC_INIT_FUNC_DEFS;
   4934     
   4935     *link = 0;
   4936 
   4937     rv = _pm4x25_port_index_get(unit, port, pm_info, &first_index, &bitmap);
   4938     _SOC_IF_ERR_EXIT(rv);
   4939     
   4940      switch(first_index) {
   4941         case 0:
   4942             status_field = PORT0_LINKSTATUSf;
   4943             clear_field = PORT0_LINKDOWN_CLEARf;
   4944             break;
   4945 
   4946         case 1:
   4947             status_field = PORT1_LINKSTATUSf;
   4948             clear_field = PORT1_LINKDOWN_CLEARf;
   4949             break;
   4950 
   4951         case 2:
   4952             status_field = PORT2_LINKSTATUSf;
   4953             clear_field = PORT2_LINKDOWN_CLEARf;
   4954             break;
   4955 
   4956         case 3:
   4957             status_field = PORT3_LINKSTATUSf;
   4958             clear_field = PORT3_LINKDOWN_CLEARf;
   4959             break;
   4960 
   4961         default:
   4962             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
   4963                      (_SOC_MSG("Port %d, failed to get port index"), port));
   4964     }
   4965 
   4966     rv = READ_CLPORT_LINKSTATUS_DOWNr(unit, port, &reg32_val);
   4967     _SOC_IF_ERR_EXIT(rv);
   4968 
   4969     (*link) = soc_reg_field_get(unit, CLPORT_LINKSTATUS_DOWNr, 
   4970                                         reg32_val, status_field);
   4971 
   4972     if (PORTMOD_PORT_LINK_LATCH_DOWN_F_CLEAR & flags) {
   4973 
   4974         rv = READ_CLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, &reg32_val);
   4975         _SOC_IF_ERR_EXIT(rv);
   4976 
   4977         soc_reg_field_set(unit, CLPORT_LINKSTATUS_DOWN_CLEARr, 
   4978                                         &reg32_val, clear_field, 1);
   4979 
   4980         rv = WRITE_CLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, reg32_val);
   4981         _SOC_IF_ERR_EXIT(rv);
   4982 
   4983         sal_usleep(10);
   4984 
   4985         soc_reg_field_set(unit, CLPORT_LINKSTATUS_DOWN_CLEARr, 
   4986                                         &reg32_val, clear_field, 0);
   4987 
   4988         /* reset default register value */
   4989         rv = WRITE_CLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, reg32_val);
   4990         _SOC_IF_ERR_EXIT(rv);
   4991 
   4992     }
   4993 
   4994         
   4995 exit:
   4996     SOC_FUNC_RETURN;
   4997 }
   4998 
   4999 /*
   5000     The field STRICT_PREAMBLE is used to check preamble+SFD strictly.
   5001     The preamble will be shrinked when some external PHY works at 1G,
   5002     so there are packet errors if STRICT_PREAMBLE is enabled.
   5003 */
   5004 int _pm4x25_port_strict_preamble_set(int unit, int port, pm_info_t pm_info)
   5005 {
   5006     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5007     int nof_phys;
   5008     int port_index=0;
   5009     uint32 bitmap;
   5010     phymod_phy_inf_config_t phy_config;
   5011     int is_higig = 0;
   5012     uint32 interface_modes;
   5013     int strict_preamble_enable=0;
   5014     SOC_INIT_FUNC_DEFS;
   5015 
   5016     _SOC_IF_ERR_EXIT
   5017         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   5018                                            phy_access ,(1+MAX_PHYN),
   5019                                            &nof_phys));
   5020 
   5021     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   5022                                          &bitmap));
   5023     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_config));
   5024 
   5025     _SOC_IF_ERR_EXIT
   5026         (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   5027                                                     0, PM_4x25_INFO(pm_info)->ref_clk,
   5028                                                     &phy_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   5029     _rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   5030     _SOC_IF_ERR_EXIT(_rv);
   5031     is_higig =  interface_modes & PHYMOD_INTF_MODES_HIGIG ? 1 : 0;
   5032     if (!is_higig && (phy_config.data_rate>= 10000)) {
   5033         strict_preamble_enable = 1;
   5034     }
   5035     _rv = clmac_strict_preamble_set(unit, port, strict_preamble_enable);
   5036     _SOC_IF_ERR_EXIT(_rv);
   5037 exit:
   5038     SOC_FUNC_RETURN;
   5039 }
   5040 
   5041 int pm4x25_port_phy_link_up_event(int unit, int port, pm_info_t pm_info)
   5042 {
   5043     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5044     int nof_phys;
   5045 
   5046     SOC_INIT_FUNC_DEFS;
   5047 
   5048     _SOC_IF_ERR_EXIT
   5049         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   5050                                            phy_access ,(1+MAX_PHYN),
   5051                                            &nof_phys));
   5052     _rv = portmod_port_phychain_phy_link_up_event(unit, port, phy_access, nof_phys);
   5053     _SOC_IF_ERR_EXIT(_rv);
   5054 
   5055     _SOC_IF_ERR_EXIT(_pm4x25_port_strict_preamble_set(unit, port, pm_info));
   5056 exit:
   5057     SOC_FUNC_RETURN;
   5058 }
   5059 
   5060 int pm4x25_port_phy_link_down_event(int unit, int port, pm_info_t pm_info)
   5061 {
   5062     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5063     int nof_phys;
   5064 
   5065     SOC_INIT_FUNC_DEFS;
   5066 
   5067     _SOC_IF_ERR_EXIT
   5068         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   5069                                            phy_access ,(1+MAX_PHYN),
   5070                                            &nof_phys));
   5071 
   5072     _rv = portmod_port_phychain_phy_link_down_event(unit, port, phy_access, nof_phys);
   5073 
   5074 exit:
   5075     SOC_FUNC_RETURN;
   5076 
   5077 }
   5078 
   5079 int pm4x25_port_mac_link_get(int unit, int port, pm_info_t pm_info, int* link)
   5080 {
   5081     uint32 reg_val, bitmap;
   5082     int port_index, phy_acc;
   5083     SOC_INIT_FUNC_DEFS;
   5084     SOC_NULL_CHECK(pm_info);
   5085    
   5086     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   5087 
   5088     /* coverity[callee_ptr_arith:FALSE] */
   5089     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index, (uint32*)(&bitmap)));
   5090 
   5091     switch(port_index) {
   5092         case 0:
   5093             _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_LN0_STATUS0_REGr(unit, phy_acc, &reg_val));
   5094             (*link) = soc_reg_field_get(unit, CLPORT_XGXS0_LN0_STATUS0_REGr, reg_val, LINK_STATUSf);
   5095             break;
   5096 
   5097         case 1:
   5098             _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_LN1_STATUS0_REGr(unit, phy_acc, &reg_val));
   5099             (*link) = soc_reg_field_get(unit, CLPORT_XGXS0_LN1_STATUS0_REGr, reg_val, LINK_STATUSf);
   5100             break;
   5101 
   5102         case 2:
   5103             _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_LN2_STATUS0_REGr(unit, phy_acc, &reg_val));
   5104             (*link) = soc_reg_field_get(unit, CLPORT_XGXS0_LN2_STATUS0_REGr, reg_val, LINK_STATUSf);
   5105             break;
   5106 
   5107         case 3:
   5108             _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_LN3_STATUS0_REGr(unit, phy_acc, &reg_val));
   5109             (*link) = soc_reg_field_get(unit, CLPORT_XGXS0_LN3_STATUS0_REGr, reg_val, LINK_STATUSf);
   5110             break;
   5111 
   5112         default:
   5113             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
   5114                      (_SOC_MSG("Port %d, failed to get port index"), port));
   5115     }
   5116 
   5117 exit:
   5118     SOC_FUNC_RETURN;
   5119 }
   5120 
   5121 
   5122 int pm4x25_port_prbs_config_set(int unit, int port, pm_info_t pm_info, 
   5123                                 portmod_prbs_mode_t mode, int flags, 
   5124                                 const phymod_prbs_t* config)
   5125 {
   5126     int port_index, rv;
   5127     uint32 bitmap;
   5128 
   5129     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5130     if (SOC_FAILURE(rv)) {
   5131          return (rv);
   5132     }
   5133 
   5134     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5135         return(SOC_E_UNAVAIL);
   5136     }
   5137     return (portmod_phy_port_prbs_config_set(unit, port, pm_info, mode, flags, config));
   5138 }
   5139 
   5140 int pm4x25_port_prbs_config_get(int unit, int port, pm_info_t pm_info, 
   5141                                 portmod_prbs_mode_t mode, int flags, 
   5142                                 phymod_prbs_t* config)
   5143 {
   5144     int port_index, rv;
   5145     uint32 bitmap;
   5146 
   5147     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5148     if (SOC_FAILURE(rv)) {
   5149          return (rv);
   5150     }
   5151 
   5152     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5153         return(SOC_E_UNAVAIL);
   5154     }
   5155 
   5156     return (portmod_phy_port_prbs_config_get(unit, port, pm_info, mode, flags, config));
   5157 }
   5158 
   5159 
   5160 int pm4x25_port_prbs_enable_set(int unit, int port, pm_info_t pm_info, 
   5161                                 portmod_prbs_mode_t mode, int flags,
   5162                                 int enable)
   5163 {
   5164     int port_index, rv;
   5165     uint32 bitmap;
   5166 
   5167     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5168     if (SOC_FAILURE(rv)) {
   5169          return (rv);
   5170     }
   5171 
   5172     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5173         return(SOC_E_UNAVAIL);
   5174     }
   5175     return (portmod_phy_port_prbs_enable_set(unit, port, pm_info, mode, flags, enable));
   5176 }
   5177 
   5178 int pm4x25_port_prbs_enable_get(int unit, int port, pm_info_t pm_info, 
   5179                                 portmod_prbs_mode_t mode, int flags,
   5180                                 int* enable)
   5181 { 
   5182     int port_index, rv;
   5183     uint32 bitmap;
   5184 
   5185     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5186     if (SOC_FAILURE(rv)) {
   5187          return (rv);
   5188     }
   5189 
   5190     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5191         return(SOC_E_UNAVAIL);
   5192     }
   5193     return (portmod_phy_port_prbs_enable_get(unit, port, pm_info, mode, flags, enable));
   5194 }
   5195 
   5196 
   5197 int pm4x25_port_prbs_status_get(int unit, int port, pm_info_t pm_info, 
   5198                                 portmod_prbs_mode_t mode, int flags, 
   5199                                 phymod_prbs_status_t* status)
   5200 {
   5201     int port_index, rv;
   5202     uint32 bitmap;
   5203 
   5204     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5205     if (SOC_FAILURE(rv)) {
   5206          return (rv);
   5207     }
   5208 
   5209     if(PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5210         return(SOC_E_UNAVAIL);
   5211     }
   5212     return (portmod_phy_port_prbs_status_get(unit, port, pm_info, mode, flags, status));
   5213 }
   5214 
   5215 
   5216 int pm4x25_port_nof_lanes_get(int unit, int port, pm_info_t pm_info, int *nof_lanes)
   5217 {
   5218     int temp_nof_lanes = 0;
   5219     SOC_INIT_FUNC_DEFS;
   5220 
   5221     temp_nof_lanes = _pm4x25_nof_lanes_get(unit, port, pm_info);
   5222     if(0 == temp_nof_lanes){
   5223         SOC_EXIT;
   5224     }
   5225     else{
   5226         *nof_lanes = temp_nof_lanes;
   5227     }
   5228 
   5229 exit:
   5230     SOC_FUNC_RETURN;
   5231 }
   5232 
   5233 
   5234 int pm4x25_port_firmware_mode_set(int unit, int port, pm_info_t pm_info,
   5235                                   phymod_firmware_mode_t fw_mode)
   5236 {
   5237         
   5238     SOC_INIT_FUNC_DEFS;
   5239     SOC_NULL_CHECK(pm_info);
   5240     
   5241     /* Place your code here */
   5242      
   5243 exit:
   5244     SOC_FUNC_RETURN; 
   5245     
   5246 }
   5247 
   5248 int pm4x25_port_firmware_mode_get(int unit, int port, pm_info_t pm_info, phymod_firmware_mode_t* fw_mode)
   5249 {
   5250         
   5251     SOC_INIT_FUNC_DEFS;
   5252     SOC_NULL_CHECK(pm_info);
   5253     
   5254     /* Place your code here */
   5255 
   5256         
   5257 exit:
   5258     SOC_FUNC_RETURN; 
   5259     
   5260 }
   5261 
   5262 
   5263 int pm4x25_port_runt_threshold_set(int unit, int port, pm_info_t pm_info, int value)
   5264 {
   5265         
   5266     SOC_INIT_FUNC_DEFS;
   5267     SOC_NULL_CHECK(pm_info);
   5268     
   5269     /* Place your code here */
   5270 
   5271         
   5272 exit:
   5273     SOC_FUNC_RETURN; 
   5274     
   5275 }
   5276 
   5277 int pm4x25_port_runt_threshold_get(int unit, int port, pm_info_t pm_info, int* value)
   5278 {
   5279         
   5280     SOC_INIT_FUNC_DEFS;
   5281     SOC_NULL_CHECK(pm_info);
   5282     
   5283     /* Place your code here */
   5284 
   5285         
   5286 exit:
   5287     SOC_FUNC_RETURN; 
   5288     
   5289 }
   5290 
   5291 
   5292 int pm4x25_port_max_packet_size_set(int unit, int port, pm_info_t pm_info, int value)
   5293 {
   5294         
   5295     SOC_INIT_FUNC_DEFS;
   5296     _SOC_IF_ERR_EXIT(clmac_rx_max_size_set(unit, port , value));      
   5297 exit:
   5298     SOC_FUNC_RETURN; 
   5299     
   5300 }
   5301 
   5302 int pm4x25_port_max_packet_size_get(int unit, int port, pm_info_t pm_info, int* value)
   5303 {
   5304         
   5305     SOC_INIT_FUNC_DEFS;
   5306     _SOC_IF_ERR_EXIT(clmac_rx_max_size_get(unit, port , value));
   5307 exit:
   5308     SOC_FUNC_RETURN; 
   5309     
   5310 }
   5311 
   5312 
   5313 int pm4x25_port_pad_size_set(int unit, int port, pm_info_t pm_info, int value)
   5314 {        
   5315     SOC_INIT_FUNC_DEFS;
   5316     SOC_NULL_CHECK(pm_info);
   5317     
   5318     _SOC_IF_ERR_EXIT(clmac_pad_size_set(unit, port , value));
   5319     
   5320 exit:
   5321     SOC_FUNC_RETURN;     
   5322 }
   5323 
   5324 int pm4x25_port_pad_size_get(int unit, int port, pm_info_t pm_info, int* value)
   5325 {        
   5326     SOC_INIT_FUNC_DEFS;
   5327     SOC_NULL_CHECK(pm_info);
   5328     
   5329     _SOC_IF_ERR_EXIT(clmac_pad_size_get(unit, port , value));
   5330         
   5331 exit:
   5332     SOC_FUNC_RETURN;     
   5333 }
   5334 
   5335 
   5336 int pm4x25_port_tx_drop_on_local_fault_set(int unit, int port, pm_info_t pm_info, int enable)
   5337 {
   5338     portmod_local_fault_control_t control;    
   5339     SOC_INIT_FUNC_DEFS;
   5340 
   5341     portmod_local_fault_control_t_init(unit, &control);
   5342     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_get(unit, port, pm_info, &control));
   5343     control.drop_tx_on_fault  = enable;
   5344     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_set(unit, port, pm_info, &control));
   5345 exit:
   5346     SOC_FUNC_RETURN; 
   5347     
   5348 }
   5349 
   5350 int pm4x25_port_tx_drop_on_local_fault_get(int unit, int port, pm_info_t pm_info, int* enable)
   5351 {       
   5352     portmod_local_fault_control_t control;    
   5353     SOC_INIT_FUNC_DEFS;
   5354 
   5355     portmod_local_fault_control_t_init(unit, &control);   
   5356     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_get(unit, port, pm_info, &control));
   5357     *enable = control.drop_tx_on_fault;
   5358 exit:
   5359     SOC_FUNC_RETURN; 
   5360 }
   5361 
   5362 
   5363 int pm4x25_port_tx_drop_on_remote_fault_set(int unit, int port,
   5364                                             pm_info_t pm_info, int enable)
   5365 {        
   5366     portmod_remote_fault_control_t control;    
   5367     SOC_INIT_FUNC_DEFS;
   5368 
   5369     portmod_remote_fault_control_t_init(unit, &control);   
   5370     _SOC_IF_ERR_EXIT(pm4x25_port_remote_fault_control_get(unit, port, pm_info, &control));
   5371     control.drop_tx_on_fault = enable;
   5372     _SOC_IF_ERR_EXIT(pm4x25_port_remote_fault_control_set(unit, port, pm_info, &control));
   5373 exit:
   5374     SOC_FUNC_RETURN;   
   5375 }
   5376 
   5377 int pm4x25_port_tx_drop_on_remote_fault_get(int unit, int port, pm_info_t pm_info, int* enable)
   5378 {
   5379     portmod_remote_fault_control_t control;    
   5380     SOC_INIT_FUNC_DEFS;
   5381 
   5382     portmod_remote_fault_control_t_init(unit, &control);   
   5383     _SOC_IF_ERR_EXIT(pm4x25_port_remote_fault_control_get(unit, port, pm_info, &control));
   5384     *enable = control.drop_tx_on_fault;
   5385 exit:
   5386     SOC_FUNC_RETURN;   
   5387 }
   5388 
   5389 int pm4x25_port_remote_fault_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   5390 {
   5391     portmod_remote_fault_control_t control;
   5392     SOC_INIT_FUNC_DEFS;
   5393 
   5394     portmod_remote_fault_control_t_init(unit, &control);
   5395     
   5396     _SOC_IF_ERR_EXIT(clmac_remote_fault_control_get(unit, port , &control));
   5397     control.enable = enable;
   5398     _SOC_IF_ERR_EXIT(clmac_remote_fault_control_set(unit, port , &control));       
   5399 exit:
   5400     SOC_FUNC_RETURN;   
   5401 }
   5402 
   5403 int pm4x25_port_remote_fault_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   5404 {
   5405     portmod_remote_fault_control_t control;   
   5406     SOC_INIT_FUNC_DEFS;
   5407 
   5408     portmod_remote_fault_control_t_init(unit, &control);
   5409 
   5410     _SOC_IF_ERR_EXIT(clmac_remote_fault_control_get(unit, port , &control));
   5411     *enable = control.enable;    
   5412 exit:
   5413     SOC_FUNC_RETURN; 
   5414     
   5415 }
   5416 
   5417 int pm4x25_port_local_fault_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   5418 {
   5419     portmod_local_fault_control_t control;
   5420     SOC_INIT_FUNC_DEFS;
   5421 
   5422     portmod_local_fault_control_t_init(unit, &control);
   5423 
   5424     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_get(unit, port, pm_info, &control));
   5425     control.enable = enable;
   5426     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_set(unit, port, pm_info, &control));
   5427 exit:
   5428     SOC_FUNC_RETURN;
   5429 }
   5430 
   5431 
   5432 int pm4x25_port_local_fault_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   5433 {
   5434     portmod_local_fault_control_t control;
   5435     SOC_INIT_FUNC_DEFS;
   5436 
   5437     portmod_local_fault_control_t_init(unit, &control);
   5438     
   5439     _SOC_IF_ERR_EXIT(pm4x25_port_local_fault_control_get(unit, port, pm_info, &control));
   5440     *enable = control.enable;
   5441 
   5442 exit:
   5443     SOC_FUNC_RETURN;
   5444 }
   5445 
   5446 int pm4x25_port_local_fault_status_get(int unit, int port,
   5447                                        pm_info_t pm_info, int* value)
   5448 {
   5449     int rv;
   5450     SOC_INIT_FUNC_DEFS;
   5451 
   5452     rv = clmac_local_fault_status_get(unit, port, 0, value);
   5453     _SOC_IF_ERR_EXIT(rv);
   5454 exit:
   5455     SOC_FUNC_RETURN;
   5456 }
   5457 
   5458 int pm4x25_port_local_fault_control_set(int unit, int port, pm_info_t pm_info,
   5459                     const portmod_local_fault_control_t* control)
   5460 {
   5461     int rv;
   5462     SOC_INIT_FUNC_DEFS;
   5463 
   5464     rv = clmac_local_fault_control_set(unit, port, control);
   5465     _SOC_IF_ERR_EXIT(rv);
   5466 exit:
   5467     SOC_FUNC_RETURN;
   5468 }
   5469 
   5470 int pm4x25_port_local_fault_control_get(int unit, int port, pm_info_t pm_info,
   5471                     portmod_local_fault_control_t* control)
   5472 {
   5473     int rv;
   5474     SOC_INIT_FUNC_DEFS;
   5475 
   5476     rv = clmac_local_fault_control_get(unit, port, control);
   5477     _SOC_IF_ERR_EXIT(rv);
   5478 exit:
   5479     SOC_FUNC_RETURN;
   5480 }
   5481 
   5482 int pm4x25_port_remote_fault_status_get(int unit, int port,
   5483                                         pm_info_t pm_info, int* value)
   5484 {
   5485     int rv;
   5486     SOC_INIT_FUNC_DEFS;
   5487 
   5488     rv = clmac_remote_fault_status_get(unit, port, 0, value);
   5489     _SOC_IF_ERR_EXIT(rv);
   5490 exit:
   5491     SOC_FUNC_RETURN;
   5492 }
   5493 
   5494 int pm4x25_port_remote_fault_control_set(int unit, int port, pm_info_t pm_info,
   5495                     const portmod_remote_fault_control_t* control)
   5496 {
   5497     int rv;
   5498     SOC_INIT_FUNC_DEFS;
   5499 
   5500     rv = clmac_remote_fault_control_set(unit, port, control);
   5501     _SOC_IF_ERR_EXIT(rv);
   5502 exit:
   5503     SOC_FUNC_RETURN;
   5504 }
   5505 
   5506 int pm4x25_port_remote_fault_control_get(int unit, int port, pm_info_t pm_info,
   5507                     portmod_remote_fault_control_t* control)
   5508 {
   5509     int rv;
   5510     SOC_INIT_FUNC_DEFS;
   5511 
   5512     rv = clmac_remote_fault_control_get(unit, port, control);
   5513     _SOC_IF_ERR_EXIT(rv);
   5514 exit:
   5515     SOC_FUNC_RETURN;
   5516 }
   5517 
   5518 int pm4x25_port_pause_control_set(int unit, int port, pm_info_t pm_info,
   5519                                   const portmod_pause_control_t* control)
   5520 {
   5521     SOC_INIT_FUNC_DEFS;
   5522     _SOC_IF_ERR_EXIT(clmac_pause_control_set(unit, port, control));
   5523 exit:
   5524     SOC_FUNC_RETURN;
   5525 }
   5526 
   5527 int pm4x25_port_pause_control_get(int unit, int port, pm_info_t pm_info,
   5528                                   portmod_pause_control_t* control)
   5529 {
   5530     SOC_INIT_FUNC_DEFS;
   5531     _SOC_IF_ERR_EXIT(clmac_pause_control_get(unit, port, control));
   5532 exit:
   5533     SOC_FUNC_RETURN;
   5534 }
   5535 
   5536 int pm4x25_port_pfc_control_set(int unit, int port,
   5537            pm_info_t pm_info, const portmod_pfc_control_t* control)
   5538 {
   5539     SOC_INIT_FUNC_DEFS;
   5540     _SOC_IF_ERR_EXIT(clmac_pfc_control_set(unit, port, control));
   5541 exit:
   5542     SOC_FUNC_RETURN;
   5543 }
   5544 
   5545 int pm4x25_port_pfc_control_get(int unit, int port, pm_info_t pm_info, portmod_pfc_control_t* control)
   5546 {
   5547     SOC_INIT_FUNC_DEFS;
   5548     _SOC_IF_ERR_EXIT(clmac_pfc_control_get(unit, port, control));     
   5549 exit:
   5550     SOC_FUNC_RETURN;
   5551 }
   5552 
   5553 
   5554 int pm4x25_port_llfc_control_set(int unit, int port,
   5555             pm_info_t pm_info, const portmod_llfc_control_t* control)
   5556 {
   5557     SOC_INIT_FUNC_DEFS;
   5558     _SOC_IF_ERR_EXIT(clmac_llfc_control_set(unit, port, control));
   5559 exit:
   5560     SOC_FUNC_RETURN;
   5561 }
   5562 
   5563 int pm4x25_port_llfc_control_get(int unit, int port,
   5564             pm_info_t pm_info, portmod_llfc_control_t* control)
   5565 {
   5566     SOC_INIT_FUNC_DEFS;
   5567     _SOC_IF_ERR_EXIT(clmac_llfc_control_get(unit, port, control));
   5568 
   5569 exit:
   5570     SOC_FUNC_RETURN;
   5571 }
   5572 
   5573 
   5574 int pm4x25_port_core_access_get (int unit, int port,
   5575                                  pm_info_t pm_info, int phyn, int max_cores,
   5576                                  phymod_core_access_t* core_access_arr,
   5577                                  int* nof_cores,
   5578                                  int* is_most_ext)
   5579 {
   5580     int port_index;
   5581     uint32 bitmap;
   5582     int index;
   5583     int done=0;
   5584     int i,j, is_legacy_phy;
   5585     uint32 xphy_id;
   5586     phymod_core_access_t core_access;
   5587 
   5588     SOC_INIT_FUNC_DEFS;
   5589 
   5590     if(PM_4x25_INFO(pm_info)->in_pm12x10){
   5591         _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("core access get cannot be called for PM4X25 which is part of PM12X10")));
   5592     }
   5593 
   5594     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   5595                                              &bitmap));
   5596 
   5597     if(phyn > PM_4x25_INFO(pm_info)->nof_phys[port_index]){
   5598         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 
   5599                (_SOC_MSG("phyn exceeded. max allowed %d. got %d"), 
   5600                        PM_4x25_INFO(pm_info)->nof_phys[port_index] - 1, phyn));
   5601     }
   5602 
   5603     if(phyn < 0)
   5604     {
   5605         phyn = PM_4x25_INFO(pm_info)->nof_phys[port_index] - 1;
   5606     }
   5607 
   5608     _SOC_IF_ERR_EXIT(phymod_core_access_t_init(&core_access_arr[0]));
   5609 
   5610     if( phyn == 0 ){
   5611         sal_memcpy(&core_access_arr[0], &(PM_4x25_INFO(pm_info)->int_core_access),
   5612                      sizeof(phymod_core_access_t));
   5613         *nof_cores = 1;
   5614     } else {
   5615         index = 0;
   5616         done = 0;
   5617         for(i=0 ; (i< MAX_PORTS_PER_PM4X25); i++) {
   5618             if(bitmap & (0x1U << i)) {
   5619                 xphy_id = PM_4x25_INFO(pm_info)->lane_conn[phyn-1][i].xphy_id;
   5620                 if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   5621                     if(index == 0){
   5622                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   5623                         sal_memcpy(&core_access_arr[index], &(core_access),
   5624                                    sizeof(phymod_core_access_t));
   5625                         index++;
   5626                     } else {
   5627                         for( j = 0 ; (j < index) &&(!done) ; j++) {
   5628                              if((!sal_memcmp (&core_access_arr[j], &core_access,
   5629                                                sizeof(phymod_core_access_t)))) { /* found a match */
   5630                                 done = 1;
   5631                             }
   5632                         }
   5633                         if((!done) && (index < max_cores)){                        
   5634                             sal_memcpy(&core_access_arr[index], &(core_access),
   5635                                        sizeof(phymod_core_access_t));
   5636                             index++;
   5637                         }
   5638                     }
   5639                 }
   5640             }
   5641         }
   5642         *nof_cores = index;
   5643     }
   5644     if (is_most_ext) {
   5645         if (phyn == PM_4x25_INFO(pm_info)->nof_phys[port_index]-1) {
   5646             *is_most_ext = 1;
   5647         } else {
   5648             *is_most_ext = 0;
   5649         }
   5650     }
   5651 
   5652 exit:
   5653     SOC_FUNC_RETURN;
   5654 }
   5655 
   5656 /*!
   5657  * pm4x25_port_frame_spacing_stretch_set
   5658  *
   5659  * @brief Port Mac Control Spacing Stretch 
   5660  *
   5661  * @param [in]  unit            - unit id
   5662  * @param [in]  port            - logical port
   5663  * @param [in]  spacing         - 
   5664  */
   5665 int pm4x25_port_frame_spacing_stretch_set (int unit, int port, 
   5666                                            pm_info_t pm_info,int spacing)
   5667 {
   5668     return(clmac_frame_spacing_stretch_set(unit, port, spacing));
   5669 }
   5670 
   5671 /*! 
   5672  * pm4x25_port_frame_spacing_stretch_get
   5673  *
   5674  * @brief Port Mac Control Spacing Stretch 
   5675  *
   5676  * @param [in]  unit            - unit id
   5677  * @param [in]  port            - logical port
   5678  * @param [in]  spacing         - 
   5679  */
   5680 int pm4x25_port_frame_spacing_stretch_get (int unit, int port,
   5681                                             pm_info_t pm_info, 
   5682                                             const int *spacing)
   5683 {
   5684     return (clmac_frame_spacing_stretch_get(unit, port, (int *)spacing));
   5685 }
   5686 
   5687 /*! 
   5688  * pm4x25_port_diag_fifo_status_get
   5689  *
   5690  * @brief get port timestamps in fifo 
   5691  *
   5692  * @param [in]  unit            - unit id
   5693  * @param [in]  port            - logical port
   5694  * @param [in]  diag_info       - 
   5695  */
   5696 int pm4x25_port_diag_fifo_status_get (int unit, int port,pm_info_t pm_info, 
   5697                                  const portmod_fifo_status_t* diag_info)
   5698 {
   5699     return(clmac_diag_fifo_status_get(unit, port, diag_info));
   5700 }
   5701 
   5702 int _clport_pfc_config_set(int unit, int port, uint32 value)
   5703 {
   5704     int rv = SOC_E_UNAVAIL;
   5705     uint32 rval32 = 0;
   5706 
   5707     if (SOC_REG_IS_VALID(unit,CLPORT_MAC_RSV_MASKr)) {
   5708         rv = READ_CLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   5709         if (SOC_SUCCESS(rv)) {
   5710             /* CLPORT_MAC_RSV_MASK: Bit 18 PFC frame detected
   5711              * Enable  PFC Frame : Set 0. Go through
   5712              * Disable PFC Frame : Set 1. Purged.
   5713              */
   5714             if(value) {
   5715                 rval32 &= ~(1 << 18);
   5716             } else {
   5717                 rval32 |= (1 << 18);
   5718             }
   5719             rv = WRITE_CLPORT_MAC_RSV_MASKr(unit, port, rval32);
   5720         }
   5721     }
   5722 
   5723     return rv;
   5724 }
   5725 
   5726 int _clport_pfc_config_get(int unit, int port, uint32* value)
   5727 {
   5728     int rv = SOC_E_NONE;
   5729     uint32 rval32 = 0;
   5730 
   5731     if (SOC_REG_IS_VALID(unit,CLPORT_MAC_RSV_MASKr)) {
   5732         rv = READ_CLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   5733         if (SOC_SUCCESS(rv)) {
   5734             /* CLPORT_MAC_RSV_MASK: Bit 18 PFC frame detected
   5735              * Enable  PFC Frame : Set 0. Go through
   5736              * Disable PFC Frame : Set 1. Purged.
   5737              */
   5738             *value = ((rval32 & 0x40000) >> 18) ? 0 : 1;
   5739         }
   5740     }
   5741 
   5742     return rv;
   5743 }
   5744 
   5745 /*! 
   5746  * pm4x25_port_pfc_config_set
   5747  *
   5748  * @brief set pass control frames. 
   5749  *
   5750  * @param [in]  unit            - unit id
   5751  * @param [in]  port            - logical port
   5752  * @param [in]  pfc_cfg         - 
   5753  */
   5754 int pm4x25_port_pfc_config_set (int unit, int port,pm_info_t pm_info,
   5755                                 const portmod_pfc_config_t* pfc_cfg)
   5756 {
   5757     SOC_INIT_FUNC_DEFS;
   5758 
   5759     if (pfc_cfg->classes != 8) {
   5760         return SOC_E_PARAM;
   5761     }
   5762     _SOC_IF_ERR_EXIT(clmac_pfc_config_set(unit, port, pfc_cfg));
   5763     _SOC_IF_ERR_EXIT(_clport_pfc_config_set(unit, port, pfc_cfg->rxpass));
   5764 exit:
   5765     SOC_FUNC_RETURN; 
   5766 }
   5767 
   5768 /*! 
   5769  * pm4x25_port_pfc_config_get
   5770  *
   5771  * @brief set pass control frames. 
   5772  *
   5773  * @param [in]  unit            - unit id
   5774  * @param [in]  port            - logical port
   5775  * @param [in]  pfc_cfg         - 
   5776  */
   5777 int pm4x25_port_pfc_config_get (int unit, int port,pm_info_t pm_info, 
   5778                                 portmod_pfc_config_t* pfc_cfg)
   5779 {
   5780     SOC_INIT_FUNC_DEFS;
   5781 
   5782     pfc_cfg->classes = 8;
   5783     _SOC_IF_ERR_EXIT(clmac_pfc_config_get(unit, port, pfc_cfg));
   5784     _SOC_IF_ERR_EXIT(_clport_pfc_config_get(unit, port, &pfc_cfg->rxpass));
   5785 exit:
   5786     SOC_FUNC_RETURN; 
   5787 }
   5788 
   5789 /*!
   5790  * pm4x25_port_eee_set
   5791  *
   5792  * @brief set EEE control and timers
   5793  *
   5794  * @param [in]  unit            - unit id
   5795  * @param [in]  port            - logical port
   5796  * @param [in]  eee             -
   5797  */
   5798 int pm4x25_port_eee_set(int unit, int port, pm_info_t pm_info,const portmod_eee_t* eee)
   5799 {
   5800     return (clmac_eee_set(unit, port, eee));
   5801 }
   5802 
   5803 /*!
   5804  * pm4x25_port_eee_get
   5805  *
   5806  * @brief get EEE control and timers
   5807  *
   5808  * @param [in]  unit            - unit id
   5809  * @param [in]  port            - logical port
   5810  * @param [in]  eee             -
   5811  */
   5812 int pm4x25_port_eee_get(int unit, int port, pm_info_t pm_info,portmod_eee_t* eee)
   5813 {
   5814     return (clmac_eee_get(unit, port, eee));
   5815 }
   5816 
   5817 /*! 
   5818  * pm4x25_port_vlan_tag_set
   5819  *
   5820  * @brief vlan tag set. 
   5821  *
   5822  * @param [in]  unit            - unit id
   5823  * @param [in]  port            - logical port
   5824  * @param [in]  vlan_tag        - 
   5825  */
   5826 int pm4x25_port_vlan_tag_set(int unit, int port, pm_info_t pm_info,const portmod_vlan_tag_t* vlan_tag)
   5827 {
   5828     return (clmac_rx_vlan_tag_set (unit, port, vlan_tag->outer_vlan_tag,
   5829                                    vlan_tag->inner_vlan_tag));
   5830 }
   5831 
   5832 
   5833 /*! 
   5834  * pm4x25_port_vlan_tag_get
   5835  *
   5836  * @brief vlan tag get. 
   5837  *
   5838  * @param [in]  unit            - unit id
   5839  * @param [in]  port            - logical port
   5840  * @param [in]  vlan_tag        - 
   5841  */
   5842 int pm4x25_port_vlan_tag_get(int unit, int port, pm_info_t pm_info, portmod_vlan_tag_t* vlan_tag)
   5843 {
   5844     return (clmac_rx_vlan_tag_get (unit, port, (int*)&vlan_tag->outer_vlan_tag,
   5845                                    (int*)&vlan_tag->inner_vlan_tag));
   5846 }
   5847 
   5848 /*! 
   5849  * pm4x25_port_duplex_set
   5850  *
   5851  * @brief duplex set. 
   5852  *
   5853  * @param [in]  unit            - unit id
   5854  * @param [in]  port            - logical port
   5855  * @param [in]  enable        - 
   5856  */
   5857 int pm4x25_port_duplex_set(int unit, int port, pm_info_t pm_info,int enable)
   5858 {
   5859     return (clmac_duplex_set (unit, port, enable)); 
   5860 }
   5861 
   5862 
   5863 /*! 
   5864  * pm4x25_port_duplex_get
   5865  *
   5866  * @brief duplex get. 
   5867  *
   5868  * @param [in]  unit            - unit id
   5869  * @param [in]  port            - logical port
   5870  * @param [in]  vlan_tag        - 
   5871  */
   5872 int pm4x25_port_duplex_get(int unit, int port, pm_info_t pm_info, int* enable)
   5873 {
   5874     return (clmac_duplex_get (unit, port, enable)); 
   5875 }
   5876 
   5877 /*!
   5878  * pm4x25_port_speed_get
   5879  *
   5880  * @brief duplex get.
   5881  *
   5882  * @param [in]  unit            - unit id
   5883  * @param [in]  port            - logical port
   5884  * @param [in]  speed         -
   5885  */
   5886 int pm4x25_port_speed_get(int unit, int port, pm_info_t pm_info, int* speed)
   5887 {
   5888     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5889     phymod_phy_inf_config_t config;
   5890     int nof_phys, rv;
   5891 
   5892     rv = portmod_port_chain_phy_access_get(unit, port, pm_info,
   5893                                            phy_access ,(1+MAX_PHYN),
   5894                                            &nof_phys);
   5895     if (rv) return(rv);
   5896 
   5897     rv = phymod_phy_interface_config_get(&phy_access[0], 0,0,  &config);
   5898     if (rv) return (rv);
   5899 
   5900     *speed = config.data_rate;
   5901     return (rv);
   5902 }
   5903 
   5904 int pm4x25_port_phy_reg_read(int unit, int port, pm_info_t pm_info, int lane, int flags, int reg_addr, uint32* value)
   5905 {
   5906     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5907     int nof_phys;
   5908     SOC_INIT_FUNC_DEFS;
   5909 
   5910     _SOC_IF_ERR_EXIT
   5911         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5912                                           phy_access ,(1+MAX_PHYN),
   5913                                            &nof_phys));
   5914     _SOC_IF_ERR_EXIT
   5915         (portmod_port_phychain_reg_read(unit, port, phy_access,
   5916                                         nof_phys, lane, flags, reg_addr,value));
   5917 exit:
   5918     SOC_FUNC_RETURN;
   5919 }
   5920 
   5921 int pm4x25_port_phy_reg_write(int unit, int port, pm_info_t pm_info, int lane, int flags, int reg_addr, uint32 value)
   5922 {
   5923     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5924     int nof_phys;
   5925     SOC_INIT_FUNC_DEFS;
   5926 
   5927     _SOC_IF_ERR_EXIT
   5928         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   5929                                           phy_access ,(1+MAX_PHYN),
   5930                                            &nof_phys));
   5931     _SOC_IF_ERR_EXIT
   5932         (portmod_port_phychain_reg_write(unit, port, phy_access,
   5933                                          nof_phys, lane, flags, reg_addr,value));
   5934 exit:
   5935     SOC_FUNC_RETURN;
   5936 }
   5937 
   5938 int pm4x25_port_reset_set (int unit, int port, pm_info_t pm_info, 
   5939                            int reset_mode, int opcode, int direction)
   5940 {
   5941     int port_index, rv;
   5942     uint32 bitmap;
   5943 
   5944     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5945     if (SOC_FAILURE(rv)) {
   5946          return (rv);
   5947     }
   5948 
   5949     if (PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5950         return(SOC_E_UNAVAIL);
   5951     } 
   5952     return(portmod_phy_port_reset_set (unit, port, pm_info, reset_mode, opcode, direction));
   5953 }
   5954 
   5955 int pm4x25_port_reset_get (int unit, int port, pm_info_t pm_info, 
   5956                            int reset_mode, int opcode, int* direction)
   5957 {
   5958     int port_index, rv;
   5959     uint32 bitmap;
   5960 
   5961     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   5962     if (SOC_FAILURE(rv)) {
   5963          return (rv);
   5964     }
   5965 
   5966     if (PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   5967         return(SOC_E_UNAVAIL);
   5968     } 
   5969     return(portmod_phy_port_reset_get (unit, port, pm_info, reset_mode, opcode, direction));
   5970 }
   5971 
   5972 /*Port remote Adv get*/
   5973 int pm4x25_port_adv_remote_get (int unit, int port, pm_info_t pm_info, 
   5974                                 int* ability_mask)
   5975 {
   5976     return (0);
   5977 }
   5978 
   5979 /*get port fec enable*/
   5980 int pm4x25_port_fec_enable_get(int unit, int port, pm_info_t pm_info, 
   5981                                uint32 phy_flags,  uint32_t* enable)
   5982 {
   5983     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5984     int   nof_phys = 0;
   5985 
   5986     SOC_INIT_FUNC_DEFS;
   5987 
   5988     _SOC_IF_ERR_EXIT
   5989         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5990                                           phy_access ,(1+MAX_PHYN),
   5991                                            &nof_phys));
   5992 
   5993     _SOC_IF_ERR_EXIT
   5994         (portmod_port_phychain_fec_enable_get(unit, port, phy_access, nof_phys, phy_flags, enable));
   5995 
   5996 exit:
   5997     SOC_FUNC_RETURN;
   5998 }
   5999 
   6000 /*set port fec enable*/
   6001 int pm4x25_port_fec_enable_set(int unit, int port, pm_info_t pm_info, 
   6002                                uint32 phy_flags, uint32_t enable)
   6003 {
   6004     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6005     int   nof_phys = 0;
   6006 
   6007     SOC_INIT_FUNC_DEFS;
   6008 
   6009     _SOC_IF_ERR_EXIT
   6010         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6011                                           phy_access ,(1+MAX_PHYN),
   6012                                            &nof_phys));
   6013 
   6014     _SOC_IF_ERR_EXIT
   6015         (portmod_port_phychain_fec_enable_set(unit, port, phy_access, nof_phys, phy_flags, enable));
   6016 
   6017 exit:
   6018     SOC_FUNC_RETURN;
   6019 }
   6020 
   6021 /*get port auto negotiation local ability*/
   6022 int pm4x25_port_ability_advert_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags,
   6023                                  portmod_port_ability_t* ability)
   6024 {
   6025     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6026     int   nof_phys = 0;
   6027     phymod_autoneg_ability_t    an_ability;
   6028     portmod_port_ability_t port_ability;
   6029     int phy_index, xphy_id, is_legacy_phy = 0;
   6030 
   6031     SOC_INIT_FUNC_DEFS;
   6032 
   6033     _SOC_IF_ERR_EXIT
   6034         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6035                                           phy_access ,(1+MAX_PHYN),
   6036                                            &nof_phys));
   6037 
   6038     _SOC_IF_ERR_EXIT
   6039         (portmod_port_phychain_autoneg_ability_get(unit, port, phy_access,
   6040                                                        nof_phys, phy_flags, &an_ability,
   6041                                                        &port_ability));
   6042     phy_index = nof_phys -1;
   6043     if (phy_index) {
   6044         xphy_id = phy_access[phy_index].access.addr;
   6045         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   6046         if (is_legacy_phy) {
   6047             sal_memcpy(ability, &port_ability, sizeof(portmod_port_ability_t));
   6048         }
   6049     } 
   6050     if (!is_legacy_phy) {
   6051         portmod_common_phy_to_port_ability(&an_ability, ability);
   6052     }
   6053 
   6054 exit:
   6055     SOC_FUNC_RETURN;
   6056 }
   6057 
   6058 /*
   6059  * Function:
   6060  *     _pm4x25_port_to_phy_ability
   6061  * Purpose:
   6062  *      This function will translate the portAbility request, which passed
   6063  *      from BCM api to anAbility format required by phymod api.
   6064  *
   6065  * Parameters:
   6066  *      portAbility         -(IN)  port an ability request from BCM Api
   6067  *      anAbility           -(OUT) phymod an ability to phymod api.
   6068  *      port_num_lanes      -(IN)  number of lane
   6069  *      line_interface      -(IN)  line interface
   6070  *      cx4_10g             -(IN)  cx4 port
   6071  *      an_cl72             -(IN)  an cl72 configuration
   6072  *      an_fec              -(IN)  fec configuration
   6073  *      an_hg_mode          -(IN)  hg_mode
   6074  * Returns:
   6075  *      None
   6076  */
   6077 void _pm4x25_port_to_phy_ability (portmod_port_ability_t *portAbility,
   6078                                   phymod_autoneg_ability_t *anAbility,
   6079                                   int port_num_lanes,
   6080                                   int line_interface,
   6081                                   int cx4_10g,
   6082                                   int an_cl72,
   6083                                   int an_fec,
   6084                                   int hg_mode,
   6085                                   phymod_an_mode_type_t an_mode)
   6086 {
   6087     uint32_t                  an_tech_ability   = 0;
   6088     uint32_t                  an_bam37_ability  = 0;
   6089     uint32_t                  an_bam73_ability  = 0;
   6090     _shr_port_mode_t          speed_full_duplex = portAbility->speed_full_duplex;
   6091 
   6092     phymod_autoneg_ability_t_init(anAbility);
   6093 
   6094     /*
   6095      * an_tech_ability
   6096      */
   6097     if (port_num_lanes == 4) {
   6098 
   6099         if (speed_full_duplex & SOC_PA_SPEED_100GB) {
   6100             if (portAbility->medium) {
   6101                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6102                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   6103                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6104                     PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   6105                 } else {
   6106                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   6107                 }
   6108             } else {
   6109                 if (line_interface == SOC_PORT_IF_CR4 ) {
   6110                     PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   6111                 } else {
   6112                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   6113                 }
   6114             }
   6115         }
   6116 
   6117         if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   6118             if (portAbility->medium) {
   6119                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6120                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   6121                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6122                     PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   6123                 } else {
   6124                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   6125                 }
   6126             } else {
   6127                 if (line_interface == SOC_PORT_IF_CR4) {
   6128                     PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   6129                 } else {
   6130                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   6131                 }
   6132             }
   6133         }
   6134 
   6135         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   6136             PHYMOD_AN_CAP_10G_KX4_SET(an_tech_ability);
   6137         }
   6138 
   6139     } else if (port_num_lanes == 1) {
   6140         /* When in MSA AN mode : We do not want to populate the base page with IEEE mode.
   6141           * If we do, then IEEE takes the higher priority. Hence we add the following exception
   6142           * block for each 25G case below: if(phymod_AN_MODE_MSA!=an_mode)  */
   6143         if ((speed_full_duplex & SOC_PA_SPEED_25GB) && (phymod_AN_MODE_MSA != an_mode)) {
   6144             if (portAbility->medium) {
   6145                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6146                     if (portAbility->channel & SOC_PA_CHANNEL_SHORT) {
   6147                         PHYMOD_AN_CAP_25G_KRS1_SET(an_tech_ability);
   6148                     } else {
   6149                         PHYMOD_AN_CAP_25G_KR1_SET(an_tech_ability);
   6150                     }
   6151                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6152                     if (portAbility->channel & SOC_PA_CHANNEL_SHORT) {
   6153                         PHYMOD_AN_CAP_25G_CRS1_SET(an_tech_ability);
   6154                     } else {
   6155                         PHYMOD_AN_CAP_25G_CR1_SET(an_tech_ability);
   6156                     }
   6157                 } else {
   6158                     /*
   6159                      *  This is essentially a Fiber mode which is not
   6160                      *  a valid case for normal operation, but port
   6161                      *  but during intialization time, it will
   6162                      *  use fiber mode as it is default.
   6163                      */
   6164                     if (portAbility->channel & SOC_PA_CHANNEL_SHORT) {
   6165                         PHYMOD_AN_CAP_25G_KRS1_SET(an_tech_ability);
   6166                     } else {
   6167                         PHYMOD_AN_CAP_25G_KR1_SET(an_tech_ability);
   6168                     }
   6169                 }
   6170             } else {
   6171                 if (line_interface == SOC_PORT_IF_CR ) {
   6172                     if (portAbility->channel & SOC_PA_CHANNEL_SHORT) {
   6173                         PHYMOD_AN_CAP_25G_CRS1_SET(an_tech_ability);
   6174                     } else {
   6175                         PHYMOD_AN_CAP_25G_CR1_SET(an_tech_ability);
   6176                     }
   6177                 } else {
   6178                     if (portAbility->channel & SOC_PA_CHANNEL_SHORT) {
   6179                         PHYMOD_AN_CAP_25G_KRS1_SET(an_tech_ability);
   6180                     } else {
   6181                         PHYMOD_AN_CAP_25G_KR1_SET(an_tech_ability);
   6182                     }
   6183                 }
   6184             }
   6185         }
   6186 
   6187         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   6188             PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
   6189         }
   6190 
   6191         if (speed_full_duplex & SOC_PA_SPEED_1000MB) {
   6192             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
   6193         }
   6194 
   6195         if (speed_full_duplex & SOC_PA_SPEED_5000MB) {
   6196             PHYMOD_AN_CAP_5G_KR1_SET(an_tech_ability);
   6197         }
   6198         if (speed_full_duplex & SOC_PA_SPEED_2500MB) {
   6199             PHYMOD_AN_CAP_2P5G_X_SET(an_tech_ability);
   6200         }
   6201     }
   6202 
   6203     /*
   6204      * an_bam73_ability
   6205      */
   6206     if (port_num_lanes == 4) {
   6207         if (speed_full_duplex & SOC_PA_SPEED_50GB) {
   6208             if (portAbility->medium) {
   6209                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6210                     PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_bam73_ability);
   6211                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6212                     PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_bam73_ability);
   6213                 } else {
   6214                     PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_bam73_ability);
   6215                 }
   6216             } else {
   6217                 if (line_interface == SOC_PORT_IF_CR4 ) {
   6218                     PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_bam73_ability);
   6219                 } else {
   6220                     PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_bam73_ability);
   6221                 }
   6222             }
   6223         }
   6224     } else if (port_num_lanes == 2) {
   6225         if (speed_full_duplex & SOC_PA_SPEED_20GB) {
   6226             if (portAbility->medium) {
   6227                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6228                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   6229                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6230                     PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
   6231                 } else {
   6232                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   6233                 }
   6234             } else {
   6235                 if (line_interface == SOC_PORT_IF_CR2) {
   6236                     PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
   6237                 } else {
   6238                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   6239                 }
   6240             }
   6241         }
   6242         if (speed_full_duplex & SOC_PA_SPEED_50GB) {
   6243             if (portAbility->medium) {
   6244                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6245                     PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_bam73_ability);
   6246                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6247                     PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_bam73_ability);
   6248                 } else {
   6249                     PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_bam73_ability);
   6250                 }
   6251             } else {
   6252                 if (line_interface == SOC_PORT_IF_CR2) {
   6253                     PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_bam73_ability);
   6254                 } else {
   6255                     PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_bam73_ability);
   6256                 }
   6257             }
   6258         }
   6259         if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   6260             if (portAbility->medium) {
   6261                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6262                     PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_bam73_ability);
   6263                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6264                     PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_bam73_ability);
   6265                 } else {
   6266                     PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_bam73_ability);
   6267                 }
   6268             } else {
   6269                 if (line_interface == SOC_PORT_IF_CR2) {
   6270                     PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_bam73_ability);
   6271                 } else {
   6272                     PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_bam73_ability);
   6273                 }
   6274             }
   6275         }
   6276     } else {
   6277         /* port_num_lanes == 1 */
   6278         if (speed_full_duplex & SOC_PA_SPEED_25GB) {
   6279             if (portAbility->medium) {
   6280                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   6281                     PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_bam73_ability);
   6282                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   6283                     PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_bam73_ability);
   6284                 } else {
   6285                     PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_bam73_ability);
   6286                 }
   6287             } else {
   6288                 if (line_interface == SOC_PORT_IF_CR) {
   6289                     PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_bam73_ability);
   6290                 } else {
   6291                     PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_bam73_ability);
   6292                 }
   6293             }
   6294 
   6295         }
   6296     }
   6297 
   6298     /*
   6299      * an_bam37_ability is not supported in PM4x25 (TSCF)
   6300      */
   6301 
   6302     anAbility->an_cap = an_tech_ability;
   6303     anAbility->cl73bam_cap = an_bam73_ability;
   6304     anAbility->cl37bam_cap = an_bam37_ability;
   6305 
   6306     switch (portAbility->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
   6307     case SOC_PA_PAUSE_TX:
   6308         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
   6309         break;
   6310     case SOC_PA_PAUSE_RX:
   6311         /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
   6312         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
   6313         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
   6314         break;
   6315     case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
   6316         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
   6317         break;
   6318     }
   6319 
   6320     if ((speed_full_duplex & SOC_PA_SPEED_10MB) ||
   6321         (speed_full_duplex & SOC_PA_SPEED_100MB) ||
   6322         (speed_full_duplex & SOC_PA_SPEED_1000MB)) {
   6323         if (portAbility->medium) {
   6324             if (!(portAbility->medium & SOC_PA_MEDIUM_FIBER)) {
   6325                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
   6326             } else {
   6327                 if (portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
   6328                     PHYMOD_AN_CAP_100M_SET(anAbility->an_cap);
   6329                 }
   6330             }
   6331         } else {
   6332             if (SOC_PORT_IF_SGMII == line_interface) {
   6333                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
   6334             } else {
   6335                 if (portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
   6336                     PHYMOD_AN_CAP_100M_SET(anAbility->an_cap);
   6337                 }
   6338             }
   6339         }
   6340     }
   6341 
   6342     /* next check if we need to set cl37 attribute */
   6343     if (an_cl72) {
   6344         anAbility->an_cl72 = 1;
   6345     }
   6346 
   6347     if (hg_mode) {
   6348         anAbility->an_hg2 = 1;
   6349     }
   6350 
   6351     /*
   6352      * check if Cl74 fec is requested from AN BCM api.
   6353      * SOC_PA_FEC_NONE mean that FEC be off.  If that bit
   6354      * is set, it will ignore both FEC_CL74 and FEC_CL91 setting.
   6355      */
   6356     if (portAbility->fec & SOC_PA_FEC_NONE) {
   6357         PHYMOD_AN_FEC_OFF_SET(anAbility->an_fec);
   6358     } else {
   6359         if ((an_fec == 1) || (portAbility->fec & SOC_PA_FEC_CL74)) {
   6360             /* The 'phy_an_fec=1' and FEC CL74 ability are all the phymod FEC CL74. */
   6361             PHYMOD_AN_FEC_CL74_SET(anAbility->an_fec);
   6362         }
   6363 
   6364         if ((an_fec == 2) || (portAbility->fec & SOC_PA_FEC_CL91)) {
   6365             /* The 'phy_an_fec=2' and FEC CL91 ability are all the phymod FEC CL74. */
   6366             PHYMOD_AN_FEC_CL91_SET(anAbility->an_fec);
   6367         }
   6368     }
   6369 
   6370 }
   6371 
   6372 int pm4x25_port_ability_advert_set(int unit, int port, pm_info_t pm_info, uint32 phy_flags, 
   6373                                  portmod_port_ability_t* ability)
   6374 {
   6375     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6376     int nof_phys = 0, port_index = 0, rv = 0;    
   6377     int port_num_lanes, line_interface, cx4_10g;
   6378     int an_cl72, an_fec, hg_mode;    
   6379     portmod_port_ability_t      port_ability;
   6380     phymod_autoneg_ability_t    an_ability;
   6381     uint32_t bitmap = 0, interface_modes;
   6382     int                       line_side;
   6383     phymod_an_mode_type_t  an_mode;
   6384 
   6385     SOC_INIT_FUNC_DEFS;
   6386 
   6387     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap));   
   6388 
   6389     _SOC_IF_ERR_EXIT
   6390         (pm4x25_port_ability_local_get(unit, port, pm_info, phy_flags, &port_ability));
   6391 
   6392     /* Make sure to advertise only abilities supported by the port */
   6393     port_ability.pause             &= ability->pause;
   6394     port_ability.interface         &= ability->interface;
   6395     port_ability.medium            &= ability->medium;
   6396     port_ability.eee               &= ability->eee;
   6397     port_ability.loopback          &= ability->loopback;
   6398     port_ability.flags             &= ability->flags;
   6399     port_ability.speed_half_duplex &= ability->speed_half_duplex;
   6400     port_ability.speed_full_duplex &= ability->speed_full_duplex;
   6401     port_ability.fec               &= ability->fec;
   6402     port_ability.channel           &= ability->channel;
   6403 
   6404     /* coverity[Out-of-bounds access:FALSE] */
   6405     SHR_BITCOUNT_RANGE(&bitmap, port_num_lanes, 0, PM4X25_LANES_PER_CORE);
   6406     rv = PM4x25_CX4_10G_GET(unit, pm_info, &cx4_10g, port_index);
   6407     _SOC_IF_ERR_EXIT(rv);
   6408     rv = PM4x25_AN_CL72_GET(unit, pm_info, &an_cl72, port_index);
   6409     _SOC_IF_ERR_EXIT(rv);
   6410     rv = PM4x25_AN_FEC_GET(unit, pm_info, &an_fec, port_index);
   6411     _SOC_IF_ERR_EXIT(rv);
   6412     rv = PM4x25_INTERFACE_TYPE_GET(unit, pm_info, &line_interface, port_index);
   6413     _SOC_IF_ERR_EXIT(rv);
   6414     rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   6415                                     port_index);
   6416     _SOC_IF_ERR_EXIT(rv);
   6417     rv = PM4x25_AN_MODE_GET(unit,pm_info,&an_mode,port_index);
   6418     hg_mode = (interface_modes & PHYMOD_INTF_MODES_HIGIG)? 1: 0;
   6419     
   6420     /* 
   6421      * Get the number of line side lanes.
   6422      */
   6423 
   6424     line_side = TRUE ;
   6425     _SOC_IF_ERR_EXIT
   6426         (pm4x25_port_lane_count_get(unit, port, pm_info,
   6427                                     line_side, &port_num_lanes));
   6428     
   6429     _pm4x25_port_to_phy_ability(&port_ability, &an_ability,
   6430                                        port_num_lanes, line_interface, cx4_10g,
   6431                                 an_cl72, an_fec, hg_mode, an_mode);
   6432 
   6433     _SOC_IF_ERR_EXIT
   6434         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6435                                           phy_access ,(1+MAX_PHYN),
   6436                                            &nof_phys));
   6437 
   6438     rv = PM4x25_AN_MASTER_LANE_GET(unit, pm_info, &an_ability.an_master_lane, port_index);
   6439     _SOC_IF_ERR_EXIT(rv);
   6440 
   6441     _SOC_IF_ERR_EXIT
   6442         (portmod_port_phychain_autoneg_ability_set(unit, port, phy_access,
   6443                                           nof_phys, phy_flags, &an_ability,
   6444                                           &port_ability));
   6445     LOG_VERBOSE(BSL_LS_BCM_PORT,
   6446                 (BSL_META_U(unit,
   6447                      "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x orig(HD=0x%08x, FD=0x%08x) \n"
   6448                      "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
   6449                      port_ability.speed_half_duplex,
   6450                      port_ability.speed_full_duplex,
   6451                      port_ability.pause,
   6452                      ability->speed_half_duplex,
   6453                      ability->speed_full_duplex,
   6454                      port_ability.interface,
   6455                      port_ability.medium, port_ability.loopback,
   6456                      port_ability.flags));
   6457 exit:
   6458     SOC_FUNC_RETURN;
   6459 }
   6460 
   6461 /*Port ability remote Adv get*/
   6462 int pm4x25_port_ability_remote_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, 
   6463                                        portmod_port_ability_t* ability)
   6464 {
   6465     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6466     int                         nof_phys;
   6467     phymod_autoneg_ability_t    an_ability;
   6468     int phy_index, xphy_id, is_legacy_phy = 0;
   6469 
   6470     SOC_INIT_FUNC_DEFS;
   6471 
   6472     _SOC_IF_ERR_EXIT
   6473         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6474                                           phy_access ,(1+MAX_PHYN),
   6475                                            &nof_phys));
   6476 
   6477     phy_index = nof_phys -1;
   6478     if (phy_index) {
   6479         xphy_id = phy_access[phy_index].access.addr;
   6480         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   6481     }
   6482     _SOC_IF_ERR_EXIT
   6483         (portmod_port_phychain_autoneg_remote_ability_get(unit, port,  
   6484                     phy_access, nof_phys, phy_flags, &an_ability, ability));
   6485     if (!is_legacy_phy) {
   6486     portmod_common_phy_to_port_ability(&an_ability, ability);
   6487     }
   6488 
   6489 exit:
   6490     SOC_FUNC_RETURN;
   6491 }
   6492 
   6493 int _clport_rx_control_set(int unit, int port, int value)
   6494 {
   6495     int rv = SOC_E_UNAVAIL;
   6496     uint32 rval32 = 0;
   6497 
   6498     if (SOC_REG_IS_VALID(unit,CLPORT_MAC_RSV_MASKr)) {
   6499         rv = READ_CLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   6500         if (SOC_SUCCESS(rv)) {
   6501             /* CLPORT_MAC_RSV_MASK: Bit 11 Control Frame recieved
   6502              * Enable  Control Frame : Set 0. Packet go through
   6503              * Disable Control Frame : Set 1. Packet is purged.
   6504              */
   6505             if(value) {
   6506                 rval32 &= ~(1 << 11);
   6507             } else {
   6508                 rval32 |= (1 << 11);
   6509             }
   6510             rv = WRITE_CLPORT_MAC_RSV_MASKr(unit, port, rval32);
   6511         }
   6512     }
   6513 
   6514     return rv;
   6515 }
   6516 
   6517 int pm4x25_port_rx_control_set (int unit, int port, pm_info_t pm_info,
   6518                                 const portmod_rx_control_t* rx_ctrl)
   6519 {
   6520     int phy_acc;
   6521     uint32 reg_val;
   6522 
   6523     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6524     SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_RSV_MASKr(unit, phy_acc, &reg_val));
   6525 
   6526     if (rx_ctrl->flags & PORTMOD_MAC_PASS_CONTROL_FRAME) {
   6527         if(rx_ctrl->pass_control_frames){
   6528             reg_val &= ~(1 << 11);
   6529         } else{
   6530             reg_val |= (1 << 11);
   6531         }
   6532     }
   6533 
   6534     if (rx_ctrl->flags & PORTMOD_MAC_PASS_PFC_FRAME) {
   6535         if(rx_ctrl->pass_pfc_frames){
   6536             reg_val &= ~(1 << 18);
   6537         } else{
   6538             reg_val |= (1 << 18);
   6539         }
   6540     }
   6541 
   6542     if (rx_ctrl->flags & PORTMOD_MAC_PASS_PAUSE_FRAME) {
   6543         if(rx_ctrl->pass_pause_frames){
   6544             reg_val &= ~(1 << 12);
   6545         } else{
   6546             reg_val |= (1 << 12);
   6547         }
   6548     }
   6549 
   6550     SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_RSV_MASKr(unit, phy_acc, reg_val));
   6551 
   6552     return (SOC_E_NONE);
   6553 }
   6554 
   6555 int pm4x25_port_rx_control_get (int unit, int port, pm_info_t pm_info,
   6556                                 portmod_rx_control_t* rx_ctrl)
   6557 {
   6558     int phy_acc;
   6559     uint32 reg_val;
   6560 
   6561     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6562     SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_RSV_MASKr(unit, phy_acc, &reg_val));
   6563 
   6564     rx_ctrl->pass_control_frames = ((reg_val & 0x800) >> 11) ? 0 : 1;
   6565     rx_ctrl->pass_pfc_frames = ((reg_val & 0x40000) >> 18) ? 0 : 1;
   6566     rx_ctrl->pass_pause_frames = ((reg_val & 0x1000) >> 12) ? 0 : 1;
   6567 
   6568     return (SOC_E_NONE);
   6569 }
   6570 
   6571 int pm4x25_port_tx_average_ipg_set (int unit, int port, pm_info_t pm_info, int value)
   6572 {
   6573     return (clmac_tx_average_ipg_set(unit, port, value));
   6574 }
   6575 
   6576 int pm4x25_port_tx_average_ipg_get (int unit, int port, pm_info_t pm_info, int* value)
   6577 {
   6578     return (clmac_tx_average_ipg_get(unit, port, value));
   6579 }
   6580 
   6581 int pm4x25_port_update(int unit, int port, pm_info_t pm_info, const portmod_port_update_control_t* update_control)
   6582 {
   6583     int link, flags = 0;
   6584     int duplex = 0, tx_pause = 0, rx_pause = 0;
   6585     phymod_autoneg_status_t autoneg;
   6586     portmod_pause_control_t pause_control;
   6587     portmod_port_ability_t local_advert, remote_advert;
   6588     portmod_port_interface_config_t interface_config;
   6589     int port_index, ref_clock, max_speed;
   6590     uint32_t                    bitmap;
   6591     phymod_phy_inf_config_t     phy_interface_config;
   6592     soc_port_if_t   interface = SOC_PORT_IF_NULL;
   6593     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6594     int nof_phys, is_clmac_en;
   6595     portmod_port_ts_adjust_t ts_adjust;
   6596     pm_version_t pm_version;
   6597     uint32 port_dynamic_state = 0;
   6598     int mac_ts_enable;
   6599     SOC_INIT_FUNC_DEFS;
   6600 
   6601     _SOC_IF_ERR_EXIT(phymod_autoneg_status_t_init(&autoneg));
   6602     _SOC_IF_ERR_EXIT(portmod_pause_control_t_init(unit, &pause_control));
   6603     sal_memset(&local_advert, 0, sizeof(portmod_port_ability_t));
   6604     sal_memset(&remote_advert, 0, sizeof(portmod_port_ability_t));
   6605     sal_memset(&ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   6606 
   6607     _SOC_IF_ERR_EXIT
   6608         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   6609                                            phy_access ,(1+MAX_PHYN),
   6610                                            &nof_phys));
   6611 
   6612     if(update_control->link_status == -1) {
   6613         _SOC_IF_ERR_EXIT(pm4x25_port_link_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &link));
   6614     } else {
   6615         link = update_control->link_status;
   6616     }
   6617 
   6618     _SOC_IF_ERR_EXIT(pm4x25_port_autoneg_status_get(unit, port, pm_info, &autoneg));
   6619 
   6620     /*
   6621      * Update the interface type stored in the SW database when the port is in the AN mode
   6622      * and link is up. The update has to be done before any possible early return in this
   6623      * function or portmod_port_interface_config_get() will get outdated interface type
   6624      * causing "BCM.0> ps" to show outdated interface types in the AN mode.
   6625      */
   6626     if (link && autoneg.enabled && autoneg.locked) {
   6627         _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_interface_config));
   6628         _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   6629         _SOC_IF_ERR_EXIT(PM4x25_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index));
   6630 
   6631         ref_clock = PM_4x25_INFO(pm_info)->ref_clk;
   6632         phy_interface_config.data_rate =  max_speed;
   6633         phy_interface_config.ref_clock =  ref_clock;
   6634         _SOC_IF_ERR_EXIT
   6635             (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   6636                                                         0, ref_clock, &phy_interface_config,
   6637                                                         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   6638         _SOC_IF_ERR_EXIT
   6639             (portmod_intf_from_phymod_intf(unit, phy_interface_config.interface_type, &interface));
   6640         _SOC_IF_ERR_EXIT
   6641             (PM4x25_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   6642         _SOC_IF_ERR_EXIT
   6643             (PM4x25_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   6644     }
   6645 
   6646     if (PORTMOD_PORT_UPDATE_F_UPDATE_SERDES_LINK_GET(update_control)){
   6647         /*
   6648          * PORTMOD_PORT_UPDATE_F_UPDATE_SERDES_LINK is set for XGS devices. Since XGS devices
   6649          * already update their MAC registers elsewhere, there is an early return below to
   6650          * avoid redundant works.
   6651          */
   6652         return (SOC_E_NONE);
   6653     }
   6654 
   6655     if(!link) {
   6656         /* PHY is down.  Disable the MAC. */
   6657         if (PORTMOD_PORT_UPDATE_F_DISABLE_MAC_GET(update_control)) {
   6658             _SOC_IF_ERR_EXIT(clmac_enable_set(unit, port, 0, 0));
   6659         }
   6660     } else {
   6661         _SOC_IF_ERR_EXIT(clmac_enable_get(unit, port, 0, &is_clmac_en));
   6662         if (is_clmac_en == 0) {
   6663         _SOC_IF_ERR_EXIT(clmac_enable_set(unit, port, 0, 1));
   6664         if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   6665             _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 0));
   6666         }
   6667         }
   6668         /* In case of AN - need to update MAC settings*/
   6669         if(autoneg.enabled && autoneg.locked) {
   6670             _SOC_IF_ERR_EXIT(pm4x25_port_interface_config_get(unit, port, pm_info, &interface_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   6671             /* update MAC */
   6672             flags = CLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   6673             _SOC_IF_ERR_EXIT(clmac_speed_set(unit, port, flags, interface_config.speed));
   6674 
   6675             /*Set MAC Timestamp Delay*/
   6676             if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, CLMAC_TS_DISABLEf)) {
   6677                 _SOC_IF_ERR_EXIT
   6678                     (pm4x25_port_mac_timestamp_enable_get(unit, port, pm_info, &mac_ts_enable));
   6679             } else {
   6680                 mac_ts_enable = 1;
   6681             }
   6682             if (mac_ts_enable) {
   6683                 _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index, &bitmap));
   6684                 _SOC_IF_ERR_EXIT(PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info, &port_dynamic_state, port_index));
   6685                 if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   6686                     _SOC_IF_ERR_EXIT(_pm4x25_port_timestamp_adjust_wb_get(unit, port, pm_info, interface_config.speed, &ts_adjust));
   6687                     _SOC_IF_ERR_EXIT(clmac_timestamp_delay_set(unit, port, ts_adjust));
   6688                 }
   6689                 _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   6690                 if (!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   6691                     _SOC_IF_ERR_EXIT(clmac_timestamp_byte_adjust_set(unit, port, 0, interface_config.speed));
   6692                 }
   6693             }
   6694 
   6695             if(PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   6696                 _SOC_IF_ERR_EXIT(pm4x25_port_soft_reset(unit, port, pm_info, 0));
   6697             }
   6698             /* update pause in MAC on the base of local and remote pause ability*/
   6699             _SOC_IF_ERR_EXIT(pm4x25_port_duplex_get(unit, port, pm_info, &duplex));
   6700             _SOC_IF_ERR_EXIT(pm4x25_port_ability_advert_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &local_advert));
   6701             _SOC_IF_ERR_EXIT(pm4x25_port_ability_remote_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &remote_advert));
   6702             /* IEEE 802.3 Flow Control Resolution.
   6703                    * Please see $SDK/doc/pause-resolution.txt for more information. */
   6704             if (duplex) {
   6705                 tx_pause = \
   6706                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   6707                     (local_advert.pause & SOC_PA_PAUSE_RX)) || \
   6708                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   6709                     !(remote_advert.pause & SOC_PA_PAUSE_TX) && \
   6710                     (local_advert.pause & SOC_PA_PAUSE_TX)); 
   6711                 rx_pause = \
   6712                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   6713                     (local_advert.pause & SOC_PA_PAUSE_RX)) || \
   6714                     ((local_advert.pause & SOC_PA_PAUSE_RX) && \
   6715                     (remote_advert.pause & SOC_PA_PAUSE_TX) && \
   6716                     !(local_advert.pause & SOC_PA_PAUSE_TX));
   6717             }
   6718             else {
   6719                 rx_pause = tx_pause = 0;
   6720             }
   6721             _SOC_IF_ERR_EXIT(pm4x25_port_pause_control_get(unit, port, pm_info, &pause_control));
   6722             if ((pause_control.rx_enable != rx_pause) || (pause_control.tx_enable != tx_pause)) {
   6723                 pause_control.rx_enable = rx_pause;
   6724                 pause_control.tx_enable = tx_pause;
   6725                 _SOC_IF_ERR_EXIT(pm4x25_port_pause_control_set(unit, port, pm_info, &pause_control));
   6726             }
   6727         }
   6728         _SOC_IF_ERR_EXIT(PM_DRIVER(pm_info)->f_portmod_port_lag_failover_status_toggle(unit, port, pm_info));
   6729     }
   6730 
   6731 exit:
   6732     SOC_FUNC_RETURN;
   6733 }
   6734 
   6735 int pm4x25_port_drv_name_get (int unit, int port, pm_info_t pm_info, 
   6736                               char* buf, int len)
   6737 {
   6738     strncpy(buf, "PM4X25 Driver", len);
   6739     return (SOC_E_NONE);
   6740 }
   6741 
   6742 int pm4x25_port_local_fault_status_clear(int unit, int port, pm_info_t pm_info)
   6743 {
   6744     int lcl_fault, rmt_fault;
   6745 
   6746     SOC_IF_ERROR_RETURN (pm4x25_port_clear_rx_lss_status_get (unit, port, pm_info, &lcl_fault, &rmt_fault));
   6747     if (lcl_fault) {
   6748         SOC_IF_ERROR_RETURN (pm4x25_port_clear_rx_lss_status_set(unit, port, pm_info, 0, rmt_fault)); 
   6749     }
   6750     return (pm4x25_port_clear_rx_lss_status_set (unit, port, pm_info, 1, rmt_fault));
   6751 
   6752 }
   6753 
   6754 int pm4x25_port_remote_fault_status_clear(int unit, int port, pm_info_t pm_info)
   6755 {
   6756     int lcl_fault, rmt_fault;
   6757 
   6758     SOC_IF_ERROR_RETURN (pm4x25_port_clear_rx_lss_status_get (unit, port, pm_info, &lcl_fault, &rmt_fault));
   6759     if (rmt_fault) {
   6760         SOC_IF_ERROR_RETURN (pm4x25_port_clear_rx_lss_status_set(unit, port, pm_info, lcl_fault, 0)); 
   6761     }
   6762     return (pm4x25_port_clear_rx_lss_status_set (unit, port, pm_info, lcl_fault, 1));
   6763 }
   6764 
   6765 int pm4x25_port_clear_rx_lss_status_set (int unit, soc_port_t port, 
   6766                            pm_info_t pm_info, int lcl_fault, int rmt_fault)
   6767 {
   6768     return (clmac_clear_rx_lss_status_set (unit, port, lcl_fault, rmt_fault));
   6769 }
   6770 
   6771 int pm4x25_port_clear_rx_lss_status_get (int unit, soc_port_t port, 
   6772                            pm_info_t pm_info, int *lcl_fault, int *rmt_fault)
   6773 {
   6774     return (clmac_clear_rx_lss_status_get (unit, port, lcl_fault, rmt_fault));
   6775 }
   6776 
   6777 int pm4x25_port_lag_failover_status_toggle (int unit, soc_port_t port, pm_info_t pm_info)
   6778 {
   6779     int phy_acc;
   6780     uint32_t rval;
   6781     int link = 0;
   6782     soc_timeout_t to;
   6783 
   6784     SOC_INIT_FUNC_DEFS;
   6785 
   6786     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6787 
   6788     /* Link status to IPIPE is updated by H/W and driven based on both the
   6789      * rising edge of CLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and
   6790      * actual link up status from Serdes.
   6791      * In some loopback scenarios it may take longer time to see Serdes link up status.
   6792      */
   6793     soc_timeout_init(&to, 10000, 0);
   6794 
   6795     do {
   6796         _SOC_IF_ERR_EXIT(pm4x25_port_mac_link_get(unit, port, pm_info, &link));
   6797         if (link) {
   6798             break;
   6799         }
   6800     } while(!soc_timeout_check(&to));
   6801 
   6802     /* Toggle link_status_up bit to notify IPIPE on link up */
   6803     _SOC_IF_ERR_EXIT(READ_CLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, &rval));
   6804     soc_reg_field_set(unit, CLPORT_LAG_FAILOVER_CONFIGr, &rval, LINK_STATUS_UPf, 1);
   6805     _SOC_IF_ERR_EXIT(WRITE_CLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, rval));
   6806     soc_reg_field_set(unit, CLPORT_LAG_FAILOVER_CONFIGr, &rval, LINK_STATUS_UPf, 0);
   6807     _SOC_IF_ERR_EXIT(WRITE_CLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, rval));
   6808 
   6809 exit:
   6810     SOC_FUNC_RETURN;
   6811 }
   6812 
   6813 int pm4x25_port_lag_failover_loopback_set (int unit, soc_port_t port,
   6814                                         pm_info_t pm_info, int value)
   6815 {
   6816     return (clmac_lag_failover_loopback_set(unit, port, value));
   6817 }
   6818 
   6819 int pm4x25_port_lag_failover_loopback_get (int unit, soc_port_t port,
   6820                                         pm_info_t pm_info, int *value)
   6821 {
   6822     return(clmac_lag_failover_loopback_get(unit, port, value));
   6823 }
   6824 
   6825 int pm4x25_port_tx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   6826 {
   6827     return (clmac_tx_mac_sa_set(unit, port, mac_addr));
   6828 }
   6829 
   6830 int pm4x25_port_tx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   6831 {
   6832     return (clmac_tx_mac_sa_get(unit, port, mac_addr));
   6833 }
   6834 
   6835 int pm4x25_port_rx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   6836 {
   6837     return (clmac_rx_mac_sa_set(unit, port, mac_addr));
   6838 }
   6839 
   6840 int pm4x25_port_rx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   6841 {
   6842     return (clmac_rx_mac_sa_get(unit, port, mac_addr));
   6843 }
   6844 
   6845 int pm4x25_port_mode_get(int unit, soc_port_t port,
   6846                      pm_info_t pm_info, portmod_port_mode_info_t *mode)
   6847 {
   6848     int port_index, rv, phy_acc;
   6849     uint32 bitmap;
   6850 
   6851     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6852 
   6853     /* coverity[callee_ptr_arith:FALSE] */
   6854     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   6855     if (rv) return (rv);
   6856 
   6857     return (_clport_mode_get(unit, phy_acc, port_index, &mode->cur_mode, &mode->lanes));
   6858 }
   6859 
   6860 static int _clport_mode_set(int unit, int phy_acc, portmod_core_port_mode_t cur_mode)
   6861 {
   6862     uint32_t rval;
   6863     int      mode;
   6864 
   6865     SOC_INIT_FUNC_DEFS;
   6866 
   6867     switch (cur_mode) {
   6868         case portmodPortModeQuad:
   6869             mode = 0;
   6870             break;
   6871 
   6872         case portmodPortModeTri012:
   6873             mode = 1;
   6874             break;
   6875 
   6876         case portmodPortModeTri023:
   6877             mode = 2;
   6878             break;
   6879 
   6880         case portmodPortModeDual:
   6881             mode = 3;
   6882             break;
   6883 
   6884         case portmodPortModeSingle:
   6885             mode = 4;
   6886             break;
   6887 
   6888         default:
   6889             return SOC_E_FAIL;
   6890     }
   6891 
   6892     /* Toggle link bit to notify IPIPE on link up */
   6893     _SOC_IF_ERR_EXIT(READ_CLPORT_MODE_REGr(unit, phy_acc, &rval));
   6894 
   6895     soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, mode);
   6896     soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, mode);
   6897 
   6898     _SOC_IF_ERR_EXIT(WRITE_CLPORT_MODE_REGr(unit, phy_acc, rval));
   6899 
   6900 exit:
   6901     SOC_FUNC_RETURN;
   6902 }
   6903 
   6904 int pm4x25_port_mode_set(int unit, soc_port_t port,
   6905                      pm_info_t pm_info, const portmod_port_mode_info_t* mode)
   6906 {
   6907     int phy_acc;
   6908     SOC_INIT_FUNC_DEFS;
   6909 
   6910     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6911 
   6912     _SOC_IF_ERR_EXIT(_clport_mode_set(unit, phy_acc, mode->cur_mode));
   6913 
   6914 exit:
   6915     SOC_FUNC_RETURN;
   6916 }
   6917 
   6918 int
   6919 pm4x25_port_trunk_hwfailover_config_set(int unit, soc_port_t port, pm_info_t pm_info, int hw_count)
   6920 {
   6921     int    old_failover_en=0, new_failover_en = 0;
   6922     int    old_link_status_sel=0, new_link_status_sel=0;
   6923     int    old_reset_flow_control=0, new_reset_flow_control = 0;
   6924     int    lag_failover_lpbk;
   6925 
   6926     if (hw_count) {
   6927         new_failover_en        = 1;
   6928         new_link_status_sel    = 1;
   6929         new_reset_flow_control = 1;
   6930     }
   6931 
   6932     SOC_IF_ERROR_RETURN (clmac_lag_failover_loopback_get(unit, port, &lag_failover_lpbk));
   6933     if (lag_failover_lpbk) return (SOC_E_NONE);
   6934 
   6935 
   6936     SOC_IF_ERROR_RETURN (clmac_lag_failover_en_get(unit, port, &old_failover_en));
   6937     SOC_IF_ERROR_RETURN (clmac_sw_link_status_select_get (unit, port, &old_link_status_sel));
   6938 
   6939     if (old_failover_en     != new_failover_en ||
   6940         old_link_status_sel != new_link_status_sel) {
   6941 
   6942         SOC_IF_ERROR_RETURN (clmac_sw_link_status_select_set (unit, port, new_link_status_sel));
   6943         SOC_IF_ERROR_RETURN (clmac_lag_failover_en_set(unit, port, new_failover_en));
   6944     }
   6945 
   6946     SOC_IF_ERROR_RETURN (clmac_reset_fc_timers_on_link_dn_get(unit,
   6947                                        port, &old_reset_flow_control));
   6948     if (old_reset_flow_control != new_reset_flow_control) {
   6949         SOC_IF_ERROR_RETURN (clmac_reset_fc_timers_on_link_dn_set(unit,
   6950                                         port, new_reset_flow_control));
   6951     }
   6952 
   6953     return 0;
   6954 }
   6955 
   6956 int
   6957 pm4x25_port_trunk_hwfailover_config_get(int unit, soc_port_t port, pm_info_t pm_info, 
   6958                                         int *enable)
   6959 {
   6960     return (clmac_lag_failover_en_get(unit, port, enable));
   6961 }
   6962 
   6963 
   6964 int
   6965 pm4x25_port_trunk_hwfailover_status_get(int unit, soc_port_t port, pm_info_t pm_info, 
   6966                                         int *loopback)
   6967 {
   6968     return (clmac_lag_failover_loopback_get(unit, port, loopback));
   6969 }
   6970 
   6971 int pm4x25_port_diag_ctrl(int unit, soc_port_t port, pm_info_t pm_info,
   6972                       uint32 inst, int op_type, int op_cmd, const void *arg) 
   6973 {
   6974     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6975     int nof_phys;
   6976     portmod_access_get_params_t params;
   6977 
   6978 
   6979     SOC_IF_ERROR_RETURN(portmod_access_get_params_t_init(unit, &params));
   6980 
   6981     if( PHY_DIAG_INST_DEV(inst) == PHY_DIAG_DEV_INT ) {
   6982         params.phyn = 0 ;
   6983     } else { /* most external is default */  
   6984         params.phyn = -1 ;  
   6985     } 
   6986 
   6987     if( PHY_DIAG_INST_INTF(inst) == PHY_DIAG_INTF_SYS ) {
   6988         params.sys_side = PORTMOD_SIDE_SYSTEM;
   6989     } else { /* most external is default */
   6990         params.sys_side = PORTMOD_SIDE_LINE ;
   6991     }
   6992 
   6993     SOC_IF_ERROR_RETURN(pm4x25_port_phy_lane_access_get(unit, port, pm_info,
   6994                                     &params, 1, phy_access, &nof_phys, NULL));
   6995 
   6996     return (portmod_phy_port_diag_ctrl(unit, port, phy_access, nof_phys, inst, op_type, op_cmd, arg));
   6997 }
   6998 
   6999 int
   7000 pm4x25_port_ref_clk_get(int unit, soc_port_t port, pm_info_t pm_info, int *ref_clk)
   7001 {
   7002     *ref_clk = pm_info->pm_data.pm4x25_db->ref_clk;
   7003 
   7004     return (SOC_E_NONE);
   7005 }
   7006 
   7007 int pm4x25_port_lag_remove_failover_lpbk_get(int unit, int port, pm_info_t pm_info, int *val)
   7008 {
   7009     return (clmac_lag_remove_failover_lpbk_get(unit, port, val));
   7010 }
   7011 
   7012 int pm4x25_port_lag_remove_failover_lpbk_set(int unit, int port, pm_info_t pm_info, int val)
   7013 {
   7014     return (clmac_lag_remove_failover_lpbk_set(unit, port, val));
   7015 }
   7016 
   7017 int pm4x25_port_lag_failover_disable(int unit, int port, pm_info_t pm_info)
   7018 {
   7019     return (clmac_lag_failover_disable(unit, port));
   7020 }
   7021 
   7022 int pm4x25_port_mac_ctrl_set(int unit, int port,
   7023                    pm_info_t pm_info, uint64 ctrl)
   7024 {
   7025     return (clmac_mac_ctrl_set(unit, port, ctrl));
   7026 }
   7027 
   7028 int pm4x25_port_drain_cell_get(int unit, int port, 
   7029            pm_info_t pm_info, portmod_drain_cells_t *drain_cells)
   7030 {
   7031     return (clmac_drain_cell_get(unit, port, drain_cells));
   7032 }
   7033 
   7034 int pm4x25_port_drain_cell_stop (int unit, int port, 
   7035            pm_info_t pm_info, const portmod_drain_cells_t *drain_cells)
   7036 {
   7037     return (clmac_drain_cell_stop (unit, port, drain_cells));
   7038                
   7039 }
   7040 
   7041 int pm4x25_port_drain_cell_start(int unit, int port, pm_info_t pm_info)
   7042 {
   7043     return (clmac_drain_cell_start(unit, port));
   7044 }
   7045 
   7046 int pm4x25_port_txfifo_cell_cnt_get(int unit, int port,
   7047                        pm_info_t pm_info, uint32* fval)
   7048 {
   7049     return (clmac_txfifo_cell_cnt_get(unit, port, fval));
   7050 }
   7051 
   7052 int pm4x25_port_egress_queue_drain_get(int unit, int port,
   7053                    pm_info_t pm_info, uint64 *ctrl, int *rx)
   7054 {
   7055     return (clmac_egress_queue_drain_get(unit, port, ctrl, rx));
   7056 }
   7057 
   7058 int pm4x25_port_drain_cells_rx_enable(int unit, int port,
   7059                    pm_info_t pm_info, int rx_en)
   7060 {
   7061     return (clmac_drain_cells_rx_enable(unit, port, rx_en));
   7062 }
   7063 
   7064 int pm4x25_port_egress_queue_drain_rx_en(int unit, int port,
   7065                    pm_info_t pm_info, int rx_en)
   7066 {
   7067     return (clmac_egress_queue_drain_rx_en(unit, port, rx_en));
   7068 }
   7069 
   7070 int pm4x25_port_mac_reset_set(int unit, int port,
   7071                    pm_info_t pm_info, int val)
   7072 {
   7073     int rv;
   7074     SOC_INIT_FUNC_DEFS;
   7075 
   7076     /* if callback defined, go to local soft reset function */
   7077     rv = (PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) ? pm4x25_port_soft_reset(unit, port, pm_info, val) : clmac_soft_reset_set(unit, port, val);
   7078     _SOC_IF_ERR_EXIT(rv);
   7079 
   7080 exit:
   7081     SOC_FUNC_RETURN;
   7082 }
   7083 
   7084 int pm4x25_port_mac_reset_get(int unit, int port, pm_info_t pm_info, int* val)
   7085 {
   7086     return (clmac_soft_reset_get(unit, port, val));
   7087 }
   7088 
   7089 int pm4x25_port_mac_reset_check(int unit, int port, pm_info_t pm_info,
   7090                                 int enable, int* reset)
   7091 {
   7092     return (clmac_reset_check(unit, port, enable, reset));
   7093 }
   7094 
   7095 int pm4x25_port_core_num_get(int unit, int port, pm_info_t pm_info,
   7096                                 int* core_num)
   7097 {
   7098     *core_num = PM_4x25_INFO(pm_info)->core_num;
   7099     return (SOC_E_NONE);
   7100 }
   7101 
   7102 /* in_out: 1= in reset, 0= in and out of reset */
   7103 STATIC
   7104 int pm4x25_port_soft_reset(int unit, int port, pm_info_t pm_info, int in_out)
   7105 {
   7106     int rv, rx_enable = 0;
   7107     int phy_port, block, bindex, i;
   7108     portmod_drain_cells_t drain_cells;
   7109     uint32 cell_count;
   7110     uint64 mac_ctrl;
   7111     soc_timeout_t to;
   7112     SOC_INIT_FUNC_DEFS;
   7113 
   7114     /* Callback soft reset function */
   7115     if (PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   7116         rv = PM_4x25_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypePre);
   7117         _SOC_IF_ERR_EXIT(rv);
   7118     }
   7119 
   7120     if (in_out == 0) {
   7121 	    rv = clmac_egress_queue_drain_get(unit, port, &mac_ctrl, &rx_enable); 
   7122 	    _SOC_IF_ERR_EXIT(rv);
   7123 
   7124 	    /* Drain cells */
   7125 	    rv = clmac_drain_cell_get(unit, port, &drain_cells);
   7126 	    _SOC_IF_ERR_EXIT(rv);
   7127 
   7128 	    /* Start TX FIFO draining */
   7129 	    rv = clmac_drain_cell_start(unit, port);
   7130 	    _SOC_IF_ERR_EXIT(rv);
   7131 
   7132 	    /* De-assert SOFT_RESET to let the drain start */
   7133 	    rv = clmac_soft_reset_set(unit, port, 0);           
   7134 	    _SOC_IF_ERR_EXIT(rv);
   7135 
   7136 	    /* Wait until TX fifo cell count is 0 */
   7137 	    soc_timeout_init(&to, 250000, 0);
   7138 	    for (;;) {
   7139 	        rv = clmac_txfifo_cell_cnt_get(unit, port, &cell_count);
   7140 	        _SOC_IF_ERR_EXIT(rv);
   7141 	        if (cell_count == 0) {
   7142 	            break;
   7143         	}
   7144 	        if (soc_timeout_check(&to)) {
   7145 	            LOG_ERROR(BSL_LS_SOC_PORT,(BSL_META_UP(unit, port, "ERROR: u=%d p=%d timeout draining TX FIFO (%d cells remain)\n"), unit, port, cell_count));
   7146         	    return SOC_E_INTERNAL;
   7147 	        }
   7148         }
   7149    
   7150 	    /* Stop TX FIFO draining */
   7151 	    rv = clmac_drain_cell_stop(unit, port, &drain_cells);
   7152 	    _SOC_IF_ERR_EXIT(rv);
   7153 
   7154 	    /* Reset port FIFO */
   7155 	    phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   7156 	    for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   7157 	        block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   7158         	if ((SOC_BLOCK_INFO(unit, block).type == SOC_BLK_CLPORT) ||
   7159         	    (SOC_BLOCK_INFO(unit, block).type == SOC_BLK_CLG2PORT)) {
   7160 	            bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   7161         	    _SOC_IF_ERR_EXIT(PM_DRIVER(pm_info)->f_portmod_port_soft_reset_toggle(unit, port, pm_info, bindex));
   7162 	            break;
   7163         	}
   7164     	    }
   7165     }
   7166 
   7167     /* Put port into SOFT_RESET */
   7168     rv = clmac_soft_reset_set(unit, port, 1);
   7169     _SOC_IF_ERR_EXIT(rv);
   7170 
   7171     if(in_out == 0) {
   7172 
   7173 	    /* Callback soft reset function */
   7174     	    if (PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   7175         	rv = PM_4x25_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypeDuring);
   7176 	        	_SOC_IF_ERR_EXIT(rv);
   7177 	        	soc_reg64_field32_set (unit, CLMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 0); /*make sure restored data wont put mac back in reset*/
   7178     	    }
   7179 
   7180 	    /* Enable TX, restore RX, de-assert SOFT_RESET */
   7181 	    rv = clmac_egress_queue_drain_rx_en(unit, port, rx_enable);
   7182 	    _SOC_IF_ERR_EXIT(rv);
   7183 
   7184 	    /* Restore clmac_CTRL to original value */
   7185 	    rv = clmac_mac_ctrl_set(unit, port, mac_ctrl);
   7186 	    _SOC_IF_ERR_EXIT(rv);
   7187     }
   7188 
   7189     /* Callback soft reset function */
   7190     if (PM_4x25_INFO(pm_info)->portmod_mac_soft_reset) {
   7191         rv = PM_4x25_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypePost);
   7192         _SOC_IF_ERR_EXIT(rv);
   7193     }
   7194  
   7195 exit:
   7196     SOC_FUNC_RETURN;
   7197 }
   7198 
   7199 /*Port discard set*/
   7200 int pm4x25_port_discard_set(int unit, int port, pm_info_t pm_info, int discard)
   7201 {
   7202     return(clmac_discard_set(unit, port, discard));
   7203 }
   7204 
   7205 /*Port soft reset set set*/
   7206 int pm4x25_port_soft_reset_set(int unit, int port, pm_info_t pm_info, int idx,
   7207                                int val, int flags)
   7208 {
   7209     return (_pm4x25_port_soft_reset_set(unit, port, pm_info, idx, val));
   7210 }
   7211 
   7212 /*Port tx_en=0 and softreset mac*/
   7213 int pm4x25_port_tx_down(int unit, int port, pm_info_t pm_info)
   7214 {
   7215     SOC_INIT_FUNC_DEFS;
   7216 
   7217     _SOC_IF_ERR_EXIT(clmac_tx_enable_set(unit, port, 0));
   7218     _SOC_IF_ERR_EXIT(clmac_discard_set(unit, port, 0));
   7219     _SOC_IF_ERR_EXIT(clmac_soft_reset_set(unit, port, 1));
   7220 
   7221 exit:
   7222     SOC_FUNC_RETURN;
   7223 }
   7224 
   7225 int pm4x25_port_pgw_reconfig (int unit, int port, pm_info_t pm_info, 
   7226                               const portmod_port_mode_info_t *pmode,
   7227                               int phy_port, int flags)
   7228 {
   7229     int rv, idx=0, physical_port, i;
   7230     int phy_acc, block;
   7231     uint32 reg_val;
   7232     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   7233 
   7234     SOC_INIT_FUNC_DEFS; 
   7235 
   7236     physical_port = SOC_INFO(unit).port_l2p_mapping[port];
   7237     for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   7238     	block = SOC_PORT_IDX_BLOCK(unit, physical_port, i);
   7239    	if ((SOC_BLOCK_INFO(unit, block).type == SOC_BLK_CLPORT) ||
   7240    	    (SOC_BLOCK_INFO(unit, block).type == SOC_BLK_CLG2PORT)) {
   7241         	idx = SOC_PORT_IDX_BINDEX(unit, physical_port, i);
   7242             	break;
   7243         }
   7244     }
   7245     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7246 
   7247     /* 1.a st SOFT_RESET field in CLMAC_CTRL for new ports that use XLMAC */
   7248     rv = clmac_soft_reset_set(unit, port, 1);
   7249     _SOC_IF_ERR_EXIT(rv);
   7250 
   7251     /* 1.a set PORT[subport] field in CLPORT_SOFT_RESET for all new ports */
   7252     _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   7253     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, port_fields[idx], 1);
   7254     _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   7255 
   7256     /* Port enable */
   7257     _SOC_IF_ERR_EXIT(READ_CLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   7258     soc_reg_field_set (unit, CLPORT_ENABLE_REGr, &reg_val,
   7259                            port_fields[idx], 1);
   7260     _SOC_IF_ERR_EXIT(WRITE_CLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   7261 
   7262  
   7263     /* set port mode */
   7264 
   7265     /* Release CLPORT SOFT RESET */
   7266     _SOC_IF_ERR_EXIT(READ_CLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   7267     soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &reg_val, port_fields[idx], 0);
   7268     _SOC_IF_ERR_EXIT(WRITE_CLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   7269 
   7270     /*Release Mac Soft Reset */
   7271     rv = clmac_soft_reset_set(unit, port, 0);
   7272     _SOC_IF_ERR_EXIT(rv);
   7273 
   7274 exit:
   7275     SOC_FUNC_RETURN;
   7276 }
   7277 
   7278 /* get interrupt value. */
   7279 int pm4x25_port_interrupt_enable_get (int unit, int port, pm_info_t pm_info,
   7280                                     int intr_type, uint32 *val)
   7281 {
   7282     uint32 reg_val;
   7283     int phy_acc;
   7284     pm_version_t pm_version;
   7285     SOC_INIT_FUNC_DEFS;
   7286 
   7287     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7288     _SOC_IF_ERR_EXIT(READ_CLPORT_INTR_ENABLEr(unit, phy_acc, &reg_val));
   7289     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   7290 
   7291     switch(intr_type) {
   7292         case portmodIntrTypeMibTxMemErr:
   7293              *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MIB_TX_MEM_ERRf);
   7294              break;
   7295         case portmodIntrTypeMibRxMemErr:
   7296              *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MIB_RX_MEM_ERRf);
   7297              break;
   7298         case portmodIntrTypeMacTxCdcMemErr:
   7299              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7300                 *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MAC_TX_CDC_MEM_ERRf);
   7301                 break;
   7302              }
   7303              else {
   7304                 return SOC_E_UNAVAIL;
   7305              }
   7306         case portmodIntrTypeMacRxCdcMemErr:
   7307              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7308                 *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MAC_RX_CDC_MEM_ERRf);
   7309                 break;
   7310              }
   7311              else {
   7312                 return SOC_E_UNAVAIL;
   7313              }
   7314         case portmodIntrTypeMacRxTsCdcMemErr:
   7315              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7316                 *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MAC_RX_TS_CDC_MEM_ERRf);
   7317                 break;
   7318              }
   7319              else {
   7320                 return SOC_E_UNAVAIL;
   7321              }
   7322         case portmodIntrTypeTscErr:
   7323              *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, TSC_ERRf);
   7324              break;
   7325         case portmodIntrTypePmdErr:
   7326              *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, PMD_ERRf);
   7327              break;
   7328         case portmodIntrTypeRxFcReqFull:
   7329              *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, RX_FLOWCONTROL_REQ_FULLf);
   7330              break;
   7331         case portmodIntrTypeLinkdown:
   7332              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7333                 *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, LINK_DOWNf);
   7334                 break;
   7335              }
   7336              else {
   7337                 return SOC_E_UNAVAIL;
   7338              }
   7339         case portmodIntrTypeMacErr:
   7340              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7341                 *val = soc_reg_field_get(unit, CLPORT_INTR_ENABLEr, reg_val, MAC_ERRf);
   7342                 break;
   7343              }
   7344              else {
   7345                 return SOC_E_UNAVAIL;
   7346              }
   7347         case portmodIntrTypeTxPktUnderflow :
   7348         case portmodIntrTypeTxPktOverflow :
   7349         case portmodIntrTypeTxLlfcMsgOverflow :
   7350         case portmodIntrTypeTxTSFifoOverflow :
   7351         case portmodIntrTypeRxPktOverflow :
   7352         case portmodIntrTypeRxMsgOverflow :
   7353         case portmodIntrTypeTxCdcSingleBitErr :
   7354         case portmodIntrTypeTxCdcDoubleBitErr :
   7355         case portmodIntrTypeRxCdcSingleBitErr :
   7356         case portmodIntrTypeRxCdcDoubleBitErr :
   7357         case portmodIntrTypeRxTsMemSingleBitErr :
   7358         case portmodIntrTypeRxTsMemDoubleBitErr :
   7359         case portmodIntrTypeLocalFaultStatus :
   7360         case portmodIntrTypeRemoteFaultStatus :
   7361         case portmodIntrTypeLinkInterruptionStatus :
   7362         case portmodIntrTypeTsEntryValid :
   7363              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7364                  _SOC_IF_ERR_EXIT(clmac_interrupt_enable_get(unit, port, intr_type, val));
   7365                  break;
   7366              }
   7367              else {
   7368                  return SOC_E_UNAVAIL;
   7369              }
   7370         default:
   7371             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   7372             break;
   7373     }
   7374 
   7375 exit:
   7376     SOC_FUNC_RETURN;
   7377 }
   7378 
   7379 /* set interrupt value. */
   7380 int pm4x25_port_interrupt_enable_set (int unit, int port, pm_info_t pm_info,
   7381                                     int intr_type, uint32 val)
   7382 {
   7383     uint32 reg_val;
   7384     int phy_acc;
   7385     pm_version_t pm_version;
   7386     SOC_INIT_FUNC_DEFS;
   7387 
   7388     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7389     _SOC_IF_ERR_EXIT(READ_CLPORT_INTR_ENABLEr(unit, phy_acc, &reg_val));
   7390     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   7391 
   7392     switch(intr_type) {
   7393         case portmodIntrTypeMibTxMemErr:
   7394              soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MIB_TX_MEM_ERRf, val);
   7395              break;
   7396         case portmodIntrTypeMibRxMemErr:
   7397              soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MIB_RX_MEM_ERRf, val);
   7398              break;
   7399         case portmodIntrTypeMacTxCdcMemErr:
   7400              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7401                 soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MAC_TX_CDC_MEM_ERRf, val);
   7402                 break;
   7403              }
   7404              else {
   7405                 return SOC_E_UNAVAIL;
   7406              }
   7407         case portmodIntrTypeMacRxCdcMemErr:
   7408              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7409                 soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MAC_RX_CDC_MEM_ERRf, val);
   7410                 break;
   7411              }
   7412              else {
   7413                 return SOC_E_UNAVAIL;
   7414              }
   7415         case portmodIntrTypeMacRxTsCdcMemErr:
   7416              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7417                 soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MAC_RX_TS_CDC_MEM_ERRf, val);
   7418                 break;
   7419              }
   7420              else {
   7421                 return SOC_E_UNAVAIL;
   7422              }
   7423         case portmodIntrTypeTscErr:
   7424              soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, TSC_ERRf, val);
   7425              break;
   7426         case portmodIntrTypePmdErr:
   7427              soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, PMD_ERRf, val);
   7428              break;
   7429         case portmodIntrTypeRxFcReqFull:
   7430              soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, RX_FLOWCONTROL_REQ_FULLf, val);
   7431              break;
   7432         case portmodIntrTypeLinkdown:
   7433              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7434                 soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, LINK_DOWNf, val);
   7435                 break;
   7436              }
   7437              else {
   7438                 return SOC_E_UNAVAIL;
   7439              }
   7440         case portmodIntrTypeMacErr:
   7441              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7442                 soc_reg_field_set(unit, CLPORT_INTR_ENABLEr, &reg_val, MAC_ERRf, val);
   7443                 break;
   7444              }
   7445              else {
   7446                 return SOC_E_UNAVAIL;
   7447              }
   7448         case portmodIntrTypeTxPktUnderflow :
   7449         case portmodIntrTypeTxPktOverflow :
   7450         case portmodIntrTypeTxLlfcMsgOverflow :
   7451         case portmodIntrTypeTxTSFifoOverflow :
   7452         case portmodIntrTypeRxPktOverflow :
   7453         case portmodIntrTypeRxMsgOverflow :
   7454         case portmodIntrTypeTxCdcSingleBitErr :
   7455         case portmodIntrTypeTxCdcDoubleBitErr :
   7456         case portmodIntrTypeRxCdcSingleBitErr :
   7457         case portmodIntrTypeRxCdcDoubleBitErr :
   7458         case portmodIntrTypeRxTsMemSingleBitErr :
   7459         case portmodIntrTypeRxTsMemDoubleBitErr :
   7460         case portmodIntrTypeLocalFaultStatus :
   7461         case portmodIntrTypeRemoteFaultStatus :
   7462         case portmodIntrTypeLinkInterruptionStatus :
   7463         case portmodIntrTypeTsEntryValid :
   7464              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7465                 _SOC_IF_ERR_EXIT(clmac_interrupt_enable_set(unit, port, intr_type, val));
   7466                 break;
   7467              }
   7468              else {
   7469                 return SOC_E_UNAVAIL;
   7470              }
   7471         default:
   7472             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   7473             break;
   7474     }
   7475     _SOC_IF_ERR_EXIT(WRITE_CLPORT_INTR_ENABLEr(unit, phy_acc, reg_val));
   7476 
   7477 exit:
   7478     SOC_FUNC_RETURN;
   7479 }
   7480 
   7481 /* get interrupt value. */
   7482 int pm4x25_port_interrupt_get (int unit, int port, pm_info_t pm_info,
   7483                                int intr_type, uint32* val)
   7484 {
   7485     uint32 reg_val;
   7486     int phy_acc;
   7487     pm_version_t pm_version;
   7488     SOC_INIT_FUNC_DEFS;
   7489 
   7490     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7491     _SOC_IF_ERR_EXIT(READ_CLPORT_INTR_STATUSr(unit, phy_acc, &reg_val));
   7492     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   7493 
   7494     switch(intr_type) {
   7495         case portmodIntrTypeMibTxMemErr:
   7496              *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MIB_TX_MEM_ERRf);
   7497              break;
   7498         case portmodIntrTypeMibRxMemErr:
   7499              *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MIB_RX_MEM_ERRf);
   7500              break;
   7501         case portmodIntrTypeMacTxCdcMemErr:
   7502              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7503                 *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_TX_CDC_MEM_ERRf);
   7504                 break;
   7505              }
   7506              else {
   7507                 return SOC_E_UNAVAIL;
   7508              }
   7509         case portmodIntrTypeMacRxCdcMemErr:
   7510              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7511                 *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_RX_CDC_MEM_ERRf);
   7512                 break;
   7513              }
   7514              else {
   7515                 return SOC_E_UNAVAIL;
   7516              }
   7517         case portmodIntrTypeMacRxTsCdcMemErr:
   7518              if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7519                 *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_RX_TS_CDC_MEM_ERRf);
   7520                 break;
   7521              }
   7522              else {
   7523                 return SOC_E_UNAVAIL;
   7524              }
   7525         case portmodIntrTypeTscErr:
   7526              *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, TSC_ERRf);
   7527              break;
   7528         case portmodIntrTypePmdErr:
   7529              *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, PMD_ERRf);
   7530              break;
   7531         case portmodIntrTypeRxFcReqFull:
   7532              *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, RX_FLOWCONTROL_REQ_FULLf);
   7533              break;
   7534         case portmodIntrTypeLinkdown:
   7535              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7536                 *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, LINK_DOWNf);
   7537                 break;
   7538              }
   7539              else {
   7540                 return SOC_E_UNAVAIL;
   7541              }
   7542         case portmodIntrTypeMacErr:
   7543              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7544                 *val = soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_ERRf);
   7545                 break;
   7546              }
   7547              else {
   7548                 return SOC_E_UNAVAIL;
   7549              }
   7550         case portmodIntrTypeTxPktUnderflow :
   7551         case portmodIntrTypeTxPktOverflow :
   7552         case portmodIntrTypeTxLlfcMsgOverflow :
   7553         case portmodIntrTypeTxTSFifoOverflow :
   7554         case portmodIntrTypeRxPktOverflow :
   7555         case portmodIntrTypeRxMsgOverflow :
   7556         case portmodIntrTypeTxCdcSingleBitErr :
   7557         case portmodIntrTypeTxCdcDoubleBitErr :
   7558         case portmodIntrTypeRxCdcSingleBitErr :
   7559         case portmodIntrTypeRxCdcDoubleBitErr :
   7560         case portmodIntrTypeRxTsMemSingleBitErr :
   7561         case portmodIntrTypeRxTsMemDoubleBitErr :
   7562         case portmodIntrTypeLocalFaultStatus :
   7563         case portmodIntrTypeRemoteFaultStatus :
   7564         case portmodIntrTypeLinkInterruptionStatus :
   7565         case portmodIntrTypeTsEntryValid :
   7566              if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7567                 _SOC_IF_ERR_EXIT(clmac_interrupt_status_get(unit, port, intr_type, val));
   7568                 break;
   7569              }
   7570              else {
   7571                 return SOC_E_UNAVAIL;
   7572              }
   7573         default:
   7574             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   7575             break;
   7576     }
   7577 exit:
   7578     SOC_FUNC_RETURN;
   7579 }
   7580 
   7581 int pm4x25_port_interrupts_get (int unit, int port, pm_info_t pm_info,
   7582                                 int arr_max_size, uint32* intr_arr, uint32* size)
   7583 {
   7584     uint32 reg_val, cnt=0;
   7585     int phy_acc;
   7586     uint32 mac_intr_cnt = 0;
   7587     pm_version_t pm_version;
   7588     SOC_INIT_FUNC_DEFS;
   7589 
   7590     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7591     _SOC_IF_ERR_EXIT(READ_CLPORT_INTR_STATUSr(unit, phy_acc, &reg_val));
   7592     _SOC_IF_ERR_EXIT(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   7593 
   7594     if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MIB_TX_MEM_ERRf)) {
   7595         if (cnt >= arr_max_size) {
   7596             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7597         }
   7598         intr_arr[cnt++] = portmodIntrTypeMibTxMemErr;
   7599     }
   7600 
   7601     if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MIB_RX_MEM_ERRf)) {
   7602         if (cnt >= arr_max_size) {
   7603             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7604         }
   7605         intr_arr[cnt++] = portmodIntrTypeMibRxMemErr;
   7606     }
   7607 
   7608     if(PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7609         if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_TX_CDC_MEM_ERRf)) {
   7610              if (cnt >= arr_max_size) {
   7611                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7612              }
   7613              intr_arr[cnt++] = portmodIntrTypeMacTxCdcMemErr;
   7614         }
   7615 
   7616         if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_RX_CDC_MEM_ERRf)) {
   7617              if (cnt >= arr_max_size) {
   7618                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7619              }
   7620              intr_arr[cnt++] = portmodIntrTypeMacRxCdcMemErr;
   7621         }
   7622 
   7623         if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_RX_TS_CDC_MEM_ERRf)) {
   7624              if (cnt >= arr_max_size) {
   7625                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7626              }
   7627              intr_arr[cnt++] = portmodIntrTypeMacRxTsCdcMemErr;
   7628         }
   7629     }
   7630 
   7631     if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, TSC_ERRf)) {
   7632         intr_arr[cnt++] = portmodIntrTypeTscErr;
   7633     }
   7634 
   7635     if (soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, RX_FLOWCONTROL_REQ_FULLf)) {
   7636         if (cnt >= arr_max_size) {
   7637             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7638         }
   7639         intr_arr[cnt++] = portmodIntrTypeRxFcReqFull;
   7640     }
   7641 
   7642     if(!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   7643         if(soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, LINK_DOWNf)) {
   7644              if (cnt >= arr_max_size) {
   7645                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7646              }
   7647              intr_arr[cnt++] = portmodIntrTypeLinkdown;
   7648         }
   7649 
   7650         if(soc_reg_field_get(unit, CLPORT_INTR_STATUSr, reg_val, MAC_ERRf)) {
   7651              if (cnt >= arr_max_size) {
   7652                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   7653              }
   7654              intr_arr[cnt++] = portmodIntrTypeMacErr;
   7655         }
   7656 
   7657         _SOC_IF_ERR_EXIT(clmac_interrupts_status_get(unit, port, (arr_max_size- cnt), (intr_arr + cnt), &mac_intr_cnt));
   7658         cnt += mac_intr_cnt;
   7659     }
   7660 
   7661     *size = cnt;
   7662 
   7663 exit:
   7664     SOC_FUNC_RETURN;
   7665 }
   7666 
   7667 /*!
   7668  * pm4x25_port_eee_clock_set
   7669  *
   7670  * @brief set EEE Config.
   7671  *
   7672  * @param [in]  unit            - unit id
   7673  * @param [in]  port            - logical port
   7674  * @param [in]  eee             -
   7675  */
   7676 int pm4x25_port_eee_clock_set(int unit, int port, pm_info_t pm_info,
   7677                               const portmod_eee_clock_t* eee_clk)
   7678 {
   7679     int phy_acc;
   7680     SOC_INIT_FUNC_DEFS;
   7681 
   7682     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7683 
   7684     _SOC_IF_ERR_EXIT(WRITE_CLPORT_EEE_CLOCK_GATEr(unit, phy_acc, eee_clk->clock_gate));
   7685     _SOC_IF_ERR_EXIT(WRITE_CLPORT_EEE_CORE0_CLOCK_GATE_COUNTERr(unit, phy_acc, eee_clk->clock_count));
   7686     _SOC_IF_ERR_EXIT(WRITE_CLPORT_EEE_DURATION_TIMER_PULSEr(unit, phy_acc, eee_clk->timer_pulse));
   7687 
   7688 exit:
   7689     SOC_FUNC_RETURN;
   7690 }
   7691 
   7692 
   7693 /*!
   7694  * portmod_port_eee_clock_get
   7695  *
   7696  * @brief set EEE Config.
   7697  *
   7698  * @param [in]  unit            - unit id
   7699  * @param [in]  port            - logical port
   7700  * @param [out]  eee             -
   7701  */
   7702 int pm4x25_port_eee_clock_get (int unit, int port, pm_info_t pm_info,
   7703                                portmod_eee_clock_t* eee_clk)
   7704 {
   7705     int phy_acc;
   7706     SOC_INIT_FUNC_DEFS;
   7707 
   7708     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7709 
   7710     _SOC_IF_ERR_EXIT(READ_CLPORT_EEE_CLOCK_GATEr(unit, phy_acc, &eee_clk->clock_gate));
   7711     _SOC_IF_ERR_EXIT(READ_CLPORT_EEE_CORE0_CLOCK_GATE_COUNTERr(unit, phy_acc, &eee_clk->clock_count));
   7712     _SOC_IF_ERR_EXIT(READ_CLPORT_EEE_DURATION_TIMER_PULSEr(unit, phy_acc, &eee_clk->timer_pulse));
   7713 
   7714 exit:
   7715     SOC_FUNC_RETURN;
   7716 }
   7717 
   7718 int pm4x25_port_check_legacy_phy (int unit, int port, pm_info_t pm_info, int *legacy_phy)
   7719 {
   7720     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7721     int nof_phys, xphy_id, is_legacy_phy;
   7722     int port_index;
   7723     uint32 bitmap;
   7724 
   7725     SOC_INIT_FUNC_DEFS;
   7726 
   7727     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   7728                                              &bitmap));
   7729 
   7730     *legacy_phy = 0;
   7731 
   7732     if (PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   7733         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7734                            (_SOC_MSG("phy reset is not supported")));
   7735     }
   7736 
   7737     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   7738                                                        phy_access ,(1+MAX_PHYN),
   7739                                                        &nof_phys));
   7740      while (nof_phys > 1) {
   7741          --nof_phys;
   7742          xphy_id = phy_access[nof_phys].access.addr;
   7743          _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   7744          if (is_legacy_phy) {
   7745              *legacy_phy = 1;
   7746              break;
   7747          }
   7748      }
   7749 
   7750 exit:
   7751     SOC_FUNC_RETURN;
   7752 }
   7753 
   7754 
   7755 int pm4x25_port_failover_mode_set(int unit, int port, pm_info_t pm_info, phymod_failover_mode_t failover)
   7756 {
   7757     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7758     int nof_phys;
   7759     int port_index;
   7760     uint32 bitmap;
   7761 
   7762     SOC_INIT_FUNC_DEFS;
   7763 
   7764     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   7765                                              &bitmap));
   7766 
   7767     if (PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   7768         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7769                            (_SOC_MSG("phy failover is not supported")));
   7770     }
   7771 
   7772     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   7773                                                        phy_access ,(1+MAX_PHYN),
   7774                                                        &nof_phys));
   7775 
   7776     SOC_IF_ERROR_RETURN(portmod_port_phychain_failover_mode_set(unit, phy_access, nof_phys, failover));
   7777 
   7778 exit:
   7779     SOC_FUNC_RETURN;
   7780 }
   7781 
   7782 int pm4x25_port_failover_mode_get(int unit, int port, pm_info_t pm_info, phymod_failover_mode_t* failover)
   7783 {
   7784     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7785     int nof_phys;
   7786     int port_index;
   7787     uint32 bitmap;
   7788 
   7789     SOC_INIT_FUNC_DEFS;
   7790 
   7791     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get (unit, port, pm_info, &port_index,
   7792                                              &bitmap));
   7793 
   7794     if (PM_4x25_INFO(pm_info)->nof_phys[port_index] == 0) {
   7795         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7796                            (_SOC_MSG("phy failover is not supported")));
   7797     }
   7798 
   7799     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   7800                                                        phy_access ,(1+MAX_PHYN),
   7801                                                        &nof_phys));
   7802 
   7803     SOC_IF_ERROR_RETURN(portmod_port_phychain_failover_mode_get(unit, phy_access, nof_phys, failover));
   7804 
   7805 exit:
   7806     SOC_FUNC_RETURN;
   7807 }
   7808 
   7809 int pm4x25_port_flow_control_set (int unit, int port, pm_info_t pm_info,
   7810                                   int merge_mode_en, int parallel_fc_en)
   7811 {
   7812     int phy_acc, rv;
   7813     uint32 rval;
   7814 
   7815     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7816 
   7817     rv = READ_CLPORT_FLOW_CONTROL_CONFIGr(unit, phy_acc, &rval);
   7818     if (SOC_FAILURE(rv)) return (rv);
   7819 
   7820     soc_reg_field_set(unit, CLPORT_FLOW_CONTROL_CONFIGr, &rval, MERGE_MODE_ENf, merge_mode_en);
   7821     soc_reg_field_set(unit, CLPORT_FLOW_CONTROL_CONFIGr, &rval, PARALLEL_FC_ENf, parallel_fc_en);
   7822 
   7823     return(WRITE_CLPORT_FLOW_CONTROL_CONFIGr(unit, phy_acc, rval));
   7824 }
   7825 
   7826 int pm4x25_port_e2ecc_hdr_set (int unit, int port, pm_info_t pm_info,
   7827                                const portmod_port_higig_e2ecc_hdr_t* e2ecc_hdr)
   7828 {
   7829     return (clmac_e2ecc_hdr_set (unit, port, (uint32_t *)e2ecc_hdr->words));
   7830 }
   7831 
   7832 
   7833 int pm4x25_port_e2ecc_hdr_get (int unit, int port, pm_info_t pm_info,
   7834                                portmod_port_higig_e2ecc_hdr_t* e2ecc_hdr)
   7835 {
   7836     return (clmac_e2ecc_hdr_get (unit, port, e2ecc_hdr->words));
   7837 }
   7838 
   7839 int pm4x25_port_e2e_enable_set (int unit, int port, pm_info_t pm_info, int enable)
   7840 {
   7841     return (clmac_e2e_enable_set(unit, port, enable));
   7842 }
   7843 
   7844 
   7845 int pm4x25_port_e2e_enable_get (int unit, int port, pm_info_t pm_info, int *enable)
   7846 {
   7847     return (clmac_e2e_enable_get(unit, port, enable));
   7848 }
   7849 
   7850 int pm4x25_port_notify(int unit, int port, pm_info_t pm_info, int link) {
   7851     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7852     int nof_phys;
   7853     portmod_port_interface_config_t interface_config;
   7854     SOC_INIT_FUNC_DEFS;
   7855 
   7856     _SOC_IF_ERR_EXIT
   7857         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   7858                                            phy_access ,(1+MAX_PHYN),
   7859                                            &nof_phys));
   7860     /* If nof phys > 1 change the internal phy speed based on the external
   7861     link speed if the link is up*/
   7862     if (nof_phys > 1) {
   7863         if (link) {
   7864             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit,
   7865                                                                port,
   7866                                                                &interface_config,
   7867                                                                PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   7868             /* Set teh interface config to internal phy */
   7869             _SOC_IF_ERR_EXIT(portmod_port_interface_config_set(unit,
   7870                                                                port,
   7871                                                                &interface_config, 
   7872                                                                PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   7873         } else {
   7874             /*TBD*/
   7875         }
   7876     }
   7877     exit:
   7878     SOC_FUNC_RETURN;
   7879 }
   7880 
   7881 int pm4x25_port_mac_rsv_mask_set(int unit, int port, pm_info_t pm_info, uint32 rsv_mask)
   7882 {
   7883         return(WRITE_CLPORT_MAC_RSV_MASKr(unit, port, rsv_mask));
   7884 }
   7885 
   7886 int pm4x25_port_mib_reset_toggle(int unit, int port, pm_info_t pm_info, int port_index)
   7887 {
   7888     uint32 reg_val[1];
   7889     int    rv = 0, phy_acc;
   7890 
   7891     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7892 
   7893     rv = READ_CLPORT_MIB_RESETr(unit, phy_acc, reg_val);
   7894     if (SOC_FAILURE(rv)) return (rv);
   7895     SHR_BITSET(reg_val, port_index);
   7896 
   7897     rv = WRITE_CLPORT_MIB_RESETr(unit, phy_acc, *reg_val);
   7898     if (SOC_FAILURE(rv)) return (rv);
   7899     SHR_BITCLR(reg_val, port_index);
   7900 
   7901     return(WRITE_CLPORT_MIB_RESETr(unit, phy_acc, *reg_val));
   7902 }
   7903 
   7904 int pm4x25_port_warmboot_db_restore(int unit, int port, pm_info_t pm_info,
   7905                          const portmod_port_interface_config_t *f_intf_config,
   7906                          const portmod_port_init_config_t      *f_init_config,
   7907                          const phymod_operation_mode_t phy_op_mode)
   7908 {
   7909     pm4x25_t pm4x25_data = NULL;
   7910     phymod_phy_access_t                 phy_access[1+MAX_PHYN];
   7911     phymod_phy_inf_config_t             phy_intf_config;
   7912     portmod_encap_t                     encap_mode;
   7913     phymod_autoneg_control_t            an;
   7914     soc_port_if_t                       interface;
   7915     int     phy, nof_phys, port_index, rv = 0, flags = 0, port_num_lanes = 0, is_interface_restore = 0;
   7916     uint32  bitmap, an_done, interface_modes = 0;
   7917 
   7918     /*
   7919      * if no warmboot db restore is required return
   7920      */
   7921     if(PM_4x25_INFO(pm_info)->warmboot_skip_db_restore){
   7922         return SOC_E_NONE;
   7923     }
   7924 
   7925     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   7926     if (SOC_FAILURE(rv)) return (rv);
   7927 
   7928     pm4x25_data      = pm_info->pm_data.pm4x25_db;
   7929 
   7930     PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy) {
   7931         pm4x25_data->first_phy = phy;
   7932         break;
   7933     }
   7934 
   7935     rv = PM4x25_INTERFACE_TYPE_SET(unit, pm_info, f_intf_config->interface, port_index);
   7936     if (SOC_FAILURE(rv)) return (rv);
   7937     rv = PM4x25_MAX_SPEED_SET(unit, pm_info, f_intf_config->max_speed, port_index);
   7938     if (SOC_FAILURE(rv)) return (rv);
   7939 
   7940     rv = PM4x25_IS_HG_SET(unit, pm_info, f_init_config->is_hg, port_index);
   7941     if (SOC_FAILURE(rv)) return (rv);
   7942     rv = PM4x25_AN_MODE_SET(unit, pm_info, f_init_config->an_mode, port_index);
   7943     if (SOC_FAILURE(rv)) return (rv);
   7944     rv = PM4x25_FS_CL72_SET(unit, pm_info, f_init_config->fs_cl72, port_index);
   7945     if (SOC_FAILURE(rv)) return (rv);
   7946     rv = PM4x25_AN_CL72_SET(unit, pm_info, f_init_config->an_cl72, port_index);
   7947     if (SOC_FAILURE(rv)) return (rv);
   7948     rv = PM4x25_AN_FEC_SET(unit, pm_info, f_init_config->an_fec, port_index);
   7949     if (SOC_FAILURE(rv)) return (rv);
   7950     rv = PM4x25_AN_MASTER_LANE_SET(unit, pm_info, f_init_config->an_master_lane, port_index);
   7951     if (SOC_FAILURE(rv)) return (rv);
   7952 
   7953     rv = portmod_port_chain_phy_access_get (unit, port, pm_info, phy_access,
   7954                                            (1+MAX_PHYN), &nof_phys);
   7955     if (SOC_FAILURE(rv)) return (rv);
   7956 
   7957     rv = portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   7958                                    0, phymodRefClk156Mhz, &phy_intf_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY);
   7959     if (SOC_FAILURE(rv)) return (rv);
   7960 
   7961     rv = PM4x25_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, port_index);
   7962     if (SOC_FAILURE(rv)) return (rv);
   7963     rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, phy_intf_config.interface_modes, port_index);
   7964     if (SOC_FAILURE(rv)) return (rv);
   7965 
   7966     rv = portmod_port_interface_type_get (unit, port, &interface);
   7967     if (SOC_FAILURE(rv)) return (rv);
   7968     rv = PM4x25_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index);
   7969     if (SOC_FAILURE(rv)) return (rv);
   7970 
   7971     clmac_encap_get(unit, port, &flags, &encap_mode);
   7972     if ((encap_mode == SOC_ENCAP_HIGIG2) || (encap_mode == SOC_ENCAP_HIGIG)) {
   7973         rv = PM4x25_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   7974         if (SOC_FAILURE(rv)) return (rv);
   7975         interface_modes |= PHYMOD_INTF_MODES_HIGIG;
   7976         rv = PM4x25_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   7977         if (SOC_FAILURE(rv)) return (rv);
   7978     }
   7979 
   7980     rv = portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &an, &an_done);
   7981     if (SOC_FAILURE(rv)) return (rv);
   7982 
   7983     if(an.an_mode != phymod_AN_MODE_NONE) {
   7984         rv = PM4x25_AN_MODE_SET(unit, pm_info, an.an_mode, port_index);
   7985         if (SOC_FAILURE(rv)) return (rv);
   7986     }
   7987     else {
   7988         /* update an information before proceeding further */
   7989         SOC_IF_ERROR_RETURN(_pm4x25_an_mode_update (unit, port, pm_info, port_index, port_num_lanes, f_init_config->an_cl73));
   7990     }
   7991 
   7992     return (SOC_E_NONE);
   7993 }
   7994 
   7995 int pm4x25_port_timesync_config_set(int unit, int port, pm_info_t pm_info, const portmod_phy_timesync_config_t* config)
   7996 {
   7997     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7998     int nof_phys;
   7999     SOC_INIT_FUNC_DEFS;
   8000 
   8001     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8002                                                        phy_access ,(1+MAX_PHYN),
   8003                                                        &nof_phys));
   8004     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_config_set(unit, port, phy_access,
   8005                                                                   nof_phys,config));
   8006     exit:
   8007     SOC_FUNC_RETURN;   
   8008 }
   8009 
   8010 int pm4x25_port_timesync_config_get(int unit, int port, pm_info_t pm_info, portmod_phy_timesync_config_t* config)
   8011 {
   8012     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8013     int nof_phys;
   8014     SOC_INIT_FUNC_DEFS;
   8015 
   8016     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8017                                                        phy_access ,(1+MAX_PHYN),
   8018                                                        &nof_phys));
   8019     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_config_get(unit, port, phy_access,
   8020                                                                   nof_phys,config));
   8021     exit:
   8022     SOC_FUNC_RETURN;  
   8023 }
   8024 
   8025 int pm4x25_port_timesync_enable_set(int unit, int port, pm_info_t pm_info, uint32 enable)
   8026 {
   8027     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8028     int nof_phys;
   8029     SOC_INIT_FUNC_DEFS;
   8030 
   8031     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8032                                                        phy_access ,(1+MAX_PHYN),
   8033                                                        &nof_phys));
   8034     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_enable_set(unit, phy_access,
   8035                                                                   nof_phys,enable));
   8036     exit:
   8037     SOC_FUNC_RETURN;   
   8038 }
   8039 
   8040 int pm4x25_port_timesync_enable_get(int unit, int port, pm_info_t pm_info, uint32* enable)
   8041 {
   8042     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8043     int nof_phys;
   8044     SOC_INIT_FUNC_DEFS;
   8045 
   8046     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8047                                                        phy_access ,(1+MAX_PHYN),
   8048                                                        &nof_phys));
   8049     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_enable_get(unit, phy_access,
   8050                                                                   nof_phys,enable));
   8051 
   8052     exit:
   8053     SOC_FUNC_RETURN;
   8054 }
   8055 
   8056 int pm4x25_port_timesync_nco_addend_set(int unit, int port, pm_info_t pm_info, uint32 freq_step)
   8057 {
   8058     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8059     int nof_phys;
   8060     SOC_INIT_FUNC_DEFS;
   8061 
   8062     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8063                                                        phy_access ,(1+MAX_PHYN),
   8064                                                        &nof_phys));
   8065     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_nco_addend_set(unit, phy_access,
   8066                                                                       nof_phys,freq_step));
   8067     exit:
   8068     SOC_FUNC_RETURN;
   8069 }
   8070 
   8071 int pm4x25_port_timesync_nco_addend_get(int unit, int port, pm_info_t pm_info, uint32* freq_step)
   8072 {
   8073     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8074     int nof_phys;
   8075     SOC_INIT_FUNC_DEFS;
   8076 
   8077     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8078                                                        phy_access ,(1+MAX_PHYN),
   8079                                                        &nof_phys));
   8080     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_nco_addend_get(unit, phy_access,
   8081                                                                       nof_phys,freq_step));
   8082     exit:
   8083     SOC_FUNC_RETURN;
   8084 }
   8085 
   8086 int pm4x25_port_timesync_framesync_mode_set(int unit, int port, pm_info_t pm_info, 
   8087                                             const portmod_timesync_framesync_t* framesync)
   8088 {
   8089     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8090     int nof_phys;
   8091     SOC_INIT_FUNC_DEFS;
   8092 
   8093     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8094                                                        phy_access ,(1+MAX_PHYN),
   8095                                                        &nof_phys));
   8096     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_framesync_mode_set(unit, phy_access,
   8097                                                                           nof_phys,framesync));
   8098     exit:
   8099     SOC_FUNC_RETURN;
   8100 }
   8101 
   8102 int pm4x25_port_timesync_framesync_mode_get(int unit, int port, pm_info_t pm_info, 
   8103                                             portmod_timesync_framesync_t* framesync)
   8104 {
   8105     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8106     int nof_phys;
   8107     SOC_INIT_FUNC_DEFS;
   8108 
   8109     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8110                                                        phy_access ,(1+MAX_PHYN),
   8111                                                        &nof_phys));
   8112     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_framesync_mode_get(unit, phy_access,
   8113                                                                       nof_phys,framesync));
   8114     exit:
   8115     SOC_FUNC_RETURN;
   8116 }
   8117 
   8118 int pm4x25_port_timesync_local_time_set(int unit, int port, pm_info_t pm_info, const uint64 local_time)
   8119 {
   8120     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8121     int nof_phys;
   8122     SOC_INIT_FUNC_DEFS;
   8123 
   8124     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8125                                                        phy_access ,(1+MAX_PHYN),
   8126                                                        &nof_phys));
   8127     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_local_time_set(unit, phy_access,
   8128                                                                       nof_phys,local_time));
   8129     exit:
   8130     SOC_FUNC_RETURN;
   8131 }
   8132 
   8133 
   8134 int pm4x25_port_timesync_local_time_get(int unit, int port, pm_info_t pm_info, uint64* local_time)
   8135 {
   8136     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8137     int nof_phys;
   8138     SOC_INIT_FUNC_DEFS;
   8139 
   8140     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8141                                                        phy_access ,(1+MAX_PHYN),
   8142                                                        &nof_phys));
   8143     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_local_time_get(unit, phy_access, nof_phys,
   8144                                                                       local_time));
   8145     exit:
   8146     SOC_FUNC_RETURN;
   8147 }
   8148 
   8149 int pm4x25_port_timesync_load_ctrl_set(int unit, int port, pm_info_t pm_info, 
   8150                                        uint32 load_once, uint32 load_always)
   8151 {
   8152     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8153     int nof_phys;
   8154     SOC_INIT_FUNC_DEFS;
   8155 
   8156     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8157                                                        phy_access ,(1+MAX_PHYN),
   8158                                                        &nof_phys));
   8159     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_load_ctrl_set(unit, phy_access, nof_phys,
   8160                                                                      load_once, load_always));
   8161     exit:
   8162     SOC_FUNC_RETURN;
   8163 }
   8164 
   8165 int pm4x25_port_timesync_load_ctrl_get(int unit, int port, pm_info_t pm_info, 
   8166                                        uint32* load_once, uint32* load_always)
   8167 {
   8168     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8169     int nof_phys;
   8170     SOC_INIT_FUNC_DEFS;
   8171 
   8172     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8173                                                        phy_access ,(1+MAX_PHYN),
   8174                                                        &nof_phys));
   8175     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_load_ctrl_get(unit, phy_access, nof_phys,
   8176                                                                      load_once, load_always));
   8177     exit:
   8178     SOC_FUNC_RETURN;
   8179 }
   8180 
   8181 int pm4x25_port_timesync_tx_timestamp_offset_set(int unit, int port, pm_info_t pm_info, uint32 ts_offset)
   8182 {
   8183     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8184     int nof_phys;
   8185     SOC_INIT_FUNC_DEFS;
   8186 
   8187     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8188                                                        phy_access ,(1+MAX_PHYN),
   8189                                                        &nof_phys));
   8190     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_tx_timestamp_offset_set(unit, phy_access, nof_phys,
   8191                                                                                ts_offset));
   8192     exit:
   8193     SOC_FUNC_RETURN;
   8194 }
   8195 
   8196 int pm4x25_port_timesync_tx_timestamp_offset_get(int unit, int port, pm_info_t pm_info, uint32* ts_offset)
   8197 {
   8198     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8199     int nof_phys;
   8200     SOC_INIT_FUNC_DEFS;
   8201 
   8202     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8203                                                        phy_access ,(1+MAX_PHYN),
   8204                                                        &nof_phys));
   8205     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_tx_timestamp_offset_get(unit, phy_access, nof_phys,
   8206                                                                                ts_offset));
   8207     exit:
   8208     SOC_FUNC_RETURN;
   8209 }
   8210 
   8211 int pm4x25_port_timesync_rx_timestamp_offset_set(int unit, int port, pm_info_t pm_info, uint32 ts_offset)
   8212 {
   8213     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8214     int nof_phys;
   8215     SOC_INIT_FUNC_DEFS;
   8216 
   8217     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8218                                                        phy_access ,(1+MAX_PHYN),
   8219                                                        &nof_phys));
   8220     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_rx_timestamp_offset_set(unit, phy_access, nof_phys,
   8221                                                                                ts_offset));
   8222     exit:
   8223     SOC_FUNC_RETURN;
   8224 }
   8225 
   8226 int pm4x25_port_timesync_rx_timestamp_offset_get(int unit, int port, pm_info_t pm_info, uint32* ts_offset)
   8227 {
   8228     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8229     int nof_phys;
   8230     SOC_INIT_FUNC_DEFS;
   8231 
   8232     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8233                                                        phy_access ,(1+MAX_PHYN),
   8234                                                        &nof_phys));
   8235     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_rx_timestamp_offset_get(unit, phy_access, nof_phys,
   8236                                                                                ts_offset));
   8237     exit:
   8238     SOC_FUNC_RETURN;
   8239 }
   8240 
   8241 /*
   8242  *Function:
   8243  *  pm4x25_port_timestamp_adjust_set
   8244  *
   8245  *Purpose:
   8246  *  It sets tsts,osts adjustment into MAC registers.
   8247 */
   8248 int
   8249 pm4x25_port_timestamp_adjust_set(int unit, int port, pm_info_t pm_info,
   8250                          const soc_port_timestamp_adjust_t *ts_adjust)
   8251 {
   8252     int port_index;
   8253     uint32_t bitmap, port_dynamic_state;
   8254     portmod_port_ts_adjust_t portmod_ts_adjust;
   8255     SOC_INIT_FUNC_DEFS;
   8256 
   8257     sal_memset(&portmod_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   8258     portmod_ts_adjust.osts_adjust = ts_adjust->osts_adjust;
   8259     portmod_ts_adjust.tsts_adjust = ts_adjust->tsts_adjust;
   8260     _SOC_IF_ERR_EXIT(clmac_timestamp_delay_set(unit, port, portmod_ts_adjust));
   8261 
   8262     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &port_index, &bitmap));
   8263     _SOC_IF_ERR_EXIT(PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info, &port_dynamic_state, port_index));
   8264     PORTMOD_PORT_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED_SET(port_dynamic_state);
   8265     _SOC_IF_ERR_EXIT(PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info, port_dynamic_state, port_index));
   8266 
   8267     exit:
   8268     SOC_FUNC_RETURN;
   8269 }
   8270 
   8271 /*
   8272  *Function:
   8273  *  pm4x25_port_timestamp_adjust_get
   8274  *
   8275  *Purpose:
   8276  *  Get the tsts,osts adjustment from MAC register for current speed.
   8277  */
   8278 int
   8279 pm4x25_port_timestamp_adjust_get(int unit, int port, pm_info_t pm_info,
   8280                           soc_port_timestamp_adjust_t *ts_adjust)
   8281 {
   8282     portmod_port_ts_adjust_t portmod_ts_adjust;
   8283     SOC_INIT_FUNC_DEFS;
   8284 
   8285     sal_memset(&portmod_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   8286 
   8287     _SOC_IF_ERR_EXIT(clmac_timestamp_delay_get(unit, port, &portmod_ts_adjust));
   8288     ts_adjust->osts_adjust = portmod_ts_adjust.osts_adjust;
   8289     ts_adjust->tsts_adjust = portmod_ts_adjust.tsts_adjust;
   8290 
   8291     exit:
   8292     SOC_FUNC_RETURN;
   8293 }
   8294 
   8295 int pm4x25_port_control_phy_timesync_set(int unit, int port, pm_info_t pm_info, const portmod_port_control_phy_timesync_t config, uint64 value)
   8296 {
   8297     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8298     int nof_phys;
   8299     SOC_INIT_FUNC_DEFS;
   8300 
   8301     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8302                                                        phy_access ,(1+MAX_PHYN),
   8303                                                        &nof_phys));
   8304 
   8305     SOC_IF_ERROR_RETURN(portmod_port_phychain_control_phy_timesync_set(unit, port, phy_access, nof_phys,
   8306                                                                        config, value));
   8307 
   8308     exit:
   8309     SOC_FUNC_RETURN;
   8310 }
   8311 
   8312 int pm4x25_port_control_phy_timesync_get(int unit, int port, pm_info_t pm_info, const portmod_port_control_phy_timesync_t config, uint64* value)
   8313 {
   8314     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8315     int nof_phys;
   8316     SOC_INIT_FUNC_DEFS;
   8317 
   8318     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8319                                                        phy_access ,(1+MAX_PHYN),
   8320                                                        &nof_phys));
   8321 
   8322     SOC_IF_ERROR_RETURN(portmod_port_phychain_control_phy_timesync_get(unit, port, phy_access, nof_phys,
   8323                                                                        config, value));
   8324 
   8325     exit:
   8326     SOC_FUNC_RETURN;
   8327 }
   8328 
   8329 int pm4x25_xphy_lane_attach_to_pm (int unit, pm_info_t pm_info, int iphy, int phyn, const portmod_xphy_lane_connection_t* lane_conn)
   8330 {   
   8331     portmod_xphy_lane_connection_t *candidate_lane_conn = NULL;
   8332     int lane_index = 0, phy_index = 0;
   8333     int pm_is_active = 0, rv = 0;
   8334     uint32 xphy_id;
   8335     int lane_mask;
   8336     uint32 active_lanes;
   8337     SOC_INIT_FUNC_DEFS;
   8338 
   8339     /* Validate parameters */
   8340     _SOC_IF_ERR_EXIT(portmod_xphy_lane_connection_t_validate(unit,lane_conn));
   8341 
   8342     if (MAX_PHYN <= phyn){
   8343         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid Ext PHY location.")));
   8344     }
   8345     /* Making sure the port macro is not active */
   8346     rv = PM4x25_IS_ACTIVE_GET(unit, pm_info,&pm_is_active);
   8347     _SOC_IF_ERR_EXIT(rv);
   8348 
   8349     /* Attaching the external phy to the phy chain of the port macro */
   8350 
   8351     /* find lane index corresponding to internal physical port */
   8352     lane_index = 0;
   8353     PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy_index) {
   8354         if (phy_index == iphy) {
   8355             break;
   8356         }
   8357         lane_index++;
   8358     }
   8359 
   8360     candidate_lane_conn = &(PM_4x25_INFO(pm_info)->lane_conn[phyn-1][lane_index]);
   8361     sal_memcpy(candidate_lane_conn, lane_conn, sizeof(portmod_xphy_lane_connection_t));
   8362     rv = PM4x25_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, candidate_lane_conn, phyn-1, lane_index);
   8363     _SOC_IF_ERR_EXIT(rv);
   8364 
   8365     xphy_id = candidate_lane_conn->xphy_id;
   8366     lane_mask = candidate_lane_conn->ss_lane_mask;
   8367 
   8368     /*
   8369      * Keeping track of the xphy lane usage.  If the xphy lane is connected
   8370      * it will set the corresponding bit to mark as lane is active.
   8371      */
   8372 
   8373     if ((lane_mask != -1) && (xphy_id != PORTMOD_XPHY_ID_INVALID)) {
   8374         _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_get(unit, xphy_id, &active_lanes));
   8375         active_lanes |= lane_mask;
   8376         _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_set(unit,xphy_id, active_lanes));
   8377     }
   8378 
   8379     /* increment the nof_phys for that lane */
   8380     if (PM_4x25_INFO(pm_info)->nof_phys[lane_index] <= phyn){
   8381         PM_4x25_INFO(pm_info)->nof_phys[lane_index] = phyn+1;
   8382         rv = PM4x25_PORT_NUM_PHYS_SET(unit, pm_info, PM_4x25_INFO(pm_info)->nof_phys[lane_index], lane_index);
   8383         _SOC_IF_ERR_EXIT(rv);
   8384     }
   8385 
   8386 exit:
   8387    SOC_FUNC_RETURN;
   8388 }
   8389 
   8390 int pm4x25_xphy_lane_detach_from_pm (int unit, pm_info_t pm_info, int iphy, int phyn, portmod_xphy_lane_connection_t* lane_conn)
   8391 {
   8392 
   8393     portmod_xphy_lane_connection_t *candidate_lane_conn = NULL;
   8394     int lane_index = 0, phy_index = 0;
   8395     int pm_is_active = 0, rv = 0;
   8396     uint32 xphy_id;
   8397     int lane_mask;
   8398     uint32 active_lanes;
   8399     SOC_INIT_FUNC_DEFS;
   8400 
   8401     if (MAX_PHYN <= phyn){
   8402         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid Ext PHY location.")));
   8403     }
   8404     /* Making sure the port macro is not active */
   8405     rv = PM4x25_IS_ACTIVE_GET(unit, pm_info,&pm_is_active);
   8406     _SOC_IF_ERR_EXIT(rv);
   8407 
   8408     /* Attaching the external phy to the phy chain of the port macro */
   8409 
   8410     /* find lane index corresponding to internal physical port */
   8411     lane_index = 0;
   8412     PORTMOD_PBMP_ITER(PM_4x25_INFO(pm_info)->phys, phy_index) {
   8413         if (phy_index == iphy) {
   8414             break;
   8415         }
   8416         lane_index++;
   8417     }
   8418 
   8419     candidate_lane_conn = &(PM_4x25_INFO(pm_info)->lane_conn[phyn-1][lane_index]);
   8420 
   8421     xphy_id = candidate_lane_conn->xphy_id;
   8422     lane_mask = candidate_lane_conn->ss_lane_mask;
   8423 
   8424     /*
   8425      * Keeping track of the xphy lane usage.  If the xphy lane is disconnected
   8426      * it will clear the corresponding bit to mark as lane is not active.
   8427      * When none of the lane are active, it clear intialization status,
   8428      * phy_type and probe status.  When it probe again, it will re-initialize
   8429      * this xphy again.
   8430      */
   8431 
   8432     if ((lane_mask != -1) && (xphy_id != PORTMOD_XPHY_ID_INVALID)) {
   8433 
   8434         _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_get(unit, xphy_id, &active_lanes));
   8435         active_lanes &= ~lane_mask;
   8436         _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_set(unit, xphy_id, active_lanes));
   8437 
   8438         if (active_lanes == 0) { /* none of the lanes are active */
   8439             _SOC_IF_ERR_EXIT(portmod_xphy_core_probed_set(unit, xphy_id, 0));
   8440             _SOC_IF_ERR_EXIT(portmod_xphy_phy_type_set(unit,xphy_id,
   8441                                                   phymodDispatchTypeInvalid));
   8442             _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_set(unit, xphy_id,0));
   8443         }
   8444     }
   8445 
   8446     sal_memcpy( lane_conn, candidate_lane_conn, sizeof(portmod_xphy_lane_connection_t));
   8447     portmod_xphy_lane_connection_t_init(unit, candidate_lane_conn); 
   8448     rv = PM4x25_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, candidate_lane_conn, phyn-1, lane_index);
   8449     _SOC_IF_ERR_EXIT(rv);
   8450 
   8451     /* decrement the nof_phys for that lane */
   8452     if (phyn > 0){
   8453         PM_4x25_INFO(pm_info)->nof_phys[lane_index] = phyn;
   8454         rv = PM4x25_PORT_NUM_PHYS_SET(unit, pm_info, PM_4x25_INFO(pm_info)->nof_phys[lane_index], lane_index);
   8455         _SOC_IF_ERR_EXIT(rv);
   8456     }
   8457 
   8458 exit:
   8459    SOC_FUNC_RETURN;
   8460 }
   8461 
   8462 int pm4x25_port_update_dynamic_state(int unit, int port, pm_info_t pm_info, uint32_t port_dynamic_state) {
   8463     int rv = 0;
   8464     int port_index;
   8465     uint32_t bitmap;
   8466     phymod_an_mode_type_t an_mode;
   8467     uint32_t an_updated = FALSE, tmp_state;
   8468     SOC_INIT_FUNC_DEFS;
   8469    
   8470     rv = _pm4x25_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   8471     if (SOC_FAILURE(rv)) {
   8472         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Unable to retrieve the port index")));
   8473     }
   8474 
   8475     if (PORTMOD_PORT_IS_AUTONEG_MODE_UPDATED(port_dynamic_state)) {
   8476         rv = PM4x25_PORT_DYNAMIC_STATE_GET(unit, pm_info, &tmp_state,
   8477                                            port_index);
   8478         _SOC_IF_ERR_EXIT(rv);
   8479         /* we need to change the data base An_mode based on the new value */
   8480         switch (port_dynamic_state >> 16 & 0xffff) {
   8481         case SOC_PHY_CONTROL_AUTONEG_MODE_CL37:
   8482             an_mode = phymod_AN_MODE_CL37;
   8483             an_updated = TRUE;
   8484             break;
   8485         case SOC_PHY_CONTROL_AUTONEG_MODE_CL37_BAM:
   8486             an_mode = phymod_AN_MODE_CL37BAM;
   8487             an_updated = TRUE;
   8488             break;
   8489         case SOC_PHY_CONTROL_AUTONEG_MODE_CL73:
   8490             an_mode = phymod_AN_MODE_CL73;
   8491             an_updated = TRUE;
   8492             break;
   8493         case SOC_PHY_CONTROL_AUTONEG_MODE_CL73_BAM:
   8494             an_mode = phymod_AN_MODE_CL73BAM;
   8495             an_updated = TRUE;
   8496             break;
   8497         default:
   8498             break;
   8499         }
   8500     } else if (PORTMOD_PORT_IS_DEFAULT_TX_PARAMS_UPDATED(port_dynamic_state)) {
   8501         rv = PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info,
   8502                                       port_dynamic_state, port_index);
   8503         _SOC_IF_ERR_EXIT(rv);
   8504     }
   8505     if (an_updated == TRUE) {
   8506         rv = PM4x25_AN_MODE_SET(unit, pm_info, an_mode, port_index);
   8507         _SOC_IF_ERR_EXIT(rv);
   8508         PORTMOD_PORT_AUTONEG_MODE_UPDATED_SET(tmp_state);
   8509         rv = PM4x25_PORT_DYNAMIC_STATE_SET(unit, pm_info, tmp_state,
   8510                                            port_index);
   8511         _SOC_IF_ERR_EXIT(rv);
   8512     }
   8513 
   8514 exit:
   8515     SOC_FUNC_RETURN;
   8516 }
   8517 
   8518 int pm4x25_port_phy_op_mode_get(int unit, int port, pm_info_t pm_info, phymod_operation_mode_t* val)
   8519 {
   8520     /* there is no opmode config for internal PHYS return 0*/
   8521     *val = 0;
   8522     return (SOC_E_NONE);
   8523 }
   8524 
   8525 int pm4x25_port_medium_config_set(int unit, int port, pm_info_t pm_info, soc_port_medium_t medium, soc_phy_config_t* config)
   8526 {
   8527     int rv;
   8528     SOC_INIT_FUNC_DEFS;
   8529 
   8530     rv = portmod_port_phychain_medium_config_set(unit, port, medium, config);
   8531     if (SOC_FAILURE(rv)) return (rv);
   8532 
   8533     SOC_FUNC_RETURN;
   8534 }
   8535 
   8536 int pm4x25_port_medium_config_get(int unit, int port, pm_info_t pm_info, soc_port_medium_t medium, soc_phy_config_t* config)
   8537 {
   8538     int rv;
   8539     SOC_INIT_FUNC_DEFS;
   8540 
   8541     rv = portmod_port_phychain_medium_config_get(unit, port, medium, config);
   8542     if (SOC_FAILURE(rv)) return (rv);
   8543 
   8544     SOC_FUNC_RETURN;
   8545 }
   8546 
   8547 int pm4x25_port_medium_get(int unit, int port, pm_info_t pm_info, soc_port_medium_t* medium)
   8548 {
   8549     int rv;
   8550     SOC_INIT_FUNC_DEFS;
   8551 
   8552     rv = portmod_port_phychain_medium_get(unit, port, medium);
   8553 
   8554     if (SOC_FAILURE(rv)) return (rv);
   8555 
   8556     SOC_FUNC_RETURN;
   8557 }
   8558 
   8559 int pm4x25_port_multi_get(int unit, int port, pm_info_t pm_info, portmod_multi_get_t* multi_get)
   8560 {
   8561     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8562     int nof_phys;
   8563     SOC_INIT_FUNC_DEFS;
   8564 
   8565     _SOC_IF_ERR_EXIT
   8566         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   8567                                            phy_access ,(1+MAX_PHYN),
   8568                                            &nof_phys));
   8569     _SOC_IF_ERR_EXIT
   8570         (portmod_port_phychain_multi_get(unit, port, phy_access, nof_phys, multi_get));
   8571 
   8572 exit:
   8573     SOC_FUNC_RETURN;
   8574 
   8575 }
   8576 
   8577 int pm4x25_port_lane_map_set(int unit, int port, pm_info_t pm_info, uint32 flags, const phymod_lane_map_t* lane_map)
   8578 {
   8579     SOC_INIT_FUNC_DEFS;
   8580 
   8581     PM_4x25_INFO(pm_info)->lane_map = *lane_map;
   8582 
   8583 
   8584     SOC_FUNC_RETURN;
   8585 }
   8586 
   8587 int pm4x25_port_lane_map_get(int unit, int port, pm_info_t pm_info, uint32 flags, phymod_lane_map_t* lane_map)
   8588 {
   8589     SOC_INIT_FUNC_DEFS;
   8590 
   8591     *lane_map = PM_4x25_INFO(pm_info)->lane_map;
   8592 
   8593 
   8594     SOC_FUNC_RETURN;
   8595 }
   8596 
   8597 int pm4x25_port_polarity_set(int unit, int port, pm_info_t pm_info, const phymod_polarity_t* polarity)
   8598 {
   8599     SOC_INIT_FUNC_DEFS;
   8600 
   8601     PM_4x25_INFO(pm_info)->polarity = *polarity;
   8602 
   8603 
   8604     SOC_FUNC_RETURN;
   8605 }
   8606 
   8607 int pm4x25_port_polarity_get(int unit, int port, pm_info_t pm_info, phymod_polarity_t* polarity)
   8608 {
   8609     SOC_INIT_FUNC_DEFS;
   8610 
   8611     *polarity = PM_4x25_INFO(pm_info)->polarity;
   8612 
   8613 
   8614     SOC_FUNC_RETURN;
   8615 }
   8616 
   8617 int pm4x25_pm_is_in_pm12x10(int unit, pm_info_t pm_info, int* in_pm12x10)
   8618 {
   8619     SOC_INIT_FUNC_DEFS;
   8620 
   8621     if (PM_4x25_INFO(pm_info)->in_pm12x10){
   8622         *in_pm12x10 = 1;
   8623     } else {
   8624         *in_pm12x10 = 0;
   8625     }
   8626 
   8627     SOC_FUNC_RETURN;
   8628 }
   8629 
   8630 /*
   8631  * This function will be called during speed change or flexport.
   8632  * This function returns pll_div value by looking up the static table.
   8633  * In flexport scenario, this funciton might be called before port is attached. The port number may be invalid(-1).
   8634  * So this function can't access registers by logical port number, or access Warmboot DB.
   8635  */
   8636 int pm4x25_port_pll_div_get(int unit, int port, pm_info_t pm_info,
   8637                             const portmod_port_resources_t* port_resource,
   8638                             uint32_t* pll_div)
   8639 {
   8640     int higig = SOC_ENCAP_IEEE;
   8641 
   8642     SOC_INIT_FUNC_DEFS;
   8643 
   8644     higig = ((port_resource->encap_mode == SOC_ENCAP_HIGIG2) ||
   8645              (port_resource->encap_mode == SOC_ENCAP_HIGIG)) ? 1 : 0;
   8646 
   8647     switch (port_resource->speed){
   8648        case 1000:
   8649            if (PORTMOD_SERDES_1000X_AT_25G_GET(port_resource->flag)) {
   8650                *pll_div = phymod_TSCF_PLL_DIV165;
   8651            } else {
   8652                *pll_div = phymod_TSCF_PLL_DIV132;
   8653            }
   8654             break;
   8655        case 10000:
   8656             if (PORTMOD_SERDES_10G_AT_25G_GET(port_resource->flag)) {
   8657                *pll_div = phymod_TSCF_PLL_DIV165;
   8658             } else {
   8659                *pll_div = phymod_TSCF_PLL_DIV132;
   8660             }
   8661             break;
   8662        case 11000:
   8663            *pll_div = phymod_TSCF_PLL_DIV140;
   8664             break;
   8665        case 12000:
   8666            *pll_div = phymod_TSCF_PLL_DIV160;
   8667             break;
   8668        case 20000:
   8669            *pll_div = phymod_TSCF_PLL_DIV132;
   8670             break;
   8671        case 21000:
   8672        case 21200:
   8673            *pll_div = phymod_TSCF_PLL_DIV140;
   8674             break;
   8675        case 25000:
   8676            *pll_div = phymod_TSCF_PLL_DIV165;
   8677             break;
   8678        case 27000:
   8679            *pll_div = phymod_TSCF_PLL_DIV175;
   8680             break;
   8681        case 40000:
   8682            *pll_div = phymod_TSCF_PLL_DIV132;
   8683             break;
   8684        case 42000:
   8685            *pll_div = phymod_TSCF_PLL_DIV140;
   8686             break;
   8687        case 48000:
   8688            *pll_div = phymod_TSCF_PLL_DIV160;
   8689             break;
   8690        case 50000:
   8691            *pll_div = phymod_TSCF_PLL_DIV165;
   8692             break;
   8693        case 53000:
   8694             if (port_resource->num_lane == 2) {
   8695                 *pll_div = phymod_TSCF_PLL_DIV175;
   8696             } else {
   8697                 *pll_div = phymod_TSCF_PLL_DIV165;
   8698             }
   8699             break;
   8700        case 100000:
   8701            if (higig){
   8702                *pll_div = phymod_TSCF_PLL_DIV160;
   8703             } else {
   8704                *pll_div = phymod_TSCF_PLL_DIV165;
   8705             }
   8706             break;
   8707        case 106000:
   8708            *pll_div = phymod_TSCF_PLL_DIV175;
   8709             break;
   8710        default:
   8711            *pll_div = phymod_TSCF_PLL_DIV175;
   8712             break;
   8713     }
   8714 
   8715     SOC_FUNC_RETURN;
   8716 }
   8717 
   8718 int pm4x25_port_master_set(int unit, int port, pm_info_t pm_info, int master_mode)
   8719 {
   8720     SOC_INIT_FUNC_DEFS;
   8721 
   8722     _SOC_IF_ERR_EXIT(portmod_port_phychain_master_set(unit, port, pm_info, master_mode));
   8723 
   8724 exit:
   8725     SOC_FUNC_RETURN;
   8726 }
   8727 
   8728 int pm4x25_port_master_get(int unit, int port, pm_info_t pm_info, int* master_mode)
   8729 {
   8730     SOC_INIT_FUNC_DEFS;
   8731 
   8732     _SOC_IF_ERR_EXIT(portmod_port_phychain_master_get(unit, port, pm_info, master_mode));
   8733 
   8734 exit:
   8735     SOC_FUNC_RETURN;
   8736 }
   8737 
   8738 /*
   8739  * Function:
   8740  *      _pm4x25_preemption_rx_frag_size_set
   8741  * Purpose:
   8742  *      This function configures preemption rx fragment size
   8743  *      of final and non-final fragments.
   8744  *
   8745  * Parameters:
   8746  *      unit                -(IN) Device unit number
   8747  *      port                -(IN) logical port
   8748  *      final_frag          -(IN) if set indicates final fragment
   8749  *      value               -(IN) value of fragment size
   8750  */
   8751 STATIC
   8752 int _pm4x25_preemption_rx_frag_size_set(int unit, int port, pm_info_t pm_info,
   8753                                         uint32 frag, uint32 value)
   8754 {
   8755     int phy_acc;
   8756     uint32_t rval;
   8757     soc_field_t field;
   8758     SOC_INIT_FUNC_DEFS;
   8759 
   8760     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8761 
   8762     _SOC_IF_ERR_EXIT(READ_CLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, &rval));
   8763 
   8764     if (frag == PORTMOD_PREEMPTION_FINAL_FRAG) {
   8765         field = MIN_FINAL_FRAG_SIZEf;
   8766     } else {
   8767         field = MIN_NON_FINAL_FRAG_SIZEf;
   8768     }
   8769 
   8770     soc_reg_field_set(unit, CLPORT_MIB_MIN_FRAG_SIZEr, &rval, field, value);
   8771     _SOC_IF_ERR_EXIT(WRITE_CLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, rval));
   8772 
   8773 exit:
   8774     SOC_FUNC_RETURN;
   8775 
   8776 }
   8777 
   8778 /*
   8779  * Function:
   8780  *      _pm4x25_preemption_rx_frag_size_get
   8781  * Purpose:
   8782  *      This function configures preemption rx fragment size
   8783  *      of final and non-final fragments.
   8784  *
   8785  * Parameters:
   8786  *      unit                -(IN)  Device unit number
   8787  *      port                -(IN)  logical port
   8788  *      final_frag          -(IN)  if set indicates final fragment
   8789  *      value               -(OUT) value of fragment size
   8790  */
   8791 STATIC
   8792 int _pm4x25_preemption_rx_frag_size_get(int unit, int port, pm_info_t pm_info,
   8793                                         uint32 frag, uint32 *value)
   8794 {
   8795     int phy_acc;
   8796     uint32_t rval;
   8797     soc_field_t field;
   8798     SOC_INIT_FUNC_DEFS;
   8799 
   8800     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8801 
   8802     _SOC_IF_ERR_EXIT(READ_CLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, &rval));
   8803 
   8804     if (frag == PORTMOD_PREEMPTION_FINAL_FRAG) {
   8805         field = MIN_FINAL_FRAG_SIZEf;
   8806     } else {
   8807         field = MIN_NON_FINAL_FRAG_SIZEf;
   8808     }
   8809 
   8810     *value = soc_reg_field_get(unit, CLPORT_MIB_MIN_FRAG_SIZEr, rval, field);
   8811 
   8812 exit:
   8813     SOC_FUNC_RETURN;
   8814 
   8815 }
   8816 
   8817 /*
   8818  * Function:
   8819  *      pm4x25_preemption_control_set
   8820  * Purpose:
   8821  *      This function configures preemption feature parameters
   8822  *      The application layer has to call this function with
   8823  *      associated preemption-controls to configure parameters.
   8824  * Parameters:
   8825  *      unit                -(IN) Device unit number
   8826  *      port                -(IN) logical port
   8827  *      type                -(IN) preemption parameter to be configured
   8828  *      value               -(IN) value
   8829  * Returns:
   8830  *      Status
   8831  */
   8832 int pm4x25_preemption_control_set(int unit, int port, pm_info_t pm_info,
   8833                                   portmod_preemption_control_t type,
   8834                                   uint32 value)
   8835 {
   8836     SOC_INIT_FUNC_DEFS;
   8837 
   8838     switch(type) {
   8839         case  portmodPreemptionControlInvalid:
   8840             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   8841               (_SOC_MSG("Invalid preemption control type(%d)"), type));
   8842             break;
   8843         case  portmodPreemptionControlPreemptionSupport:
   8844             /* Enable/disable port preemption capability support */
   8845             _SOC_IF_ERR_EXIT(clmac_preemption_mode_set(unit, port, value));
   8846             break;
   8847         case  portmodPreemptionControlEnableTx:
   8848             /*
   8849              * Enable/disable port preemption on tx side
   8850              * if verify_enable = 1
   8851              * this function call blocks until, verify operation is complete
   8852              * if verify_enable = 0
   8853              * means static preemption, function call returns immediately
   8854              * after enabling preemption in the hardware in tx direction
   8855              */
   8856             _SOC_IF_ERR_EXIT(clmac_preemption_tx_enable_set(unit, port, value));
   8857             break;
   8858         case  portmodPreemptionControlVerifyEnable:
   8859             /*
   8860              * Enable/disable verify operation.
   8861              * Before enabling the verify operation on a port,
   8862              * the number of attempts for a veriy operation and
   8863              * the timeout for each verify operation should be configured
   8864              */
   8865             _SOC_IF_ERR_EXIT(
   8866                 clmac_preemption_verify_enable_set(unit, port, value));
   8867             break;
   8868         case  portmodPreemptionControlVerifyTime:
   8869             /*
   8870              * Configuring the verify timeout is valid only when verify
   8871              * operation is enabled.
   8872              * The timeout here means, if verify operation is not complete
   8873              * success/failure/inprogress after the (timeout + 1) millisecs
   8874              * the MAC sends another verify message to the link partner
   8875              */
   8876             _SOC_IF_ERR_EXIT(
   8877                 clmac_preemption_verify_time_set(unit, port, value));
   8878             break;
   8879         case  portmodPreemptionControlVerifyAttempts:
   8880             /*
   8881              * Configuring the number of verify attempts is valid only when
   8882              * verify operation is enabled.
   8883              * If verify operation is not complete success/failure/inprogress
   8884              * after the (timeout + 1) millisecs the MAC sends another verify
   8885              * to the link partner. The MAC tries for (num_verify_attempts + 1)
   8886              * to complete the verify operation.
   8887              */
   8888             _SOC_IF_ERR_EXIT(
   8889                 clmac_preemption_verify_attempts_set(unit, port, value)); 
   8890             break;
   8891         case  portmodPreemptionControlNonFinalFragSizeRx:
   8892             /* configure non-final rx fragment size */
   8893             _SOC_IF_ERR_EXIT(
   8894                 _pm4x25_preemption_rx_frag_size_set(unit, port, pm_info,
   8895                                       PORTMOD_PREEMPTION_NON_FINAL_FRAG,
   8896                                       value));
   8897             break;
   8898         case  portmodPreemptionControlFinalFragSizeRx:
   8899             /* configure final rx fragment size */
   8900             _SOC_IF_ERR_EXIT(
   8901                 _pm4x25_preemption_rx_frag_size_set(unit, port, pm_info,
   8902                                           PORTMOD_PREEMPTION_FINAL_FRAG,
   8903                                           value));
   8904             break;
   8905         default:
   8906             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   8907               (_SOC_MSG("Invalid preemption control type(%d)"), type));
   8908             break;
   8909     }
   8910 
   8911 exit:
   8912     SOC_FUNC_RETURN;
   8913 
   8914 }
   8915 
   8916 /*
   8917  * Function:
   8918  *      pm4x25_preemption_control_get
   8919  * Purpose:
   8920  *      This function gets the value of preemption parameters
   8921  *      configured. The application layer has to call this function with
   8922  *      associated preemption-controls to configure parameters.
   8923  * Parameters:
   8924  *      unit                -(IN) Device unit number
   8925  *      port                -(IN) logical port
   8926  *      type                -(IN) preemption parameter to be configured
   8927  *      value               -(OUT) value returned from hardware
   8928  * Returns:
   8929  *      Status
   8930  */
   8931 int pm4x25_preemption_control_get(int unit, int port, pm_info_t pm_info,
   8932                                   portmod_preemption_control_t type,
   8933                                   uint32 *value)
   8934 {
   8935     SOC_INIT_FUNC_DEFS;
   8936 
   8937     switch(type) {
   8938         case  portmodPreemptionControlInvalid:
   8939             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   8940               (_SOC_MSG("Invalid preemption control type(%d)"), type));
   8941             break;
   8942         case  portmodPreemptionControlPreemptionSupport:
   8943             _SOC_IF_ERR_EXIT(clmac_preemption_mode_get(unit, port, value));
   8944             break;
   8945         case  portmodPreemptionControlEnableTx:
   8946             _SOC_IF_ERR_EXIT(clmac_preemption_tx_enable_get(unit, port, value));
   8947             break;
   8948         case  portmodPreemptionControlVerifyEnable:
   8949             _SOC_IF_ERR_EXIT(
   8950                 clmac_preemption_verify_enable_get(unit, port, value));
   8951             break;
   8952         case  portmodPreemptionControlVerifyTime:
   8953             _SOC_IF_ERR_EXIT(
   8954                 clmac_preemption_verify_time_get(unit, port, value));
   8955             break;
   8956         case  portmodPreemptionControlVerifyAttempts:
   8957             _SOC_IF_ERR_EXIT(
   8958                 clmac_preemption_verify_attempts_get(unit, port, value));
   8959             break;
   8960         case  portmodPreemptionControlNonFinalFragSizeRx:
   8961             /* get non-final rx fragment size */
   8962             _SOC_IF_ERR_EXIT(
   8963                 _pm4x25_preemption_rx_frag_size_get(unit, port, pm_info,
   8964                                       PORTMOD_PREEMPTION_NON_FINAL_FRAG,
   8965                                       value));
   8966             break;
   8967         case  portmodPreemptionControlFinalFragSizeRx:
   8968             /* get final rx fragment size */
   8969             _SOC_IF_ERR_EXIT(
   8970                 _pm4x25_preemption_rx_frag_size_get(unit, port, pm_info,
   8971                                           PORTMOD_PREEMPTION_FINAL_FRAG,
   8972                                           value));
   8973             break;
   8974         default:
   8975             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   8976               (_SOC_MSG("Invalid preemption control type(%d)"), type));
   8977             break;
   8978     }
   8979 
   8980 exit:
   8981     SOC_FUNC_RETURN;
   8982 }
   8983 
   8984 /*!
   8985  * pm4x25_preemption_tx_status_get
   8986  *
   8987  * @brief Get the preemption status on the transmit side Indicates if
   8988  *        preemption on a port is
   8989  *        Inactive: (Verifiy is enabled but its status is either failed
   8990  *                  or not initiated) or (preemption is not enabled)
   8991  *        Verify in progress: Preemption is enabled and Verify is
   8992  *                            enabled and its operation is in progress
   8993  *        Active: Preemption is enabled and ((Verify is enabled and
   8994  *                succeeded) or (Verify is NOT enabled))
   8995  *
   8996  * @param [in]  unit            - unit id
   8997  * @param [in]  port            - logical port
   8998  * @param [out] value           - indicates preemption status in tx direction.
   8999  */
   9000 int pm4x25_preemption_tx_status_get(int unit, int port,
   9001                                     pm_info_t pm_info,
   9002                                     uint32* value)
   9003 {
   9004     return (clmac_preemption_tx_status_get(unit, port,
   9005                                            CLMAC_PREEMPTION_TX_STATUS,
   9006                                            value));
   9007 }
   9008 
   9009 /*!
   9010  * pm4x25_preemption_verify_status_get
   9011  *
   9012  * @brief Get the preemption verify status.
   9013  *        This function gets verify operation status or verify count
   9014  *        status based on the verify status type argument.
   9015  *
   9016  * @param [in]  unit            - unit id
   9017  * @param [in]  port            - logical port
   9018  * @param [in]  type            - portmod_preemption_verify_status_type_t
   9019  * @param [out] value           - indicates preemption verify op status
   9020  */
   9021 int pm4x25_preemption_verify_status_get(int unit, int port,
   9022                                  pm_info_t pm_info,
   9023                                  portmod_preemption_verify_status_type_t type,
   9024                                  uint32* value)
   9025 {
   9026     SOC_INIT_FUNC_DEFS;
   9027 
   9028     switch (type) {
   9029         case portmodPreemptionVerifyStatus:
   9030             _SOC_IF_ERR_EXIT(clmac_preemption_tx_status_get(unit, port,
   9031                                        CLMAC_PREEMPTION_VERIFY_STATUS,
   9032                                        value));
   9033             break;
   9034         case portmodPreemptionVerifyCountStatus:
   9035             _SOC_IF_ERR_EXIT(clmac_preemption_tx_status_get(unit, port,
   9036                                   CLMAC_PREEMPTION_VERIFY_CNT_STATUS,
   9037                                   value));
   9038             break;
   9039         default:
   9040             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   9041               (_SOC_MSG("Invalid verify status type(%d)"), type));
   9042             break;
   9043     }
   9044 
   9045 exit:
   9046     SOC_FUNC_RETURN;
   9047 }
   9048 
   9049 /*!
   9050  * portmod_preemption_force_rx_eop_mode_set
   9051  *
   9052  * @brief Set preemption forced rx lost eop(end of packet) sequence mode
   9053  * setting. The rx lost eop sequence can be either software or hardware
   9054  * enforced.
   9055  * If HW based rx lost eop is enabled, link down or rx disable even
   9056  * forces rx_lost_eop sequence after some internal delay if preempt
   9057  * packet EOP was not sent.
   9058  * If Sw based rx lost eop is enabled,  the application rx eop sequence
   9059  * When SW rx lost EOP is enabled(done by application layer), rising
   9060  * edge MAC forces rx_lost_eop sequence after some internal delay if
   9061  * preempt packet EOP was not sent.
   9062  *
   9063  * @param [in]  unit            - unit id
   9064  * @param [in]  port            - logical port
   9065  * @param [in]  enable          - enable/disable
   9066  * @param [in]  timeout_cnt     - timeout in millisecs
   9067  */
   9068 int pm4x25_preemption_force_rx_eop_mode_set(int unit, int port,
   9069                               pm_info_t pm_info,
   9070                               portmod_preemption_force_rx_eop_mode_t type,
   9071                               uint32 value)
   9072 {
   9073     SOC_INIT_FUNC_DEFS;
   9074 
   9075     switch (type) {
   9076         case portmodPreemptionForceSwRxEop:
   9077             _SOC_IF_ERR_EXIT(clmac_preemption_force_rx_lost_eop_set(unit, port,
   9078                                               CLMAC_PREEMPTION_FORCE_SW_RX_EOP,
   9079                                               value));
   9080             break;
   9081         case portmodPreemptionForceAutoHwEop:
   9082             _SOC_IF_ERR_EXIT(clmac_preemption_force_rx_lost_eop_set(unit, port,
   9083                                          CLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP,
   9084                                          value));
   9085             break;
   9086         default:
   9087             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   9088               (_SOC_MSG("Invalid Force RX lost EOP type(%d)"), type));
   9089             break;
   9090     }
   9091 
   9092 exit:
   9093     SOC_FUNC_RETURN;
   9094 }
   9095 
   9096 /*!
   9097  * pm4x25_preemption_force_rx_eop_mode_get
   9098  *
   9099  * @brief Get preemption forced rx lost eop(end of packet) sequence mode
   9100  * setting. The rx lost eop sequence can be either software or hardware
   9101  * enforced.
   9102  * This functin returns the rx lost eop setting based on the type
   9103  * of lost eop is enforced.
   9104  *
   9105  *
   9106  * @param [in]  unit            - unit id
   9107  * @param [in]  port            - logical port
   9108  * @param [out] type            - portmod_preemption_force_rx_eop_mode_t
   9109  * @param [out] value           - timeout in millisecs
   9110  */
   9111 int pm4x25_preemption_force_rx_eop_mode_get(int unit, int port,
   9112                                  pm_info_t pm_info,
   9113                                  portmod_preemption_force_rx_eop_mode_t type,
   9114                                  uint32 *value)
   9115 {
   9116     SOC_INIT_FUNC_DEFS;
   9117 
   9118     switch (type) {
   9119         case portmodPreemptionForceSwRxEop:
   9120             _SOC_IF_ERR_EXIT(clmac_preemption_force_rx_lost_eop_get(unit, port,
   9121                                               CLMAC_PREEMPTION_FORCE_SW_RX_EOP,
   9122                                               value));
   9123             break;
   9124         case portmodPreemptionForceAutoHwEop:
   9125             _SOC_IF_ERR_EXIT(clmac_preemption_force_rx_lost_eop_get(unit, port,
   9126                                          CLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP,
   9127                                          value));
   9128             break;
   9129         default:
   9130             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   9131               (_SOC_MSG("Invalid Force RX lost EOP type(%d)"), type));
   9132             break;
   9133     }
   9134 
   9135 exit:
   9136     SOC_FUNC_RETURN;
   9137 }
   9138 int pm4x25_port_lane_count_get (int unit, int port, pm_info_t pm_info, int line_side, int* num_lanes)
   9139 {
   9140     portmod_access_get_params_t params;
   9141     phymod_phy_access_t phy_access;
   9142     int nof_phys;
   9143     int is_outer_most = 0;
   9144     SOC_INIT_FUNC_DEFS;
   9145 
   9146     /* coverity[check_return] */
   9147     portmod_access_get_params_t_init(unit, &params);
   9148 
   9149     if(line_side){
   9150         params.sys_side =  PORTMOD_SIDE_LINE;
   9151     } else {
   9152         params.sys_side =  PORTMOD_SIDE_SYSTEM;
   9153     }
   9154 
   9155     _SOC_IF_ERR_EXIT(pm4x25_port_phy_lane_access_get(unit, port, pm_info,
   9156                                                      &params, 1 , &phy_access,
   9157                                                      &nof_phys, &is_outer_most));
   9158 
   9159     *num_lanes = 0;
   9160     PORTMOD_BIT_COUNT(phy_access.access.lane_mask,*num_lanes);
   9161 
   9162 exit:
   9163     SOC_FUNC_RETURN;
   9164 }
   9165 
   9166 /*!
   9167  * pm4x25_preemption_rx_timeout_set
   9168  *
   9169  * @brief Set specified preemption rx timeout and timeout count.
   9170  * This function should only be called during device init.
   9171  * There are 2 rx parameters rx timeout enable, rx timeout value in microsec
   9172  * that can be configured using this function.
   9173  * If set, enables TIMEOUT mechanism for Rx preempt traffic.
   9174  * Timeout value in microsec, this configuration indicates link idle
   9175  * time(in microsec) after which Rx timeout will force rx_lost_eop sequence
   9176  * if preempt packet EOP was not sent.
   9177  *
   9178  * @param [in]  unit            - unit id
   9179  * @param [in]  port            - logical port
   9180  * @param [in]  enable          - enables timeout for rx preempt traffic
   9181  * @param [in]  timeout_cnt     - timeout in microsecs
   9182  */
   9183 int pm4x25_preemption_rx_timeout_set(int unit, int port, pm_info_t pm_info,
   9184                                      uint32 enable, uint32 timeout_cnt)
   9185 {
   9186     return (clmac_preemption_rx_timeout_info_set(unit, port, enable,
   9187                                                  timeout_cnt));
   9188 }
   9189 
   9190 /*!
   9191  * pm4x25_preemption_rx_timeout_set
   9192  *
   9193  * @brief Get specified preemption rx timeout and timeout count.
   9194  *
   9195  * @param [in]  unit            - unit id
   9196  * @param [in]  port            - logical port
   9197  * @param [in]  enable          - enables timeout for rx preempt traffic
   9198  * @param [out] timeout_cnt     - timeout in millisec
   9199  */
   9200 int pm4x25_preemption_rx_timeout_get(int unit, int port, pm_info_t pm_info,
   9201                                      uint32 *enable, uint32 *timeout_cnt)
   9202 {
   9203     return (clmac_preemption_rx_timeout_info_get(unit, port, enable,
   9204                                                  timeout_cnt));
   9205 }
   9206 
   9207 STATIC
   9208 int _pm4x25_phy_timesync_tx_info_get(int unit, int port, pm_info_t pm_info, portmod_fifo_status_t* tx_info)
   9209 {
   9210     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9211     int nof_phys;
   9212     phymod_ts_fifo_status_t phy_ts_tx_info;
   9213     SOC_INIT_FUNC_DEFS;
   9214 
   9215     _SOC_IF_ERR_EXIT(phymod_ts_fifo_status_t_init(&phy_ts_tx_info));
   9216 
   9217     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9218                                                        phy_access ,(1+MAX_PHYN),
   9219                                                        &nof_phys));
   9220     _SOC_IF_ERR_EXIT(portmod_port_phychain_timesync_tx_info_get(unit, port, phy_access,
   9221                                                                   nof_phys, &phy_ts_tx_info));
   9222 
   9223     tx_info->timestamps_in_fifo = phy_ts_tx_info.ts_in_fifo_lo;
   9224     tx_info->timestamps_in_fifo_hi = phy_ts_tx_info.ts_in_fifo_hi;
   9225     tx_info->sequence_id = phy_ts_tx_info.ts_seq_id;
   9226     tx_info->timestamp_sub_nanosec = phy_ts_tx_info.ts_sub_nanosec;
   9227 
   9228 exit:
   9229     SOC_FUNC_RETURN;
   9230 }
   9231 
   9232 /*!
   9233  * pm4x10_port_timesync_tx_info_get
   9234  *
   9235  * @brief get port timestamps in fifo
   9236  *
   9237  * @param [in]  unit            - unit id
   9238  * @param [in]  port            - logical port
   9239  * @param [inout]  tx_info         - timestamp and seq id form fifo
   9240  */
   9241 
   9242 int pm4x25_port_timesync_tx_info_get(int unit, int port, pm_info_t pm_info, portmod_fifo_status_t* tx_info)
   9243 {
   9244     int phy_acc, mac_ts_disable;
   9245     uint32 reg_val;
   9246     SOC_INIT_FUNC_DEFS;
   9247 
   9248     mac_ts_disable = 0;
   9249 
   9250     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9251     if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, CLMAC_TS_DISABLEf)) {
   9252         _SOC_IF_ERR_EXIT(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   9253         mac_ts_disable = soc_reg_field_get(unit, CLPORT_MAC_CONTROLr, reg_val, CLMAC_TS_DISABLEf);
   9254     }
   9255 
   9256    /*
   9257     * 1 = disable MAC timestamp, use TSC for timestamp.
   9258     * 0 = legacy mode, use MAC for timestamp.
   9259     */
   9260     if (mac_ts_disable) {
   9261         _SOC_IF_ERR_EXIT(_pm4x25_phy_timesync_tx_info_get(unit, port, pm_info, tx_info));
   9262     } else {
   9263         _SOC_IF_ERR_EXIT(clmac_timesync_tx_info_get(unit, port, tx_info));
   9264     }
   9265 
   9266 exit:
   9267     SOC_FUNC_RETURN;
   9268 }
   9269 
   9270 #ifdef FW_BCAST_DOWNLOAD
   9271 STATIC int
   9272 _pm4x25_sbus_control_set(int unit, const phymod_core_access_t* core_acc, int bcast_id, int chain_last)
   9273 {
   9274     portmod_default_user_access_t *user_acc = (portmod_default_user_access_t*)core_acc->access.user_acc;
   9275     int reg_acc_idx = user_acc->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK;
   9276     soc_reg_t sbus_control_reg = CLPORT_SBUS_CONTROLr;
   9277     uint32 reg_val;
   9278 
   9279     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, sbus_control_reg, reg_acc_idx, 0, &reg_val));
   9280     soc_reg_field_set(unit, sbus_control_reg, &reg_val,
   9281                       SBUS_BCAST_BLOCK_IDf, bcast_id);
   9282     soc_reg_field_set(unit, sbus_control_reg, &reg_val,
   9283                       SBUS_CHAIN_LASTf, chain_last);
   9284     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, sbus_control_reg, reg_acc_idx, 0, reg_val));
   9285 
   9286     return SOC_E_NONE;
   9287 }
   9288 
   9289 STATIC int
   9290 _pm4x25_tsc_acc_mode_set(int unit, const phymod_core_access_t* core_acc, int acc_mem)
   9291 {
   9292     portmod_default_user_access_t *user_acc = (portmod_default_user_access_t*)core_acc->access.user_acc;;
   9293     int reg_acc_idx = user_acc->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK;
   9294     soc_reg_t ucmem_ctrl_reg = CLPORT_WC_UCMEM_CTRLr;
   9295     uint64 reg_val;
   9296 
   9297     SOC_IF_ERROR_RETURN(soc_reg_get(unit, ucmem_ctrl_reg, reg_acc_idx, 0, &reg_val));
   9298     soc_reg64_field32_set(unit, ucmem_ctrl_reg, &reg_val, ACCESS_MODEf, acc_mem);
   9299     SOC_IF_ERROR_RETURN(soc_reg_set(unit, ucmem_ctrl_reg, reg_acc_idx, 0, reg_val));
   9300 
   9301     return SOC_E_NONE;
   9302 }
   9303 #endif
   9304 
   9305 int pm4x25_fw_bcast(int unit, pm_info_t pm_info, const portmod_sbus_bcast_config_t* config)
   9306 {
   9307 #ifdef FW_BCAST_DOWNLOAD
   9308     phymod_core_access_t* core_access = &PM_4x25_INFO(pm_info)->int_core_access;
   9309     phymod_core_init_config_t core_conf;
   9310     phymod_core_status_t core_status;
   9311     portmod_default_user_access_t* user_acc;
   9312     int flag = config->flag;
   9313 
   9314     SOC_IF_ERROR_RETURN(phymod_core_init_config_t_init(&core_conf));
   9315     SOC_IF_ERROR_RETURN(phymod_core_status_t_init(&core_status));
   9316 
   9317     core_conf.flags = 0;
   9318     PHYMOD_CORE_INIT_F_SERDES_FW_BCAST_SET(&core_conf);
   9319     if (flag & PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY) {
   9320         PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_SET(&core_conf);
   9321         flag &= ~PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
   9322     }
   9323 
   9324     core_conf.firmware_loader = pm4x25_default_fw_loader;
   9325     core_status.pmd_active = 0;
   9326 
   9327     switch (flag) {
   9328     case PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD:
   9329         PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_SET(&core_conf);
   9330         SOC_IF_ERROR_RETURN(phymod_core_init(core_access, &core_conf, &core_status));
   9331         PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_CLR(&core_conf);
   9332         break;
   9333 
   9334     case PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD:
   9335         PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_SET(&core_conf);
   9336         SOC_IF_ERROR_RETURN(phymod_core_init(core_access, &core_conf, &core_status));
   9337         PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_CLR(&core_conf);
   9338 
   9339         /* program broadcast ID and chain last */
   9340         _pm4x25_sbus_control_set(unit, core_access, config->bcast_id, config->chain_last);
   9341 
   9342         /* access TSC ucode memory */
   9343         _pm4x25_tsc_acc_mode_set(unit, core_access, 1);
   9344         break;
   9345 
   9346     case PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD:
   9347         /*
   9348          * phymod_core_init still need to access register to check whether UC is enabled before download firmware
   9349          * TSC access mode will be changed to memory mode finally in fw_loader that will be called in phymod_core_init
   9350          */
   9351         _pm4x25_tsc_acc_mode_set(unit, core_access, 0);
   9352 
   9353         user_acc = (portmod_default_user_access_t*)core_access->access.user_acc;
   9354         PORTMOD_USER_ACCESS_FW_LOAD_BROADCAST_SET(user_acc);
   9355 
   9356         PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_SET(&core_conf);
   9357         SOC_IF_ERROR_RETURN(phymod_core_init(core_access, &core_conf, &core_status));
   9358         PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_CLR(&core_conf);
   9359 
   9360         PORTMOD_USER_ACCESS_FW_LOAD_BROADCAST_CLR(user_acc);
   9361         break;
   9362 
   9363     case PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD:
   9364         /* access TSC register */
   9365         _pm4x25_tsc_acc_mode_set(unit, core_access, 0);
   9366 
   9367         /* clear broadcast ID and chain last */
   9368         _pm4x25_sbus_control_set(unit, core_access, 0x7f, 0);
   9369 
   9370         PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_SET(&core_conf);
   9371         SOC_IF_ERROR_RETURN(phymod_core_init(core_access, &core_conf, &core_status));
   9372         PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_CLR(&core_conf);
   9373         break;
   9374 
   9375     case PHYMOD_CORE_INIT_F_FW_LOAD_END:
   9376         PHYMOD_CORE_INIT_F_FW_LOAD_END_SET(&core_conf);
   9377         SOC_IF_ERROR_RETURN(phymod_core_init(core_access, &core_conf, &core_status));
   9378         PHYMOD_CORE_INIT_F_FW_LOAD_END_CLR(&core_conf);
   9379         break;
   9380 
   9381     default:
   9382         break;
   9383     }
   9384 
   9385     return SOC_E_NONE;
   9386 #else
   9387     return SOC_E_UNAVAIL;
   9388 #endif
   9389 }
   9390 
   9391 
   9392 STATIC int
   9393 _pm4x25_init_plls_get(int unit, int port, pm_info_t pm_info, portmod_vcos_speed_config_t *speed_config, int size, phymod_dual_plls_t *dual_plls)
   9394 {
   9395     portmod_dual_vcos_t dual_vcos;
   9396 
   9397     portmod_dual_vcos_t_init(unit, &dual_vcos);
   9398     size = 1;
   9399     pm4x25_port_vcos_get(unit, port, pm_info, speed_config, size, &dual_vcos);
   9400 
   9401     if (speed_config->port_type == portmodCpmPrtEthOfMixedMode) {
   9402         /* PLL1 is used for ETH ports */
   9403         dual_plls->pll0_div = 0;
   9404         dual_plls->pll1_div = (dual_vcos.vco_1 == portmodVCO20G)? phymod_TSCF_PLL_DIV132 : phymod_TSCF_PLL_DIV165;
   9405     } else {
   9406         switch (dual_vcos.vco_0) {
   9407             case portmodVCO20G:
   9408                 dual_plls->pll0_div = phymod_TSCF_PLL_DIV132;
   9409                 break;
   9410             case portmodVCO21G:
   9411                 dual_plls->pll0_div = phymod_TSCF_PLL_DIV140;
   9412                 break;
   9413             case portmodVCO27G:
   9414                 dual_plls->pll0_div = phymod_TSCF_PLL_DIV175;
   9415                 break;
   9416             default:
   9417                 dual_plls->pll0_div = phymod_TSCF_PLL_DIV132;
   9418                 break;
   9419        }
   9420        /* PLL1 is always 25G */
   9421        dual_plls->pll1_div = phymod_TSCF_PLL_DIV165;
   9422    }
   9423 
   9424    return SOC_E_NONE;
   9425 }
   9426 
   9427 
   9428 #define VCO_20G      0x1
   9429 #define VCO_21G      0x2
   9430 #define VCO_25G      0x4
   9431 #define VCO_27G      0x8
   9432 #define VCO_20G_25G  0x5
   9433 int
   9434 pm4x25_port_vcos_get(int unit, int port, pm_info_t pm_info, const portmod_vcos_speed_config_t* speed_config_list, int size, portmod_dual_vcos_t* dual_vco)
   9435 {
   9436     int index = 0;
   9437     int vco_bitmap[4] = {0};
   9438     int vco_bmp = 0;
   9439 
   9440     if (size == 0) return SOC_E_NONE;
   9441     for (index = 0; index < size; index++){
   9442         /* Check if eth port is in the quad. If yes, PLL1 vco is either 20G or 25G */
   9443         switch (speed_config_list[index].num_lanes){
   9444             case 1:
   9445                 if(speed_config_list[index].speed == 1000){
   9446                     vco_bitmap[index] = VCO_20G;
   9447                 }else if (speed_config_list[index].speed == 2500){
   9448                     vco_bitmap[index] = VCO_25G;
   9449                 }else if (speed_config_list[index].speed == 5000){
   9450                     vco_bitmap[index] = VCO_20G;
   9451                 }else if (speed_config_list[index].speed == 10000){
   9452                     vco_bitmap[index] = VCO_20G;
   9453                 }else if (speed_config_list[index].speed == 20000){
   9454                     vco_bitmap[index] = VCO_20G;
   9455                 }else if (speed_config_list[index].speed == 25000){
   9456                     vco_bitmap[index] = VCO_25G;
   9457                 }else if (speed_config_list[index].speed == 11000){
   9458                     vco_bitmap[index] = VCO_21G;
   9459                 } else if (speed_config_list[index].speed == 21000){
   9460                     vco_bitmap[index] = VCO_21G;
   9461                 } else if(speed_config_list[index].speed == 27000){
   9462                     vco_bitmap[index] = VCO_27G;
   9463                 }
   9464                 break;
   9465             case 2:
   9466                 if(speed_config_list[index].speed == 20000){
   9467                     vco_bitmap[index] = VCO_20G;
   9468                 }else if (speed_config_list[index].speed == 40000){
   9469                     vco_bitmap[index] = VCO_25G;
   9470                 }else if (speed_config_list[index].speed == 50000){
   9471                     vco_bitmap[index] = VCO_25G;
   9472                 }else if (speed_config_list[index].speed == 21000){
   9473                     vco_bitmap[index] = VCO_21G;
   9474                 } else if (speed_config_list[index].speed == 42000){
   9475                     vco_bitmap[index] = VCO_21G;
   9476                 } else if(speed_config_list[index].speed == 53000){
   9477                     vco_bitmap[index] = VCO_27G;
   9478                 }
   9479                 break;
   9480             case 4:
   9481                 if(speed_config_list[index].speed == 40000){
   9482                     vco_bitmap[index] = VCO_20G;
   9483                 }else if (speed_config_list[index].speed == 50000){
   9484                     vco_bitmap[index] = VCO_25G;
   9485                 }else if (speed_config_list[index].speed == 100000){
   9486                     vco_bitmap[index] = VCO_25G;
   9487                 }else if (speed_config_list[index].speed == 42000){
   9488                     vco_bitmap[index] = VCO_21G;
   9489                 } else if (speed_config_list[index].speed == 53000){
   9490                     vco_bitmap[index] = VCO_27G;
   9491                 } else if(speed_config_list[index].speed == 106000){
   9492                     vco_bitmap[index] = VCO_27G;
   9493                 }
   9494                 break;
   9495             default:
   9496                  LOG_ERROR(BSL_LS_SOC_PORT,
   9497                   (BSL_META_U(unit, "fail to get vcos -- no vco matches lane %d speed %d\n"),
   9498                    speed_config_list[index].num_lanes, speed_config_list[index].speed));
   9499                 return SOC_E_PARAM;
   9500         }
   9501         vco_bmp |= vco_bitmap[index];
   9502     }
   9503     if (speed_config_list->port_type == portmodCpmPrtEthOfMixedMode) {
   9504         switch (vco_bmp){
   9505             case VCO_20G:
   9506                 dual_vco->vco_1 = portmodVCO20G;
   9507             break;
   9508             case VCO_25G:
   9509                 dual_vco->vco_1 = portmodVCO25G;
   9510             break;
   9511             default:
   9512                  LOG_ERROR(BSL_LS_SOC_PORT,
   9513                   (BSL_META_U(unit, "fail to get vcos -- no vcos matches in ETH vco_bmp 0x%x\n"), vco_bmp));
   9514                 return SOC_E_PARAM;
   9515         }
   9516     } else {
   9517         switch (vco_bmp){
   9518             case VCO_20G:
   9519             case VCO_25G:
   9520             case VCO_20G_25G:
   9521                 dual_vco->vco_0 = portmodVCO20G;  /* IEEE */
   9522                 dual_vco->vco_1 = portmodVCO25G;
   9523             break;
   9524             case VCO_21G:
   9525                 dual_vco->vco_0 = portmodVCO21G;  /* HiGig */
   9526                 dual_vco->vco_1 = portmodVCO25G;
   9527                 break;
   9528             case VCO_27G:
   9529                 dual_vco->vco_0 = portmodVCO27G;  /* HiGig */
   9530                 dual_vco->vco_1 = portmodVCO25G;
   9531                 break;
   9532             default:
   9533                  LOG_ERROR(BSL_LS_SOC_PORT,
   9534                   (BSL_META_U(unit, "fail to get vcos -- no vcos combination vco_bmp 0x%x\n"), vco_bmp));
   9535                 return SOC_E_PARAM;
   9536         }
   9537     }
   9538 
   9539     return SOC_E_NONE;
   9540 
   9541 }
   9542 
   9543 STATIC
   9544 int _pm4x25_ext_tsc_clk_set(int unit, int phy_acc, int ext_clk, int pll_vcoclk)
   9545 {
   9546     uint32 reg_val;
   9547     SOC_INIT_FUNC_DEFS;
   9548 
   9549     _SOC_IF_ERR_EXIT(READ_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   9550     soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, EXT_TSC_CLK_ENf, ext_clk? 1 : 0);
   9551     if (!ext_clk){
   9552         soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &reg_val, TSC_CLK_SELf, pll_vcoclk ? 1 : 0);
   9553     }
   9554     _SOC_IF_ERR_EXIT(WRITE_CLPORT_XGXS0_CTRL_REGr(unit, phy_acc, reg_val));
   9555 
   9556 exit:
   9557     SOC_FUNC_RETURN;
   9558 
   9559 }
   9560 
   9561 STATIC
   9562 int _pm4x25_pm_ext_tsc_clk_set(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   9563 {
   9564     int phy_acc;
   9565     int ext_clk = 0;
   9566     int pll_vcoclk = 0;
   9567     portmod_vcos_speed_config_t speed_config;
   9568     phymod_dual_plls_t init_plls;
   9569 
   9570     SOC_INIT_FUNC_DEFS;
   9571     portmod_vcos_speed_config_t_init(unit, &speed_config);
   9572     speed_config.higig_mode = add_info->init_config.is_hg;
   9573     speed_config.speed = add_info->interface_config.speed;
   9574     speed_config.num_lanes = add_info->interface_config.port_num_lanes;
   9575     if (add_info->init_config.cpm_core_mode == portmodCpmMixEthCpri) {
   9576         speed_config.port_type = portmodCpmPrtEthOfMixedMode;
   9577     }
   9578     _pm4x25_init_plls_get(unit, 0 , pm_info, &speed_config, 1, &init_plls);
   9579 
   9580     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9581     if ((add_info->init_config.cpm_core_mode == portmodCpmAllIEEE) || (add_info->init_config.cpm_core_mode == portmodCpmAllHIGIG)
   9582          || (add_info->init_config.cpm_core_mode == portmodCpmMixEthCpri)) {
   9583         ext_clk = 1;
   9584 
   9585     } else if (add_info->init_config.cpm_core_mode == portmodCpmAllCpri) {
   9586         LOG_ERROR(BSL_LS_SOC_PORT,
   9587             (BSL_META_U(unit, " Wrong port _mode from CPM4x25 %d\n"), portmodCpmAllCpri));
   9588     } else {
   9589         if(add_info->init_config.is_hg) {
   9590             ext_clk = 0;
   9591             pll_vcoclk = 0;
   9592             /* Check if port is HIGIG mode with IEEE speed */
   9593             if((init_plls.pll0_div == phymod_TSCF_PLL_DIV132) && (init_plls.pll1_div == phymod_TSCF_PLL_DIV165)) {
   9594                 pll_vcoclk = 1;
   9595             }
   9596         } else {
   9597             ext_clk = 0;
   9598             pll_vcoclk = 1;
   9599         }
   9600 #if 0
   9601         if(add_info->init_config.txpi_mode){
   9602             ext_clk = 1;
   9603         }
   9604 #endif
   9605     }
   9606 
   9607     _SOC_IF_ERR_EXIT
   9608         (_pm4x25_ext_tsc_clk_set(unit, phy_acc, ext_clk, pll_vcoclk));
   9609 
   9610 exit:
   9611 
   9612     SOC_FUNC_RETURN;
   9613 }
   9614 
   9615 int pm4x25_port_mac_timestamp_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   9616 {
   9617     int phy_acc;
   9618     uint32 reg_val;
   9619     pm_version_t pm_version;
   9620 
   9621     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9622     if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, CLMAC_TS_DISABLEf)) {
   9623         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   9624         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &reg_val,
   9625                                 CLMAC_TS_DISABLEf, (enable) ? 0 : 1);
   9626         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   9627     } else {
   9628         return SOC_E_UNAVAIL;
   9629     }
   9630 
   9631     if (!enable) {
   9632         /* Disable XLMAC byte_adjust if MAC timestamp is disabled.
   9633          * Otherwise, it will affect timestamp value of TSC timestamping.
   9634          */
   9635         SOC_IF_ERROR_RETURN(_pm4x25_pm_version_get(unit, pm_info, &pm_version));
   9636         /* PM VERSION and CLMAC BYTE ADJUST aren't valid before TH2 */
   9637         if (!PORTMOD_PM4x25_IS_GEN1(pm_version)) {
   9638             SOC_IF_ERROR_RETURN
   9639                 (clmac_timestamp_byte_adjust_set(unit, port, CLMAC_TIMESTAMP_BYTE_ADJUST_CLEAR, 0));
   9640         }
   9641 
   9642     }
   9643     return (SOC_E_NONE);
   9644 }
   9645 
   9646 int pm4x25_port_mac_timestamp_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   9647 {
   9648     int phy_acc, tmp;
   9649     uint32 reg_val;
   9650 
   9651     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9652     if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, CLMAC_TS_DISABLEf)) {
   9653         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   9654         tmp = soc_reg_field_get(unit, CLPORT_MAC_CONTROLr, reg_val, CLMAC_TS_DISABLEf);
   9655     } else {
   9656         return SOC_E_UNAVAIL;
   9657     }
   9658 
   9659     if (tmp) {
   9660         *enable = FALSE;
   9661     } else {
   9662         *enable = TRUE;
   9663     }
   9664 
   9665     return (SOC_E_NONE);
   9666 }
   9667 
   9668 /*
   9669  *Function:
   9670  *  _pm4x25_txpi_sdm_scheme_set
   9671  *
   9672  *Purpose:
   9673  *  Set Portmacro TXPI DSM scheme type
   9674  *  Default type is portmodTxPiSdmType1StOderWithFloor
   9675  *  This is a core level API
   9676  *  SDM scheme can't be changed if the port is active
   9677 */
   9678 int _pm4x25_txpi_sdm_scheme_set(int unit, int port, pm_info_t pm_info, portmod_txpi_sdm_type_t type)
   9679 {
   9680     int phy_acc;
   9681     uint32 reg_val;
   9682     SOC_INIT_FUNC_DEFS;
   9683 
   9684     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9685 
   9686     _SOC_IF_ERR_EXIT(READ_CLPORT_TXPI_CSR_CTRL1r(unit, phy_acc, &reg_val));
   9687     soc_reg_field_set(unit, CLPORT_TXPI_CSR_CTRL1r, &reg_val, TXPI_CSR_CTRL_SDM_TYPEf, type);
   9688     _SOC_IF_ERR_EXIT(WRITE_CLPORT_TXPI_CSR_CTRL1r(unit, phy_acc, reg_val));
   9689 
   9690 exit:
   9691     SOC_FUNC_RETURN;
   9692 }
   9693 
   9694 /*
   9695  *Function:
   9696  *  pm4x25_txpi_lane_select_set
   9697  *
   9698  *Purpose:
   9699  *  Set Portmacro TXPI lane select
   9700  *  Defaults to using TXPI for it's own lane
   9701  *  This is a core level API
   9702 */
   9703 int _pm4x25_txpi_lane_select_set(int unit, int port, pm_info_t pm_info, uint32_t *lane_select)
   9704 {
   9705     int phy_acc;
   9706     uint32 reg_val = 0;
   9707     SOC_INIT_FUNC_DEFS;
   9708 
   9709     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9710 
   9711     soc_reg_field_set(unit, CLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_0f, lane_select[0]);
   9712     soc_reg_field_set(unit, CLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_1f, lane_select[1]);
   9713     soc_reg_field_set(unit, CLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_2f, lane_select[2]);
   9714     soc_reg_field_set(unit, CLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_3f, lane_select[3]);
   9715     _SOC_IF_ERR_EXIT(WRITE_CLPORT_TXPI_LANE_SELECTIONr(unit, phy_acc, reg_val));
   9716 
   9717 exit:
   9718     SOC_FUNC_RETURN;
   9719 }
   9720 
   9721 /*
   9722  *Function:
   9723  *  _pm4x25_port_phy_txpi_mode_set
   9724  *
   9725  *Purpose:
   9726  *  Set PMD TXPI mode: normal or external PD
   9727  *  This is a port level API
   9728 */
   9729 int _pm4x25_port_phy_txpi_mode_set(int unit, int port, pm_info_t pm_info, uint32 mode)
   9730 {
   9731     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9732     int nof_phys;
   9733     phymod_txpi_config_t config;
   9734     SOC_INIT_FUNC_DEFS;
   9735 
   9736     config.enable = mode ? 1 : 0;
   9737     config.mode   = mode;
   9738 
   9739     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9740                                                        phy_access ,(1+MAX_PHYN),
   9741                                                        &nof_phys));
   9742     SOC_IF_ERROR_RETURN(portmod_port_phychain_txpi_config_set(unit, phy_access, nof_phys, &config));
   9743 
   9744 exit:
   9745     SOC_FUNC_RETURN;
   9746 }
   9747 
   9748 /*
   9749  *Function:
   9750  *  pm4x25_port_txpi_override_set
   9751  *
   9752  *Purpose:
   9753  *  Overwrite Portmacro TXPI SDM value
   9754  *  Defaults to using value from CMIC
   9755  *  This is a port level API
   9756 */
   9757 int pm4x25_port_txpi_override_set (int unit, int port, pm_info_t pm_info, const portmod_txpi_override_t *override)
   9758 {
   9759     int phy_acc;
   9760     uint32 reg_val_en, bitmap;
   9761     int i, first_index;
   9762     int64 reg_value;
   9763 
   9764     soc_field_t field[MAX_PORTS_PER_PM4X25] = {TXPI_CSR_OVER_EN_0f, TXPI_CSR_OVER_EN_1f, TXPI_CSR_OVER_EN_2f, TXPI_CSR_OVER_EN_3f};
   9765     soc_reg_t over_reg_low[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_CSR_OVER_VAL_0_LOWr, CLPORT_TXPI_CSR_OVER_VAL_1_LOWr,
   9766                                                     CLPORT_TXPI_CSR_OVER_VAL_2_LOWr, CLPORT_TXPI_CSR_OVER_VAL_3_LOWr};
   9767     soc_reg_t over_reg_high[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_CSR_OVER_VAL_0_HIGHr, CLPORT_TXPI_CSR_OVER_VAL_1_HIGHr,
   9768                                                     CLPORT_TXPI_CSR_OVER_VAL_2_HIGHr, CLPORT_TXPI_CSR_OVER_VAL_3_HIGHr};
   9769     SOC_INIT_FUNC_DEFS;
   9770 
   9771     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9772     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &first_index, &bitmap));
   9773 
   9774     /* Enable TXPI DSM override */
   9775     _SOC_IF_ERR_EXIT(READ_CLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, &reg_val_en));
   9776     for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
   9777         if (bitmap & (0x1 << i)) {
   9778             soc_reg_field_set(unit, CLPORT_TXPI_CSR_OVER_ENr, &reg_val_en, field[i], override->enable ? TRUE : FALSE);
   9779         }
   9780     }
   9781     _SOC_IF_ERR_EXIT(WRITE_CLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, reg_val_en));
   9782 
   9783     /* Write TXPI DSM override value. Low 32 bits must be wroten before high register
   9784      * reg_value = txpi_dsm_value_1ppm * override->value;
   9785     */
   9786     COMPILER_64_SET(reg_value, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
   9787     COMPILER_64_UMUL_32(reg_value, override->value);
   9788 
   9789     for (i = 0; i < MAX_PORTS_PER_PM4X25; i++) {
   9790         if (bitmap & (0x1 << i)) {
   9791             soc_reg32_set(unit, over_reg_low[i], phy_acc, 0, override->enable ? COMPILER_64_LO(reg_value) : 0);
   9792             soc_reg32_set(unit, over_reg_high[i], phy_acc, 0, override->enable ? (COMPILER_64_HI(reg_value) & 0xffff) : 0);
   9793         }
   9794     }
   9795 
   9796 exit:
   9797     SOC_FUNC_RETURN;
   9798 }
   9799 
   9800 /*
   9801  *Function:
   9802  *  pm4x25_port_txpi_override_get
   9803  *
   9804  *Purpose:
   9805  *  Get Portmacro TXPI SDM override status and value
   9806  *  Defaults to using value from CMIC
   9807  *  This is a port level API
   9808 */
   9809 int pm4x25_port_txpi_override_get (int unit, int port, pm_info_t pm_info, portmod_txpi_override_t *override)
   9810 {
   9811     int phy_acc;
   9812     uint32 reg_val_en, bitmap;
   9813     int first_index;
   9814     uint32 reg_value_lo, reg_value_hi;
   9815     int64 tmp_reg_val64, txpi_dsm_value_1ppm;
   9816 
   9817     soc_field_t field[MAX_PORTS_PER_PM4X25] = {TXPI_CSR_OVER_EN_0f, TXPI_CSR_OVER_EN_1f, TXPI_CSR_OVER_EN_2f, TXPI_CSR_OVER_EN_3f};
   9818     soc_reg_t over_reg_low[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_CSR_OVER_VAL_0_LOWr, CLPORT_TXPI_CSR_OVER_VAL_1_LOWr,
   9819                                                     CLPORT_TXPI_CSR_OVER_VAL_2_LOWr, CLPORT_TXPI_CSR_OVER_VAL_3_LOWr};
   9820     soc_reg_t over_reg_high[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_CSR_OVER_VAL_0_HIGHr, CLPORT_TXPI_CSR_OVER_VAL_1_HIGHr,
   9821                                                     CLPORT_TXPI_CSR_OVER_VAL_2_HIGHr, CLPORT_TXPI_CSR_OVER_VAL_3_HIGHr};
   9822     SOC_INIT_FUNC_DEFS;
   9823 
   9824     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9825      _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &first_index, &bitmap));
   9826 
   9827     /*Get enable status of TXPI DSM override */
   9828     _SOC_IF_ERR_EXIT(READ_CLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, &reg_val_en));
   9829     override->enable = soc_reg_field_get(unit, CLPORT_TXPI_CSR_OVER_ENr, reg_val_en, field[first_index]);
   9830 
   9831     /* Get TXPI DSM override value */
   9832     if (override->enable == TRUE) {
   9833         /*  The LOW register should be read first before reading from the HIGH register. */
   9834         _SOC_IF_ERR_EXIT(soc_reg32_get(unit, over_reg_low[first_index],
   9835                                        phy_acc, 0, &reg_value_lo));
   9836         _SOC_IF_ERR_EXIT(soc_reg32_get(unit, over_reg_high[first_index],
   9837                          phy_acc, 0, &reg_value_hi));
   9838         /*
   9839          * bit47 : 0 -- positive; 1 -- negative.
   9840          * If it is negative, the high 16 bits must be filled with 1.
   9841          */
   9842         reg_value_hi = (reg_value_hi & 0x8000) ? (reg_value_hi | 0xffff0000) : (reg_value_hi & 0xffff);
   9843         /*
   9844          *Use COMPILER_64_XXX macros to put together 64 bit variables txpi_dsm_value_1ppm and tmp_reg_val64
   9845          *and then generate the override->value
   9846          */
   9847         COMPILER_64_SET(txpi_dsm_value_1ppm, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
   9848         COMPILER_64_SET(tmp_reg_val64, reg_value_hi, reg_value_lo);
   9849         COMPILER_64_UDIV_64(tmp_reg_val64, txpi_dsm_value_1ppm);
   9850 
   9851         COMPILER_64_TO_32_LO(override->value, tmp_reg_val64);
   9852     } else {
   9853         override->value = 0;
   9854     }
   9855 
   9856 exit:
   9857     SOC_FUNC_RETURN;
   9858 }
   9859 
   9860 /*
   9861  *Function:
   9862  *  pm4x25_port_txpi_sdm_data_get
   9863  *
   9864  *Purpose:
   9865  *  Get Portmacro TXPI SDM value of resolution
   9866  *  This is a port level API
   9867 */
   9868 int pm4x25_port_txpi_sdm_data_get(int unit, int port, pm_info_t pm_info, int *value)
   9869 
   9870 {
   9871     int phy_acc;
   9872     uint32 bitmap;
   9873     int first_index;
   9874     uint32 reg_value_lo, reg_value_hi;
   9875     int64 tmp_reg_val64, txpi_dsm_value_1ppm;
   9876 
   9877     soc_reg_t data_reg_low[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_DATA_OUT_STS_0_LOWr, CLPORT_TXPI_DATA_OUT_STS_1_LOWr,
   9878                                                     CLPORT_TXPI_DATA_OUT_STS_2_LOWr, CLPORT_TXPI_DATA_OUT_STS_3_LOWr};
   9879     soc_reg_t data_reg_high[MAX_PORTS_PER_PM4X25] = {CLPORT_TXPI_DATA_OUT_STS_0_HIGHr, CLPORT_TXPI_DATA_OUT_STS_1_HIGHr,
   9880                                                     CLPORT_TXPI_DATA_OUT_STS_2_HIGHr, CLPORT_TXPI_DATA_OUT_STS_3_HIGHr};
   9881     SOC_INIT_FUNC_DEFS;
   9882 
   9883     PM4x25_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9884     _SOC_IF_ERR_EXIT(_pm4x25_port_index_get(unit, port, pm_info, &first_index, &bitmap));
   9885 
   9886     /* get the first sub-port if the port is dual-lane or quad-lane mode.
   9887      * The LOW register should be read first before reading from the HIGH register.
   9888      */
   9889     _SOC_IF_ERR_EXIT(soc_reg32_get(unit, data_reg_low[first_index],
   9890                                    phy_acc, 0, &reg_value_lo));
   9891     _SOC_IF_ERR_EXIT(soc_reg32_get(unit, data_reg_high[first_index],
   9892                                    phy_acc, 0, &reg_value_hi));
   9893     /*
   9894      * bit47 : 0 -- positive; 1 -- negative.
   9895      * If it is negative, the high 16 bits must be filled with 1.
   9896      */
   9897     reg_value_hi = (reg_value_hi & 0x8000) ? (reg_value_hi | 0xffff0000) : (reg_value_hi & 0xffff);
   9898 
   9899     /*
   9900      *Use COMPILER_64_XXX macros to put together 64 bit variables txpi_dsm_value_1ppm and tmp_reg_val64
   9901      *and then generate the override->value
   9902      */
   9903     COMPILER_64_SET(txpi_dsm_value_1ppm, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
   9904     COMPILER_64_SET(tmp_reg_val64, reg_value_hi, reg_value_lo);
   9905     COMPILER_64_UDIV_64(tmp_reg_val64, txpi_dsm_value_1ppm);
   9906 
   9907     COMPILER_64_TO_32_LO(*value, tmp_reg_val64);
   9908 exit:
   9909     SOC_FUNC_RETURN;
   9910 }
   9911 
   9912 int pm4x25_port_synce_clk_ctrl_set(int unit, int port, pm_info_t pm_info,
   9913                                    const portmod_port_synce_clk_ctrl_t* cfg)
   9914 {
   9915     phymod_synce_clk_ctrl_t phy_synce_cfg;
   9916     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9917     int nof_phys;
   9918     SOC_INIT_FUNC_DEFS;
   9919 
   9920     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9921                                                        phy_access ,(1+MAX_PHYN),
   9922                                                        &nof_phys));
   9923 
   9924     phymod_synce_clk_ctrl_t_init(&phy_synce_cfg);
   9925     phy_synce_cfg.stg0_mode = cfg->stg0_mode;
   9926     phy_synce_cfg.stg1_mode = cfg->stg1_mode;
   9927     phy_synce_cfg.sdm_val = cfg->sdm_val;
   9928 
   9929     _SOC_IF_ERR_EXIT(phymod_phy_synce_clk_ctrl_set(&phy_access[0],
   9930                                                    phy_synce_cfg));
   9931 
   9932 exit:
   9933     SOC_FUNC_RETURN;
   9934 }
   9935 
   9936 int pm4x25_port_synce_clk_ctrl_get(int unit, int port, pm_info_t pm_info,
   9937                                    portmod_port_synce_clk_ctrl_t* cfg)
   9938 {
   9939     phymod_synce_clk_ctrl_t phy_synce_cfg;
   9940     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9941     int nof_phys;
   9942     SOC_INIT_FUNC_DEFS;
   9943 
   9944     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9945                                                        phy_access ,(1+MAX_PHYN),
   9946                                                        &nof_phys));
   9947 
   9948     phymod_synce_clk_ctrl_t_init(&phy_synce_cfg);
   9949 
   9950     _SOC_IF_ERR_EXIT(phymod_phy_synce_clk_ctrl_get(&phy_access[0],
   9951                                                     &phy_synce_cfg));
   9952 
   9953     cfg->stg0_mode = phy_synce_cfg.stg0_mode;
   9954     cfg->stg1_mode = phy_synce_cfg.stg1_mode;
   9955     cfg->sdm_val = phy_synce_cfg.sdm_val;
   9956 
   9957 exit:
   9958     SOC_FUNC_RETURN;
   9959 }
   9960 
   9961 #endif /* PORTMOD_PM4X25_SUPPORT */
   9962 
   9963 #undef _ERR_MSG_MODULE_NAME