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

pm4x10.c (438159B)


      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_common.h>
     17 #include <soc/portmod/portmod_dispatch.h>
     18 #include <soc/portmod/portmod_chain.h>
     19 #include <soc/portmod/portmod_legacy_phy.h>
     20 #include <soc/portmod/portmod_system.h>
     21 
     22 
     23 #include <soc/portmod/xlmac.h>
     24 #include <soc/portmod/pm4x10.h>
     25 #include <soc/portmod/pm12x10_internal.h>
     26 #include <soc/portmod/pm12x10_xgs_internal.h>
     27 
     28 #ifdef _ERR_MSG_MODULE_NAME 
     29 #error "_ERR_MSG_MODULE_NAME redefined" 
     30 #endif
     31 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     32 
     33 #ifdef PORTMOD_PM4X10_SUPPORT
     34 
     35 #if 0
     36 #define PORTMOD_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \
     37     do{\
     38         PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\
     39         (_phy_access)->type = (_core_access)->type; \
     40     }while(0)
     41 #endif
     42 
     43 /* 10G mode at 10.3125G and 1G mode at 1.25G */
     44 #define PM4X10_LANES_PER_CORE (4)
     45 #define MAX_PORTS_PER_PM4X10 (4)
     46 
     47 #define TXPI_DSM_VALUE_1PPM_HI (uint32) 0x29   /* 1ppm value is 1.80144E+11 (0x29F16B11C7) in register */
     48 #define TXPI_DSM_VALUE_1PPM_LO (uint32) 0xF16B11C7
     49 
     50 #define PM_4x10_INFO(pm_info) ((pm_info)->pm_data.pm4x10_db)
     51 
     52 #define PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc) \
     53     do { \
     54         uint32 is_bypass; \
     55         uint8 in_pm12x10 = PM_4x10_INFO(pm_info)->in_pm12x10; \
     56         phy_acc = 0; \
     57         SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &is_bypass); \
     58         phy_acc = (is_bypass && !in_pm12x10 && PM_4x10_INFO(pm_info)->first_phy != -1) ? (PM_4x10_INFO(pm_info)->first_phy | SOC_REG_ADDR_PHY_ACC_MASK) : port; \
     59     } while (0)
     60 
     61 #define PM4x10_WB_BUFFER_VERSION        (10)
     62 
     63 #define PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info, dynamic_state, \
     64                                       port_index)                   \
     65     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
     66                           pm_info->wb_vars_ids[portDynamicState],   \
     67                           &dynamic_state, port_index)
     68 #define PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info, dynamic_state, \
     69                                       port_index)                   \
     70     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,              \
     71                           pm_info->wb_vars_ids[portDynamicState],   \
     72                           dynamic_state, port_index)
     73 #define PM4x10_SPEED_SET(unit, pm_info, speed, port_index)     \
     74     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,         \
     75                           pm_info->wb_vars_ids[dataRate],      \
     76                           &speed, port_index)
     77 #define PM4x10_SPEED_GET(unit, pm_info, speed, port_index)     \
     78     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,         \
     79                           pm_info->wb_vars_ids[dataRate],      \
     80                           speed, port_index)
     81 #define PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index) \
     82     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,             \
     83                           pm_info->wb_vars_ids[maxSpeed],          \
     84                           &max_speed, port_index)
     85 #define PM4x10_MAX_SPEED_GET(unit, pm_info, max_speed, port_index) \
     86     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,             \
     87                           pm_info->wb_vars_ids[maxSpeed],          \
     88                           max_speed, port_index)
     89 #define PM4x10_INTERFACE_TYPE_SET(unit, pm_info, interface_type, port_index) \
     90     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
     91                           pm_info->wb_vars_ids[interfaceType],               \
     92                           &interface_type, port_index)
     93 #define PM4x10_INTERFACE_TYPE_GET(unit, pm_info, interface_type, port_index) \
     94     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
     95                           pm_info->wb_vars_ids[interfaceType],               \
     96                           interface_type, port_index)
     97 #define PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface_type, port_index) \
     98     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                                   \
     99                           pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy],          \
    100                           &interface_type, port_index)
    101 #define PM4x10_OUTMOST_PHY_INTERFACE_TYPE_GET(unit, pm_info, interface_type, port_index) \
    102     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                                   \
    103                           pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy],          \
    104                           interface_type, port_index)
    105 #define PM4x10_SERDES_INTERFACE_TYPE_SET(unit, pm_info, serdes_interface,    \
    106                                          port_index)                         \
    107     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    108                           pm_info->wb_vars_ids[serdesInterfaceType],         \
    109                           &serdes_interface, port_index)
    110 #define PM4x10_SERDES_INTERFACE_TYPE_GET(unit, pm_info, serdes_interface,    \
    111                                          port_index)                         \
    112     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    113                           pm_info->wb_vars_ids[serdesInterfaceType],         \
    114                           serdes_interface, port_index)
    115 #define PM4x10_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index) \
    116     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                         \
    117                           pm_info->wb_vars_ids[interfaceModes],                \
    118                           &interface_modes, port_index)
    119 #define PM4x10_INTERFACE_MODES_GET(unit, pm_info, interface_modes, port_index) \
    120     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                         \
    121                           pm_info->wb_vars_ids[interfaceModes],                \
    122                           interface_modes, port_index)
    123 #define PM4x10_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore, \
    124                                         port_index)                          \
    125     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    126                           pm_info->wb_vars_ids[isInterfaceRestore],          \
    127                           &is_interface_restore, port_index)
    128 #define PM4x10_IS_INTERFACE_RESTORE_GET(unit, pm_info, is_interface_restore, \
    129                                         port_index)                          \
    130     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    131                           pm_info->wb_vars_ids[isInterfaceRestore],          \
    132                           is_interface_restore, port_index)
    133 #define PM4x10_IS_HG_SET(unit, pm_info, is_hg, port_index)                \
    134     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                    \
    135                           pm_info->wb_vars_ids[isHg], &is_hg, port_index)
    136 #define PM4x10_IS_HG_GET(unit, pm_info, is_hg, port_index)                \
    137     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                    \
    138                           pm_info->wb_vars_ids[isHg], is_hg, port_index)
    139 #define PM4x10_AN_MODE_SET(unit, pm_info, an_mode, port_index)               \
    140     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    141                           pm_info->wb_vars_ids[anMode], &an_mode, port_index)
    142 #define PM4x10_AN_MODE_GET(unit, pm_info, an_mode, port_index)               \
    143     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    144                           pm_info->wb_vars_ids[anMode], an_mode, port_index)
    145 #define PM4x10_FS_CL72_SET(unit, pm_info, fs_cl72, port_index)               \
    146     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    147                           pm_info->wb_vars_ids[fsCl72], &fs_cl72, port_index)
    148 #define PM4x10_FS_CL72_GET(unit, pm_info, fs_cl72, port_index)               \
    149     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    150                           pm_info->wb_vars_ids[fsCl72], fs_cl72, port_index)
    151 #define PM4x10_CX4_10G_SET(unit, pm_info, cx4_10G, port_index)              \
    152     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    153                        pm_info->wb_vars_ids[cx4In10G], &cx4_10G, port_index)
    154 #define PM4x10_CX4_10G_GET(unit, pm_info, cx4_10G, port_index)              \
    155     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    156                        pm_info->wb_vars_ids[cx4In10G], cx4_10G, port_index)
    157 #define PM4x10_AN_CL72_SET(unit, pm_info, an_cl72, port_index)              \
    158     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    159                           pm_info->wb_vars_ids[anCl72], &an_cl72, port_index)
    160 #define PM4x10_AN_CL72_GET(unit, pm_info, an_cl72, port_index)              \
    161     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    162                           pm_info->wb_vars_ids[anCl72], an_cl72, port_index)
    163 #define PM4x10_AN_FEC_SET(unit, pm_info, an_fec, port_index)                \
    164     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    165                           pm_info->wb_vars_ids[anFec], &an_fec, port_index)
    166 #define PM4x10_AN_FEC_GET(unit, pm_info, an_fec, port_index)                \
    167     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    168                           pm_info->wb_vars_ids[anFec], an_fec, port_index)
    169 #define PM4x10_AN_CL37_SET(unit, pm_info, an_cl37, port_index)              \
    170     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    171                           pm_info->wb_vars_ids[anCl37], &an_cl37, port_index)
    172 #define PM4x10_AN_CL37_GET(unit, pm_info, an_cl37, port_index)              \
    173     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                      \
    174                           pm_info->wb_vars_ids[anCl37], an_cl37, port_index)
    175 #define PM4x10_AN_MASTER_LANE_SET(unit, pm_info, an_master_lane, port_index) \
    176     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    177                           pm_info->wb_vars_ids[anMasterLane],                \
    178                           &an_master_lane, port_index)
    179 #define PM4x10_AN_MASTER_LANE_GET(unit, pm_info, an_master_lane, port_index) \
    180     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    181                           pm_info->wb_vars_ids[anMasterLane],                \
    182                           an_master_lane, port_index)
    183 #define PM4x10_CL37_SGMII_CNT_SET(unit, pm_info, cl37_sgmii_cnt, port_index)  \
    184     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                        \
    185                           pm_info->wb_vars_ids[cl37SgmiiCnt], &cl37_sgmii_cnt,\
    186                           port_index)
    187 #define PM4x10_CL37_SGMII_CNT_GET(unit, pm_info, cl37_sgmii_cnt, port_index)  \
    188     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                        \
    189                           pm_info->wb_vars_ids[cl37SgmiiCnt], cl37_sgmii_cnt, \
    190                           port_index)
    191 #define PM4x10_CL37_SGMII_RESTART_CNT_SET(unit, pm_info,                     \
    192                                           cl37_sgmii_restart_cnt, port_index)\
    193     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    194                           pm_info->wb_vars_ids[cl37SgmiiRestartCnt],         \
    195                           &cl37_sgmii_restart_cnt, port_index)
    196 #define PM4x10_CL37_SGMII_RESTART_CNT_GET(unit, pm_info,                     \
    197                                           cl37_sgmii_restart_cnt, port_index)\
    198     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    199                           pm_info->wb_vars_ids[cl37SgmiiRestartCnt],         \
    200                           cl37_sgmii_restart_cnt, port_index)
    201 #define PM4x10_PORT_OP_MODE_SET(unit, pm_info, port_op_mode, port_index)     \
    202     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    203                           pm_info->wb_vars_ids[portOpMode],                  \
    204                           &port_op_mode, port_index)
    205 #define PM4x10_PORT_OP_MODE_GET(unit, pm_info, port_op_mode, port_index)     \
    206     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    207                           pm_info->wb_vars_ids[portOpMode],                  \
    208                           port_op_mode, port_index)
    209 #define PM4x10_RXAUI_MODE_SET(unit, pm_info, rxaui_mode, port_index)    \
    210     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                  \
    211                           pm_info->wb_vars_ids[rxauiMode],              \
    212                           &rxaui_mode, port_index)
    213 #define PM4x10_RXAUI_MODE_GET(unit, pm_info, rxaui_mode, port_index)    \
    214     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                  \
    215                           pm_info->wb_vars_ids[rxauiMode],              \
    216                           rxaui_mode, port_index)
    217 
    218 #define PM4x10_TX_PARAMS_USER_FLAG_SET(unit, pm_info,                        \
    219                                        tx_params_user_flag, port_index)      \
    220     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    221                           pm_info->wb_vars_ids[txParamsUserFlag],            \
    222                           &tx_params_user_flag, port_index)
    223 #define PM4x10_TX_PARAMS_USER_FLAG_GET(unit, pm_info,                        \
    224                                        tx_params_user_flag, port_index)      \
    225     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    226                           pm_info->wb_vars_ids[txParamsUserFlag],            \
    227                           tx_params_user_flag, port_index)
    228 
    229 #define PM4x10_EXT_PHY_TX_PARAMS_USER_FLAG_SET(unit, pm_info,                \
    230                                    ext_phy_tx_params_user_flag, port_index)  \
    231     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    232                           pm_info->wb_vars_ids[extPhyTxParamsUserFlag],      \
    233                           &ext_phy_tx_params_user_flag, port_index)
    234 #define PM4x10_EXT_PHY_TX_PARAMS_USER_FLAG_GET(unit, pm_info,                \
    235                                    ext_phy_tx_params_user_flag, port_index)  \
    236     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                       \
    237                           pm_info->wb_vars_ids[extPhyTxParamsUserFlag],      \
    238                           ext_phy_tx_params_user_flag, port_index)
    239 
    240 #define PM4x10_PORT_FALLBACK_LANE_SET(unit, pm_info, fallback_lane, port_index)\
    241     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                         \
    242                           pm_info->wb_vars_ids[fallbackLane],                  \
    243                           &fallback_lane, port_index)
    244 #define PM4x10_PORT_FALLBACK_LANE_GET(unit, pm_info, fallback_lane, port_index)\
    245     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                         \
    246                           pm_info->wb_vars_ids[fallbackLane],                  \
    247                           fallback_lane, port_index)
    248 
    249 #define PM4x10_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, lane_connection_db, xphy_idx, lane) \
    250     SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[laneConnectionDb], \
    251         (uint8 *)lane_connection_db, lane, xphy_idx)
    252 #define PM4x10_PORT_LANE_CONNECTION_DB_GET(unit, pm_info, lane_connection_db, xphy_idx, lane) \
    253     SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[laneConnectionDb], \
    254         (uint8 *)lane_connection_db, lane, xphy_idx)
    255 
    256 #define PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, nof_phys, lane)   \
    257         SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[nofPhys], nof_phys, lane)
    258 #define PM4x10_PORT_NUM_PHYS_GET(unit, pm_info, nof_phys, lane)   \
    259         SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[nofPhys], nof_phys, lane)
    260 
    261 #define PM4x10_PORT_PLL_DIVIDER_REQ_SET(unit, pm_info,                \
    262                                         pll_divider_req,              \
    263                                         port_index)                   \
    264     SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    265                           pm_info->wb_vars_ids[pllDividerReq],        \
    266                           &pll_divider_req, port_index)
    267 #define PM4x10_PORT_PLL_DIVIDER_REQ_GET(unit, pm_info,                \
    268                                         pll_divider_req,              \
    269                                         port_index)                   \
    270     SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,                \
    271                           pm_info->wb_vars_ids[pllDividerReq],        \
    272                           pll_divider_req, port_index)
    273 
    274 #define PM4x10_PORT_TIME_STAMP_ADJUST_OLD_SET(unit, pm_info,          \
    275                                         port_ts_adjust,               \
    276                                         adjust_index,                 \
    277                                         port_index)                   \
    278     SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,            \
    279                           pm_info->wb_vars_ids[tsAdjustOld],          \
    280                           (uint8 *)port_ts_adjust, adjust_index,      \
    281                           port_index)
    282 
    283 #define PM4x10_PORT_TIME_STAMP_ADJUST_OLD_GET(unit, pm_info,           \
    284                                         port_ts_adjust,                \
    285                                         adjust_index,                  \
    286                                         port_index)                    \
    287     SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,             \
    288                           pm_info->wb_vars_ids[tsAdjustOld],           \
    289                          (uint8 *)port_ts_adjust, adjust_index,        \
    290                           port_index)
    291 
    292 #define PM4x10_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info,              \
    293                                         port_ts_adjust,               \
    294                                         adjust_index,                 \
    295                                         port_index)                   \
    296     SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,            \
    297                           pm_info->wb_vars_ids[tsAdjust],             \
    298                           (uint8 *)port_ts_adjust, adjust_index,      \
    299                           port_index)
    300 
    301 #define PM4x10_PORT_TIME_STAMP_ADJUST_GET(unit, pm_info,              \
    302                                         port_ts_adjust,               \
    303                                         adjust_index,                 \
    304                                         port_index)                   \
    305     SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD,            \
    306                           pm_info->wb_vars_ids[tsAdjust],             \
    307                          (uint8 *)port_ts_adjust, adjust_index,       \
    308                           port_index)
    309 
    310 /* Warm Boot Variables to indicate the boot state */
    311 typedef enum pm4x10_fabric_wb_vars{
    312     isInitialized,
    313     ports,
    314     isActive,
    315     isBypassed,
    316     threePortsMode,
    317     phy_type,
    318     interfaceConfig,
    319     portInitConfig,
    320     phyInitConfig,
    321     phyInterfaceConfig,
    322     portDynamicState,
    323     nofPhys, /* number of phys for the port */
    324     laneConnectionDb, /* represents the physical topology of the  serdes and ext phy lanes */
    325     dataRate,/* port speed - phy_intf_config.data_rate */
    326     maxSpeed, /* Max Port Speed Supported */
    327     /* interface type -  portmod_port_interface_config_t.interface */
    328     interfaceType, /* interface of type soc_port_if_t */
    329     /* serdes interface -  portmod_port_interface_config_t.serdes_interface */
    330     serdesInterfaceType,
    331     interfaceModes, /* see PHYMOD_INTF_MODES_ */
    332     isInterfaceRestore, /*indicate whether interface should be restored from DB (otherwise retrieved from HW), replace PHYMOD_INTF_F_INTF_PARAM_SET_ONLY*/
    333     isHg, /* specify wheather the port is higig port */
    334     anMode, /* spn_PHY_AN_MODE - Specify the AN mode */
    335     fsCl72, /* spn_FORCED_INIT_CL72 - if trainig should be enabled in Forced speed mode */
    336     cx4In10G, /* see PHYMOD_BAM_CL37_CAP_10G_CX4 */
    337     anCl72, /* spn_PHY_AN_C72 - Specify if the link training should be enabled */
    338     anFec, /* spn_FORCED_INIT_FEC specify if FEC should be enabled in AN mode */
    339     anCl37, /**< AN CL37 */
    340     anMasterLane, /* spn_PHY_AUTONEG_MASTER_LANE - Specify the AN master lane */
    341     cl37SgmiiCnt, /* store cl37 sgmii count */
    342     cl37SgmiiRestartCnt, /* spn_SERDES_CL37_SGMII_RESTART_COUNT - cl37_sgmii_cnt threshold*/
    343     portOpMode, /* spn_PHY_PCS_REPEATER - phy operation Mode */
    344     rxauiMode,  /* portmod_port_init_config_t.rxaui_mode */
    345     /* tx params flag - phy_init_config_t.tx_params_user_flag */
    346     txParamsUserFlag,
    347     /* tx params flag - phy_init_config_t.tx */
    348     txParams,
    349     /* ext tx params flag - phy_init_config_t.ext_phy_tx_params_user_flag */
    350     extPhyTxParamsUserFlag,
    351     /* ext tx params - phy_init_config_t.ext_phy_tx */
    352     extPhyTxParams,
    353     /* port fallback lane - portmod_port_init_config_t.port_fallback_lane */
    354     fallbackLane,
    355     /* pll_divider_req setting on the port */
    356     pllDividerReq,
    357     /* the interface type written into the outmost PHY */
    358     interfaceWrittenIntoOutmostPhy,
    359     /* the time stamp adjust setting on MAC ** removed ** */
    360     tsAdjustOld,
    361     /* the time stamp adjust setting on MAC */
    362     tsAdjust
    363 }pm4x10_wb_vars_t;
    364 
    365 struct pm4x10_s{
    366     portmod_pbmp_t phys;
    367     int first_phy;
    368     phymod_ref_clk_t ref_clk;
    369     phymod_polarity_t polarity;
    370     phymod_lane_map_t lane_map;
    371     phymod_firmware_load_method_t fw_load_method;
    372     phymod_firmware_loader_f external_fw_loader;
    373     phymod_core_access_t int_core_access ; /* for internal SerDes only */
    374     int nof_phys[PM4X10_LANES_PER_CORE]; /* internal + External Phys for each lane*/
    375     uint8 in_pm12x10;
    376     uint8 default_fw_loader_is_used;
    377     uint8 default_bus_is_used;
    378     portmod_phy_external_reset_f  portmod_phy_external_reset;
    379     portmod_mac_soft_reset_f portmod_mac_soft_reset;
    380     int core_num;
    381     int core_num_int;  /* 0, 1, 2 for TSC12 */
    382     portmod_xphy_lane_connection_t lane_conn[MAX_PHYN][PM4X10_LANES_PER_CORE];
    383     int warmboot_skip_db_restore;
    384     int rescal;
    385     int is_pm4x10q;
    386     portmod_port_mode_aux_info_t port_mode_aux_info;
    387     portmod_link_recovery_t link_recovery;
    388 };
    389 
    390 #define PM4x10_QUAD_MODE_IF(interface) \
    391     (interface == SOC_PORT_IF_CAUI  || \
    392      interface == SOC_PORT_IF_XLAUI || \
    393      interface == SOC_PORT_IF_CR4   || \
    394      interface == SOC_PORT_IF_SR4   || \
    395      interface == SOC_PORT_IF_KR4   || \
    396      interface == SOC_PORT_IF_XGMII || \
    397      interface == SOC_PORT_IF_DNX_XAUI)
    398 
    399 #define PM4x10_DUAL_MODE_IF(interface) \
    400     (interface == SOC_PORT_IF_RXAUI || \
    401      interface == SOC_PORT_IF_SR2   || \
    402      interface == SOC_PORT_IF_KR2   || \
    403      interface == SOC_PORT_IF_CR2)
    404 
    405 /* Legacy phymod_tx_t structure format  */
    406 typedef struct pm4x10_phymod_tx_s {
    407     int8_t pre;
    408     int8_t main;
    409     int8_t post;
    410     int8_t post2;
    411     int8_t post3;
    412     int8_t amp;
    413     int8_t drivermode;
    414 } pm4x10_phymod_tx_t;
    415 
    416 #define PORTMOD_PM4x10_IS_GEN1(pm_version)             ((pm_version.type == PM_TYPE_PM4X10) && (pm_version.gen == PM_GEN1))
    417 #define PORTMOD_PM4x10_IS_GEN2_16nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X10) && (pm_version.gen == PM_GEN2) && (pm_version.tech_process == PM_TECH_16NM))
    418 #define PORTMOD_PM4x10_IS_GEN2_28nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X10) && (pm_version.gen == PM_GEN2) && (pm_version.tech_process == PM_TECH_28NM))
    419 #define PORTMOD_PM4x10_IS_GEN3_16nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X10) && (pm_version.gen == PM_GEN3) && (pm_version.tech_process == PM_TECH_16NM))
    420 #define PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)        ((pm_version.type == PM_TYPE_PM4X10) && (pm_version.gen == PM_GEN3) && (pm_version.tech_process == PM_TECH_28NM))
    421 #define PORTMOD_PM4x10_IS_REVISION_A0(pm_version)      ((pm_version.revision_letter == PM_REVISION_A) && (pm_version.revision_number == PM_REVISION_0))
    422 /* Add other revision check here */
    423 
    424 STATIC
    425 int pm4x10_port_soft_reset(int unit, int port, pm_info_t pm_info, int enable);
    426 
    427 STATIC
    428 int _pm4x10_txpi_lane_select_set(int unit, int port, pm_info_t pm_info, uint32_t *lane_select);
    429 
    430 STATIC
    431 int _pm4x10_port_phy_txpi_mode_set(int unit, int port, pm_info_t pm_info, uint32 mode);
    432 
    433 STATIC
    434 int _pm4x10_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);
    435 
    436 STATIC
    437 int _pm4x10_pm_version_get(int unit, pm_info_t pm_info, pm_version_t *version)
    438 {
    439     uint32 raddr, reg_val, pm_type;
    440     int phy_port, block;
    441     uint8 access_type;
    442 
    443     SOC_INIT_FUNC_DEFS;
    444 
    445     version->type            = PM_TYPE_INVALID;
    446     version->gen             = PM_GEN_INVALID;
    447     version->tech_process    = PM_TECH_INVALID;
    448     version->revision_number = PM_REVISION_NUM_INVALID;
    449     version->revision_letter = PM_REVISION_LETTER_INVALID;
    450 
    451     /*
    452      * PM version ID register is not defined in PM GEN1.
    453      * PM12x10 only has gen1 now. To be fixed if support PM12X10 gen2.
    454      */
    455     if (SOC_REG_IS_VALID(unit, XLPORT_PM_VERSION_IDr) &&
    456         (!PM_4x10_INFO(pm_info)->in_pm12x10)) {
    457 
    458         /* Get the first physical port of the pm core */
    459         PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy_port) {
    460             break;
    461         }
    462 
    463         raddr = soc_reg_addr_get(unit, XLPORT_PM_VERSION_IDr, phy_port, 0,
    464                              SOC_REG_ADDR_OPTION_PRESERVE_PORT, &block, &access_type);
    465         _SOC_IF_ERR_EXIT(_soc_reg32_get(unit, block, access_type, raddr, &reg_val));
    466 
    467         pm_type = soc_reg_field_get(unit, XLPORT_PM_VERSION_IDr, reg_val, PM_TYPEf);
    468         if (pm_type == 0) {
    469             version->type = PM_TYPE_PM4X10;
    470             version->gen  = PM_GEN2;
    471         } else if (pm_type == 5){
    472             version->type = PM_TYPE_PM4X10;
    473             version->gen  = PM_GEN3;
    474         }
    475         /* The hardware value of techology/revision starts from 0 */
    476         version->tech_process    = soc_reg_field_get(unit, XLPORT_PM_VERSION_IDr, reg_val, TECH_PROCESSf) +1;
    477         version->revision_number = soc_reg_field_get(unit, XLPORT_PM_VERSION_IDr, reg_val, REV_NUMBERf) + 1;
    478         version->revision_letter = soc_reg_field_get(unit, XLPORT_PM_VERSION_IDr, reg_val, REV_LETTERf) + 1;
    479     } else {
    480         version->type = PM_TYPE_PM4X10;
    481         version->gen  = PM_GEN1;
    482     }
    483 
    484 exit:
    485     SOC_FUNC_RETURN;
    486 }
    487 
    488 
    489 /*
    490  *  Check the PM is a master PLL or not
    491  *  For GEN1/GEN2, only need to check one PLL
    492  *  For GEN3, need to check PLL0 and PLL1
    493  */
    494 STATIC
    495 int _pm4x10_port_tsc_is_master_pll(int unit, int port, pm_info_t pm_info)
    496 {
    497    int phy_acc;
    498    uint32 reg_val;
    499    uint32 refclk_out_en_0 = 0, refclk_out_en_1 = 0;
    500    pm_version_t pm_version;
    501    SOC_INIT_FUNC_DEFS;
    502 
    503    PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
    504 
    505    _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
    506    if (PORTMOD_PM4x10_IS_GEN2_28nm(pm_version)) {
    507         /* This function is Valid only for G2 28nm EAGLEPLL, don't care for 16nm */
    508         _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
    509         refclk_out_en_0 = soc_reg_field_get(unit, XLPORT_XGXS0_CTRL_REGr, reg_val, REFOUT_ENf);
    510     } else if (PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
    511         /* Valid only for G3 28nm EAGLE2PLL, don't care for 16nm */
    512         _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
    513         refclk_out_en_0 = soc_reg_field_get(unit, XLPORT_XGXS0_CTRL_REGr, reg_val, PLL0_REFOUT_ENf);
    514         refclk_out_en_1 = soc_reg_field_get(unit, XLPORT_XGXS0_CTRL_REGr, reg_val, PLL1_REFOUT_ENf);
    515     } else {
    516         refclk_out_en_0 = 0;
    517         refclk_out_en_1 = 0;
    518     }
    519 
    520    if (refclk_out_en_0 || refclk_out_en_1) {
    521        return TRUE;
    522    }
    523 
    524    return FALSE;
    525 
    526 exit:
    527     SOC_FUNC_RETURN;
    528 }
    529 
    530 int pm4x10_pm_interface_type_is_supported(int unit, soc_port_if_t interface, 
    531                                           int* is_supported)
    532 {
    533     SOC_INIT_FUNC_DEFS;
    534     switch(interface){
    535         case SOC_PORT_IF_SGMII:
    536         case SOC_PORT_IF_GMII:
    537         case SOC_PORT_IF_KX:
    538         case SOC_PORT_IF_KR:
    539         case SOC_PORT_IF_DNX_XAUI:
    540         case SOC_PORT_IF_XLAUI:
    541         case SOC_PORT_IF_RXAUI:
    542         case SOC_PORT_IF_KR2:
    543         case SOC_PORT_IF_CR2:
    544         case SOC_PORT_IF_XFI:
    545         case SOC_PORT_IF_SFI:
    546         case SOC_PORT_IF_SR4:
    547         case SOC_PORT_IF_CR4:
    548         case SOC_PORT_IF_KR4:
    549         case SOC_PORT_IF_ER4:
    550         case SOC_PORT_IF_XGMII:
    551             *is_supported = TRUE;
    552             break;
    553 
    554         /* these modes pm4x10 should be bypass */
    555         case SOC_PORT_IF_QSGMII:
    556         case SOC_PORT_IF_CAUI:
    557             *is_supported = TRUE;
    558             break;
    559         default:
    560             *is_supported = FALSE;
    561             break;
    562     }
    563     SOC_FUNC_RETURN;
    564 }
    565 
    566 STATIC
    567 int _pm4x10_port_index_get(int unit, int port, pm_info_t pm_info,
    568                            int *first_index, uint32 *bitmap)
    569 {
    570    int i, rv = 0, tmp_port = 0;
    571 
    572    SOC_INIT_FUNC_DEFS;
    573 
    574    *first_index = -1;
    575    *bitmap = 0;
    576 
    577    for( i = 0 ; i < MAX_PORTS_PER_PM4X10; i++) {
    578        rv = SOC_WB_ENGINE_GET_ARR (unit, SOC_WB_ENGINE_PORTMOD, 
    579                      pm_info->wb_vars_ids[ports], &tmp_port, i);
    580        _SOC_IF_ERR_EXIT(rv);
    581 
    582        if(tmp_port == port){
    583            *first_index = (*first_index == -1 ? i : *first_index);
    584            SHR_BITSET(bitmap, i);
    585        }
    586    }
    587 
    588    if(*first_index == -1) {
    589        _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
    590               (_SOC_MSG("port was not found in internal DB %d"), port));
    591    }
    592 
    593 exit:
    594     SOC_FUNC_RETURN;
    595 }
    596 
    597 /*
    598  * Function:
    599  *      portmod_pm4x10_wb_upgrade_func
    600  * Purpose:
    601  *      This function will take care of the warmboot variable manipulation
    602  *      in case of upgrade case, when variable definition got change or
    603  *      unspoorted varaible from previous version.
    604  * Parameters:
    605  *      unit                -(IN) Device unit number .
    606  *      arg                 -(IN) Generic pointer for a specific module to be used.
    607  *      recovered_version   -(IN) Warmboot version of the existing data.
    608  *      new_version         -(IN) Warmboot version of new data.
    609  * Returns:
    610  *      Status
    611  */
    612 
    613 int portmod_pm4x10_wb_upgrade_func(int unit, void *arg, int recovered_version, int new_version)
    614 {
    615     pm_info_t pm_info;
    616     int i;
    617     int nof_phys, adjust_index;
    618     portmod_port_ts_adjust_t port_ts_adjust;
    619     soc_port_if_t interface;
    620     SOC_INIT_FUNC_DEFS;
    621 
    622     pm_info = arg;
    623 
    624     /*
    625      * skip the warmboot db restore, it is  only needed for
    626      * certain upgrade which will be updated below.
    627      */
    628     PM_4x10_INFO(pm_info)->warmboot_skip_db_restore  = TRUE;
    629 
    630     if ((recovered_version <= 4) &&
    631         (new_version >= 5)) {
    632 
    633         /*
    634          * Need to do db restore.
    635          */
    636         PM_4x10_INFO(pm_info)->warmboot_skip_db_restore  = FALSE;
    637     }
    638 
    639     if ((recovered_version <= 3) &&
    640         (new_version >= 4)) {
    641 
    642         /*
    643          * in version 3 or earlier, nof_phys was not populated properly.
    644          * It need to initialize to 1  to count for internal phy. 1 may not
    645          * be proper value as some port may have ext phy.
    646          */
    647         nof_phys = 1;
    648         for(i = 0 ; i < PM4X10_LANES_PER_CORE ; i++){
    649             _SOC_IF_ERR_EXIT(PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, &nof_phys, i));
    650             PM_4x10_INFO(pm_info)->nof_phys[i] = nof_phys;
    651         }
    652     }
    653 
    654     if ((recovered_version <= 6) &&
    655         (new_version >= 7)) {
    656         /* interface_written_into_outmost_phy does not exist in version 6 or earlier */
    657         interface = SOC_PORT_IF_COUNT;
    658         for (i = 0 ; i < MAX_PORTS_PER_PM4X10 ; i++) {
    659             _SOC_IF_ERR_EXIT(
    660                 PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, i));
    661         }
    662     }
    663 
    664     if ((recovered_version <= 7) &&
    665         (new_version >= 8)) {
    666         sal_memset(&port_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
    667         for (i = 0; i < MAX_PORTS_PER_PM4X10; i++) {
    668              for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM_OLD; adjust_index++) {
    669                   _SOC_IF_ERR_EXIT(
    670                       PM4x10_PORT_TIME_STAMP_ADJUST_OLD_SET(unit, pm_info, &port_ts_adjust, adjust_index, i));
    671              }
    672         }
    673     }
    674 
    675     if ((recovered_version <= 9) &&
    676         (new_version >= 10)) {
    677         for (i = 0; i < MAX_PORTS_PER_PM4X10; i++) {
    678             /* Copy existing timestamp adjust configs from old WB variable. */
    679             for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM_OLD; adjust_index++) {
    680                 _SOC_IF_ERR_EXIT(
    681                     PM4x10_PORT_TIME_STAMP_ADJUST_OLD_GET(unit, pm_info, &port_ts_adjust,
    682                                                           adjust_index, i));
    683                 _SOC_IF_ERR_EXIT(
    684                     PM4x10_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info, &port_ts_adjust,
    685                                                       adjust_index, i));
    686             }
    687             /* Initialize new timestamp adjust configs as 0. */
    688             while (adjust_index < PORTMOD_TS_ADJUST_NUM) {
    689                 sal_memset(&port_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
    690                 _SOC_IF_ERR_EXIT(
    691                     PM4x10_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info, &port_ts_adjust,
    692                                                       adjust_index, i));
    693                 adjust_index++;
    694             }
    695         }
    696     }
    697 exit:
    698     SOC_FUNC_RETURN;
    699 }
    700 /*
    701  * Initialize the buffer to support warmboot
    702  * The state of warmboot is store in the variables like
    703  * isInitialized, isActive, isBypassed, ports.. etc.,
    704  * All of these variables need to be added to warmboot
    705  * any variables added to save the state of warmboot should be
    706  * included here.
    707  */
    708 STATIC
    709 int pm4x10_wb_buffer_init(int unit, int wb_buffer_index, pm_info_t pm_info)
    710 {
    711     /* Declare the common variables needed for warmboot */
    712     WB_ENGINE_INIT_TABLES_DEFS;
    713     int wb_var_id, rv;
    714     int buffer_id = wb_buffer_index; /*required by SOC_WB_ENGINE_ADD_ Macros*/
    715     SOC_INIT_FUNC_DEFS;
    716 
    717     COMPILER_REFERENCE(buffer_is_dynamic);
    718 
    719     SOC_WB_ENGINE_ADD_BUFF(SOC_WB_ENGINE_PORTMOD, wb_buffer_index, "pm4x10",
    720                            portmod_pm4x10_wb_upgrade_func, pm_info,
    721                            PM4x10_WB_BUFFER_VERSION, 1, SOC_WB_ENGINE_PRE_RELEASE);
    722     _SOC_IF_ERR_EXIT(rv);
    723 
    724     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    725     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_initialized",
    726                           wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    727     _SOC_IF_ERR_EXIT(rv);
    728     pm_info->wb_vars_ids[isInitialized] = wb_var_id;
    729 
    730     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    731     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "ports",
    732                           wb_buffer_index, sizeof(int), NULL,
    733                           MAX_PORTS_PER_PM4X10, VERSION(1));
    734     _SOC_IF_ERR_EXIT(rv);
    735     pm_info->wb_vars_ids[ports] = wb_var_id;
    736 
    737     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    738     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_active",
    739                           wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    740     _SOC_IF_ERR_EXIT(rv);
    741     pm_info->wb_vars_ids[isActive] = wb_var_id;
    742 
    743     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    744     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_bypassed",
    745                           wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    746     _SOC_IF_ERR_EXIT(rv);
    747     pm_info->wb_vars_ids[isBypassed] = wb_var_id;
    748 
    749     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    750     SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "three_ports_mode",
    751                           wb_buffer_index, sizeof(uint32), NULL, VERSION(1));
    752     _SOC_IF_ERR_EXIT(rv);
    753     pm_info->wb_vars_ids[threePortsMode] = wb_var_id;
    754 
    755     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    756     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "phy_type",
    757                           wb_buffer_index, sizeof(int), NULL,
    758                           MAX_PORTS_PER_PM4X10, VERSION(1));
    759     _SOC_IF_ERR_EXIT(rv);
    760     pm_info->wb_vars_ids[phy_type] = wb_var_id;
    761 
    762     /* Deleting the below WB structures since most likely to be added in the future in a diffrent format */
    763     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    764     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    765                                         "interface_config", wb_buffer_index,
    766                                         sizeof(portmod_port_interface_config_t),
    767                                         NULL, 1, 1, 0xffffffff, 0xffffffff,
    768                                         VERSION(2), VERSION(3), NULL);
    769     _SOC_IF_ERR_EXIT(rv);
    770     pm_info->wb_vars_ids[interfaceConfig] = wb_var_id;
    771 
    772     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    773     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    774                                         "port_init_config", wb_buffer_index,
    775                                         sizeof(portmod_port_init_config_t),
    776                                         NULL, 1, 1, 0xffffffff, 0xffffffff,
    777                                         VERSION(2), VERSION(3), NULL);
    778     _SOC_IF_ERR_EXIT(rv);
    779     pm_info->wb_vars_ids[portInitConfig] = wb_var_id;
    780 
    781     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    782     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    783                                         "phy_init_config", wb_buffer_index,
    784                                         sizeof(phymod_phy_init_config_t),
    785                                         NULL, 1, 1, 0xffffffff, 0xffffffff,
    786                                         VERSION(2), VERSION(3), NULL);
    787     _SOC_IF_ERR_EXIT(rv);
    788     pm_info->wb_vars_ids[phyInitConfig] = wb_var_id;
    789 
    790     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    791     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    792                                        "phy_interface_config", wb_buffer_index,
    793                                        sizeof(phymod_phy_inf_config_t), NULL,
    794                                        1, 1, 0xffffffff, 0xffffffff, VERSION(2),
    795                                        VERSION(3), NULL);
    796     _SOC_IF_ERR_EXIT(rv);
    797     pm_info->wb_vars_ids[phyInterfaceConfig] = wb_var_id;
    798 
    799     /*
    800      * Keeping the below 2 WB var/arr since most likely to be used in the future.
    801      */
    802     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    803     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    804                           "port_dynamic_state", wb_buffer_index,
    805                           sizeof(uint32_t), NULL, PM4X10_LANES_PER_CORE,
    806                           VERSION(2));
    807     _SOC_IF_ERR_EXIT(rv);
    808     pm_info->wb_vars_ids[portDynamicState] = wb_var_id;
    809 
    810     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    811     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "nof_phys",
    812                           wb_buffer_index, sizeof(int), NULL,
    813                           PM4X10_LANES_PER_CORE, VERSION(2));
    814     _SOC_IF_ERR_EXIT(rv);
    815     pm_info->wb_vars_ids[nofPhys] = wb_var_id;
    816 
    817     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    818     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "lane_connection_db",
    819                           wb_buffer_index, sizeof(portmod_xphy_lane_connection_t), NULL,
    820                           PM4X10_LANES_PER_CORE, MAX_PHYN, VERSION(4));
    821     _SOC_IF_ERR_EXIT(rv);
    822     pm_info->wb_vars_ids[laneConnectionDb] = wb_var_id;
    823 
    824     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    825     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "data_rate",
    826                           wb_buffer_index, sizeof(int), NULL,
    827                           MAX_PORTS_PER_PM4X10, VERSION(5));
    828     _SOC_IF_ERR_EXIT(rv);
    829     pm_info->wb_vars_ids[dataRate] = wb_var_id;
    830     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    831     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "max_speed",
    832                           wb_buffer_index, sizeof(uint32), NULL,
    833                           MAX_PORTS_PER_PM4X10, VERSION(5));
    834     _SOC_IF_ERR_EXIT(rv);
    835     pm_info->wb_vars_ids[maxSpeed] = wb_var_id;
    836     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    837     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_type",
    838                           wb_buffer_index, sizeof(uint32), NULL,
    839                           MAX_PORTS_PER_PM4X10, VERSION(5));
    840     _SOC_IF_ERR_EXIT(rv);
    841     pm_info->wb_vars_ids[interfaceType] = wb_var_id;
    842     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    843     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "serdes_interface",
    844                           wb_buffer_index, sizeof(uint32), NULL,
    845                           MAX_PORTS_PER_PM4X10, VERSION(5));
    846     _SOC_IF_ERR_EXIT(rv);
    847     pm_info->wb_vars_ids[serdesInterfaceType] = wb_var_id;
    848     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    849     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "interface_modes",
    850                           wb_buffer_index, sizeof(uint32), NULL,
    851                           MAX_PORTS_PER_PM4X10, VERSION(5));
    852     _SOC_IF_ERR_EXIT(rv);
    853     pm_info->wb_vars_ids[interfaceModes] = wb_var_id;
    854     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    855     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    856                           "is_interface_restore", wb_buffer_index,
    857                           sizeof(uint32), NULL, PM4X10_LANES_PER_CORE,
    858                           VERSION(5));
    859     _SOC_IF_ERR_EXIT(rv);
    860     pm_info->wb_vars_ids[isInterfaceRestore] = wb_var_id;
    861     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    862     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_hg",
    863                           wb_buffer_index, sizeof(uint32), NULL,
    864                           PM4X10_LANES_PER_CORE, VERSION(5));
    865     _SOC_IF_ERR_EXIT(rv);
    866     pm_info->wb_vars_ids[isHg] = wb_var_id;
    867     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    868     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_cl73",
    869                           wb_buffer_index, sizeof(uint32), NULL,
    870                           PM4X10_LANES_PER_CORE, VERSION(5));
    871     _SOC_IF_ERR_EXIT(rv);
    872     pm_info->wb_vars_ids[anMode] = wb_var_id;
    873     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    874     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "fs_cl72",
    875                           wb_buffer_index, sizeof(uint32), NULL,
    876                           PM4X10_LANES_PER_CORE, VERSION(5));
    877     _SOC_IF_ERR_EXIT(rv);
    878     pm_info->wb_vars_ids[fsCl72] = wb_var_id;
    879     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    880     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "cx4_10G",
    881                           wb_buffer_index, sizeof(uint32), NULL,
    882                           PM4X10_LANES_PER_CORE, VERSION(5));
    883     _SOC_IF_ERR_EXIT(rv);
    884     pm_info->wb_vars_ids[cx4In10G] = wb_var_id;
    885     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    886     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_Cl72",
    887                           wb_buffer_index, sizeof(uint32), NULL,
    888                           PM4X10_LANES_PER_CORE, VERSION(5));
    889     _SOC_IF_ERR_EXIT(rv);
    890     pm_info->wb_vars_ids[anCl72] = wb_var_id;
    891     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    892     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_fec",
    893                           wb_buffer_index, sizeof(uint32), NULL,
    894                           PM4X10_LANES_PER_CORE,  VERSION(5));
    895     _SOC_IF_ERR_EXIT(rv);
    896     pm_info->wb_vars_ids[anFec] = wb_var_id;
    897     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    898     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_cl37",
    899                           wb_buffer_index, sizeof(uint32), NULL,
    900                           PM4X10_LANES_PER_CORE, VERSION(5));
    901     _SOC_IF_ERR_EXIT(rv);
    902     pm_info->wb_vars_ids[anCl37] = wb_var_id;
    903     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    904     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "an_master_lane",
    905                           wb_buffer_index, sizeof(int), NULL,
    906                           PM4X10_LANES_PER_CORE, VERSION(5));
    907     _SOC_IF_ERR_EXIT(rv);
    908     pm_info->wb_vars_ids[anMasterLane] = wb_var_id;
    909     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    910     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "cl37_sgmii_count",
    911                           wb_buffer_index, sizeof(int), NULL,
    912                           PM4X10_LANES_PER_CORE, VERSION(5));
    913     _SOC_IF_ERR_EXIT(rv);
    914     pm_info->wb_vars_ids[cl37SgmiiCnt] = wb_var_id;
    915     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    916     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    917                           "cl37_sgmii_restart_count", wb_buffer_index,
    918                           sizeof(int), NULL, PM4X10_LANES_PER_CORE, VERSION(5));
    919     _SOC_IF_ERR_EXIT(rv);
    920     pm_info->wb_vars_ids[cl37SgmiiRestartCnt] = wb_var_id;
    921     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    922     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "port_op_mode",
    923                           wb_buffer_index, sizeof(int), NULL,
    924                           PM4X10_LANES_PER_CORE, VERSION(5));
    925     _SOC_IF_ERR_EXIT(rv);
    926     pm_info->wb_vars_ids[portOpMode] = wb_var_id;
    927     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    928     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "rxaui_mode",
    929                           wb_buffer_index, sizeof(int), NULL,
    930                           PM4X10_LANES_PER_CORE, VERSION(5));
    931     _SOC_IF_ERR_EXIT(rv);
    932     pm_info->wb_vars_ids[rxauiMode] = wb_var_id;
    933     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    934     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    935                           "tx_params_user_flag",
    936                           wb_buffer_index, sizeof(uint32), NULL,
    937                           PHYMOD_MAX_LANES_PER_PORT, VERSION(5));
    938     _SOC_IF_ERR_EXIT(rv);
    939     pm_info->wb_vars_ids[txParamsUserFlag] = wb_var_id;
    940 
    941     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    942     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id, "tx_params", wb_buffer_index, sizeof(pm4x10_phymod_tx_t), NULL, 1, PHYMOD_MAX_LANES_PER_PORT, 0xffffffff, 0xffffffff, VERSION(5), VERSION(9), NULL);
    943     _SOC_IF_ERR_EXIT(rv);
    944     pm_info->wb_vars_ids[txParams] = wb_var_id;
    945 
    946     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    947     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    948                           "ext_phy_tx_params_user_flag",
    949                           wb_buffer_index, sizeof(uint32), NULL,
    950                           PHYMOD_MAX_LANES_PER_PORT, VERSION(5));
    951     _SOC_IF_ERR_EXIT(rv);
    952     pm_info->wb_vars_ids[extPhyTxParamsUserFlag] = wb_var_id;
    953 
    954     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    955     SOC_WB_ENGINE_ADD_VAR_WITH_FEATURES(SOC_WB_ENGINE_PORTMOD, wb_var_id, "ext_phy_tx_params", wb_buffer_index, sizeof(pm4x10_phymod_tx_t), NULL, 1, PHYMOD_MAX_LANES_PER_PORT, 0xffffffff, 0xffffffff, VERSION(5), VERSION(9), NULL);
    956     _SOC_IF_ERR_EXIT(rv);
    957     pm_info->wb_vars_ids[extPhyTxParams] = wb_var_id;
    958 
    959     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    960     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "fallback_lane",
    961                           wb_buffer_index, sizeof(int), NULL,
    962                           PM4X10_LANES_PER_CORE, VERSION(5));
    963     _SOC_IF_ERR_EXIT(rv);
    964     pm_info->wb_vars_ids[fallbackLane] = wb_var_id;
    965 
    966     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    967     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    968                           "pll_divider_req",
    969                           wb_buffer_index, sizeof(int), NULL,
    970                           PM4X10_LANES_PER_CORE,
    971                           VERSION(6));
    972     _SOC_IF_ERR_EXIT(rv);
    973     pm_info->wb_vars_ids[pllDividerReq] = wb_var_id;
    974 
    975     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    976     SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    977                           "interface_written_into_outmost_phy",
    978                           wb_buffer_index, sizeof(uint32), NULL,
    979                           MAX_PORTS_PER_PM4X10, VERSION(7));
    980     _SOC_IF_ERR_EXIT(rv);
    981     pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy] = wb_var_id;
    982 
    983     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    984     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    985                           "time stamp adjust setting on MAC",
    986                           wb_buffer_index, sizeof(portmod_port_ts_adjust_t), NULL,
    987                           PORTMOD_TS_ADJUST_NUM_OLD,
    988                           MAX_PORTS_PER_PM4X10, VERSION(8));
    989     _SOC_IF_ERR_EXIT(rv);
    990     pm_info->wb_vars_ids[tsAdjustOld] = wb_var_id;
    991 
    992     _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id));
    993     SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id,
    994                           "new time stamp adjust setting on MAC",
    995                           wb_buffer_index, sizeof(portmod_port_ts_adjust_t), NULL,
    996                           PORTMOD_TS_ADJUST_NUM,
    997                           MAX_PORTS_PER_PM4X10, VERSION(10));
    998     _SOC_IF_ERR_EXIT(rv);
    999     pm_info->wb_vars_ids[tsAdjust] = wb_var_id;
   1000 
   1001     _SOC_IF_ERR_EXIT(soc_wb_engine_init_buffer(unit, SOC_WB_ENGINE_PORTMOD,
   1002                      wb_buffer_index, FALSE));
   1003 
   1004     if(!SOC_WARM_BOOT(unit)){
   1005         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1006                                       pm_info->wb_vars_ids[ports], -1);
   1007         _SOC_IF_ERR_EXIT(rv);
   1008         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1009                                       pm_info->wb_vars_ids[dataRate], 0);
   1010         _SOC_IF_ERR_EXIT(rv);
   1011         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1012                                       pm_info->wb_vars_ids[maxSpeed], 0);
   1013         _SOC_IF_ERR_EXIT(rv);
   1014         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1015                                       pm_info->wb_vars_ids[interfaceType],
   1016                                       _SHR_PORT_IF_COUNT);
   1017         _SOC_IF_ERR_EXIT(rv);
   1018         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1019                                pm_info->wb_vars_ids[serdesInterfaceType],
   1020                                _SHR_PORT_IF_NULL);
   1021         _SOC_IF_ERR_EXIT(rv);
   1022         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1023                                    pm_info->wb_vars_ids[interfaceModes], 0);
   1024         _SOC_IF_ERR_EXIT(rv);
   1025         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1026                                       pm_info->wb_vars_ids[nofPhys], 0);
   1027         _SOC_IF_ERR_EXIT(rv);
   1028         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1029                                    pm_info->wb_vars_ids[portDynamicState], 0);
   1030         _SOC_IF_ERR_EXIT(rv);
   1031         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1032                                  pm_info->wb_vars_ids[isInterfaceRestore], 0);
   1033         _SOC_IF_ERR_EXIT(rv);
   1034         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1035                                pm_info->wb_vars_ids[isHg], _SHR_PORT_IF_COUNT);
   1036         _SOC_IF_ERR_EXIT(rv);
   1037         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1038                                       pm_info->wb_vars_ids[anMode],
   1039                                       phymod_AN_MODE_Count);
   1040         _SOC_IF_ERR_EXIT(rv);
   1041         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1042                                       pm_info->wb_vars_ids[fsCl72], 0);
   1043         _SOC_IF_ERR_EXIT(rv);
   1044         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1045                                       pm_info->wb_vars_ids[cx4In10G], 0);
   1046         _SOC_IF_ERR_EXIT(rv);
   1047         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1048                                       pm_info->wb_vars_ids[anCl72], 0);
   1049         _SOC_IF_ERR_EXIT(rv);
   1050         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1051                                       pm_info->wb_vars_ids[anFec], 0);
   1052         _SOC_IF_ERR_EXIT(rv);
   1053         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1054                                       pm_info->wb_vars_ids[anCl37], 0);
   1055         _SOC_IF_ERR_EXIT(rv);
   1056         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1057                                       pm_info->wb_vars_ids[anMasterLane], -1);
   1058         _SOC_IF_ERR_EXIT(rv);
   1059         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1060                                       pm_info->wb_vars_ids[rxauiMode], 0);
   1061         _SOC_IF_ERR_EXIT(rv);
   1062         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1063                                    pm_info->wb_vars_ids[txParamsUserFlag], 0);
   1064         _SOC_IF_ERR_EXIT(rv);
   1065         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1066                         pm_info->wb_vars_ids[extPhyTxParamsUserFlag], 0);
   1067         _SOC_IF_ERR_EXIT(rv);
   1068         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1069                         pm_info->wb_vars_ids[pllDividerReq], 0);
   1070         _SOC_IF_ERR_EXIT(rv);
   1071         rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1072                         pm_info->wb_vars_ids[interfaceWrittenIntoOutmostPhy], _SHR_PORT_IF_COUNT);
   1073         _SOC_IF_ERR_EXIT(rv);
   1074     }
   1075 exit:
   1076     SOC_FUNC_RETURN;
   1077 }
   1078 
   1079 STATIC portmod_ucode_buf_t pm4x10_ucode_buf[SOC_MAX_NUM_DEVICES] = {{NULL, 0}};
   1080 STATIC portmod_ucode_buf_t pm4x10_ucode_buf_2nd[SOC_MAX_NUM_DEVICES] = {{NULL, 0}};
   1081 
   1082 
   1083 int pm4x10_pm_destroy(int unit, pm_info_t pm_info)
   1084 {
   1085     if(pm_info->pm_data.pm4x10_db != NULL) {
   1086         sal_free(pm_info->pm_data.pm4x10_db);
   1087         pm_info->pm_data.pm4x10_db = NULL;
   1088     }
   1089 
   1090     /* free pm4x10_ucode_buf */
   1091     if(pm4x10_ucode_buf[unit].ucode_dma_buf != NULL){
   1092         portmod_sys_dma_free(unit, pm4x10_ucode_buf[unit].ucode_dma_buf);
   1093         pm4x10_ucode_buf[unit].ucode_dma_buf = NULL;
   1094     }
   1095     pm4x10_ucode_buf[unit].ucode_alloc_size = 0;
   1096 
   1097     if(pm4x10_ucode_buf_2nd[unit].ucode_dma_buf != NULL){
   1098         portmod_sys_dma_free(unit, pm4x10_ucode_buf_2nd[unit].ucode_dma_buf);
   1099         pm4x10_ucode_buf_2nd[unit].ucode_dma_buf = NULL;
   1100     }
   1101     pm4x10_ucode_buf_2nd[unit].ucode_alloc_size = 0;
   1102 
   1103     return SOC_E_NONE;
   1104 }
   1105 
   1106 int
   1107 pm4x10_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data)
   1108 {
   1109     int rv;
   1110     portmod_default_user_access_t *user_data;
   1111     int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit;
   1112     portmod_ucode_buf_order_t load_order;
   1113     SOC_INIT_FUNC_DEFS;
   1114 
   1115     user_data = (portmod_default_user_access_t*)core->access.user_acc;
   1116 
   1117     if (PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_GET(user_data)) {
   1118         load_order = portmod_ucode_buf_order_reversed;
   1119     } else {
   1120         load_order = portmod_ucode_buf_order_straight;
   1121     }
   1122 
   1123     rv = portmod_firmware_set(unit,
   1124                               user_data->blk_id,
   1125                               data,
   1126                               length,
   1127                               load_order,
   1128                               0,
   1129                               &(pm4x10_ucode_buf[unit]),
   1130                               &(pm4x10_ucode_buf_2nd[unit]),
   1131                               XLPORT_WC_UCMEM_DATAm,
   1132                               XLPORT_WC_UCMEM_CTRLr);
   1133     _SOC_IF_ERR_EXIT(rv);
   1134 
   1135 exit:
   1136     SOC_FUNC_RETURN;
   1137 }
   1138 
   1139 STATIC
   1140 int
   1141 pm4x10_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
   1142 {
   1143     return portmod_common_phy_sbus_reg_write(XLPORT_WC_UCMEM_DATAm, user_acc, core_addr, reg_addr, val);
   1144 }
   1145 
   1146 STATIC
   1147 int
   1148 pm4x10_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
   1149 {
   1150     return portmod_common_phy_sbus_reg_read(XLPORT_WC_UCMEM_DATAm, user_acc, core_addr, reg_addr, val);
   1151 }
   1152 
   1153 /*
   1154  * XLPORT_SOFT_RESET by physical port
   1155  * This function expects 2nd argument port is physical port.
   1156  */
   1157 STATIC
   1158 int _pm4x10_port_soft_reset_set_by_phyport(int unit, int port, pm_info_t pm_info, int idx, int val)
   1159 {
   1160     int phy_port;
   1161     uint32 reg_val, raddr;
   1162     int    block;
   1163     uint8  at;
   1164     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   1165 
   1166     SOC_INIT_FUNC_DEFS;
   1167 
   1168     phy_port = port;
   1169     raddr = soc_reg_addr_get(unit, XLPORT_SOFT_RESETr, phy_port, 0,
   1170                  SOC_REG_ADDR_OPTION_PRESERVE_PORT,
   1171                  &block, &at);
   1172 
   1173     _SOC_IF_ERR_EXIT
   1174       (_soc_reg32_get(unit, block, at, raddr, &reg_val));
   1175 
   1176     soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, port_fields[idx], val);
   1177 
   1178     raddr = soc_reg_addr_get(unit, XLPORT_SOFT_RESETr, phy_port, 0,
   1179                 SOC_REG_ADDR_OPTION_WRITE | SOC_REG_ADDR_OPTION_PRESERVE_PORT,
   1180                 &block, &at);
   1181     _SOC_IF_ERR_EXIT(_soc_reg32_set(unit, block, at, raddr, reg_val));
   1182 
   1183 exit:
   1184     SOC_FUNC_RETURN;
   1185 }
   1186 
   1187 STATIC
   1188 int _pm4x10_port_soft_reset_set(int unit, int port, pm_info_t pm_info, int idx, int val)
   1189 {
   1190     int phy_acc;
   1191     uint32 reg_val;
   1192     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   1193 
   1194     SOC_INIT_FUNC_DEFS;
   1195 
   1196     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1197 
   1198     _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   1199     soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, port_fields[idx],
   1200                       val);
   1201     _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   1202 
   1203 exit:
   1204     SOC_FUNC_RETURN;
   1205 }
   1206 
   1207 int pm4x10_port_soft_reset_toggle(int unit, int port, pm_info_t pm_info, int idx)
   1208 {                    
   1209     int phy_acc;      
   1210     uint32 reg_val, old_val;
   1211     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   1212 
   1213     SOC_INIT_FUNC_DEFS;
   1214 
   1215     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1216             
   1217     _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   1218     old_val = reg_val;
   1219 
   1220     soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, port_fields[idx], 1); 
   1221 
   1222     _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   1223     _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, old_val));
   1224 
   1225 exit:
   1226     SOC_FUNC_RETURN;        
   1227 }
   1228 
   1229 phymod_bus_t pm4x10_default_bus = {
   1230     "PM4x10 Bus",
   1231     pm4x10_default_bus_read,
   1232     pm4x10_default_bus_write,
   1233     NULL,
   1234     portmod_common_mutex_take,
   1235     portmod_common_mutex_give,
   1236     NULL,
   1237     NULL,
   1238     PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL
   1239 };
   1240 
   1241 int pm4x10_pm_init(int unit,
   1242                    const portmod_pm_create_info_internal_t* pm_add_info,
   1243                    int wb_buffer_index, pm_info_t pm_info)
   1244 {
   1245     const portmod_pm4x10_create_info_t *info;
   1246     pm4x10_t pm4x10_data = NULL;
   1247     int i,j, pm_is_active, rv, three_ports_mode, nof_phys = 0;
   1248     int pm_is_initialized;
   1249     int bypass_enable;
   1250     int lane, phyn;
   1251     portmod_xphy_lane_connection_t lane_conn; 
   1252     portmod_xphy_lane_connection_t *db_lane_conn;    
   1253  
   1254     SOC_INIT_FUNC_DEFS;
   1255 
   1256     info = &pm_add_info->pm_specific_info.pm4x10;
   1257     pm4x10_data = sal_alloc(sizeof(struct pm4x10_s), "pm4x10_specific_db");
   1258     SOC_NULL_CHECK(pm4x10_data);
   1259 
   1260     pm_info->type = pm_add_info->type;
   1261     pm_info->unit = unit;
   1262     pm_info->wb_buffer_id = wb_buffer_index;
   1263     pm_info->pm_data.pm4x10_db = pm4x10_data;
   1264     pm_info->pm_data.pm4x10_db->link_recovery.enabled = TRUE;
   1265     pm_info->pm_data.pm4x10_db->link_recovery.tick_cnt = 0;
   1266     pm_info->pm_data.pm4x10_db->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK;
   1267     PORTMOD_PBMP_ASSIGN(pm4x10_data->phys, pm_add_info->phys);
   1268     pm4x10_data->int_core_access.type = phymodDispatchTypeInvalid;
   1269     pm4x10_data->default_bus_is_used = 0;
   1270     pm4x10_data->default_fw_loader_is_used = 0;
   1271     pm4x10_data->portmod_phy_external_reset = pm_add_info->pm_specific_info.pm4x10.portmod_phy_external_reset;
   1272     pm4x10_data->portmod_mac_soft_reset = pm_add_info->pm_specific_info.pm4x10.portmod_mac_soft_reset;
   1273     pm4x10_data->first_phy = -1;
   1274     pm4x10_data->warmboot_skip_db_restore = TRUE;
   1275     pm4x10_data->rescal = pm_add_info->pm_specific_info.pm4x10.rescal;
   1276     pm4x10_data->is_pm4x10q = pm_add_info->pm_specific_info.pm4x10.is_pm4x10q;
   1277     pm4x10_data->port_mode_aux_info = pm_add_info->pm_specific_info.pm4x10.port_mode_aux_info;
   1278 
   1279     /* initialize num of phys for each lane */
   1280     for(i = 0 ; i < PM4X10_LANES_PER_CORE ; i++){
   1281         pm4x10_data->nof_phys[i] = 0;
   1282     }
   1283     /* init intertnal SerDes core access */
   1284     phymod_core_access_t_init(&pm4x10_data->int_core_access);
   1285 
   1286     /* initialize lane connections */
   1287     for(i = 0 ; i < MAX_PHYN ; i++){
   1288         for(j = 0 ; j < PM4X10_LANES_PER_CORE ; j++){
   1289             portmod_xphy_lane_connection_t_init(unit, &pm4x10_data->lane_conn[i][j]);
   1290         }
   1291     }
   1292 
   1293     sal_memcpy(&pm4x10_data->polarity, &info->polarity, 
   1294                 sizeof(phymod_polarity_t));
   1295     sal_memcpy(&(pm4x10_data->int_core_access.access), &info->access,
   1296                 sizeof(phymod_access_t));
   1297     sal_memcpy(&pm4x10_data->lane_map, &info->lane_map,
   1298                 sizeof(pm4x10_data->lane_map));
   1299     pm4x10_data->ref_clk = info->ref_clk;
   1300     pm4x10_data->fw_load_method = info->fw_load_method;
   1301     pm4x10_data->external_fw_loader = info->external_fw_loader;
   1302 
   1303     if(info->access.bus == NULL) {
   1304         /* if null - use default */
   1305         pm4x10_data->int_core_access.access.bus = &pm4x10_default_bus;
   1306         pm4x10_data->default_bus_is_used = 1;
   1307     }
   1308 
   1309     if(pm4x10_data->external_fw_loader == NULL) {
   1310         /* if null - use default */
   1311         pm4x10_data->external_fw_loader = pm4x10_default_fw_loader;
   1312         pm4x10_data->default_fw_loader_is_used = 1;
   1313     }
   1314  
   1315    /* initialize num of phys for each lane */
   1316     for(i = 0 ; i < PM4X10_LANES_PER_CORE ; i++){
   1317         pm4x10_data->nof_phys[i] = 1;
   1318     }
   1319  
   1320     pm4x10_data->in_pm12x10   = info->in_pm_12x10;
   1321     pm4x10_data->core_num     = info->core_num;
   1322     pm4x10_data->core_num_int = info->core_num_int;
   1323 
   1324     /*init wb buffer*/
   1325     _SOC_IF_ERR_EXIT(pm4x10_wb_buffer_init(unit, wb_buffer_index,  pm_info));
   1326 
   1327     if(SOC_WARM_BOOT(unit)){
   1328 
   1329         rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1330                          pm_info->wb_vars_ids[phy_type], &pm4x10_data->int_core_access.type, 0);
   1331 
   1332         /* restore nof_phys from wb */
   1333         for(i = 0 ; i < PM4X10_LANES_PER_CORE ; i++){
   1334             _SOC_IF_ERR_EXIT(PM4x10_PORT_NUM_PHYS_GET(unit, pm_info, &nof_phys, i));
   1335             pm4x10_data->nof_phys[i] = nof_phys;
   1336         }
   1337 
   1338         for(phyn = 0 ; phyn < MAX_PHYN ; phyn++){
   1339             for(lane = 0 ; lane < PM4X10_LANES_PER_CORE ; lane++){
   1340                 db_lane_conn = &(PM_4x10_INFO(pm_info)->lane_conn[phyn][lane]);
   1341                 _SOC_IF_ERR_EXIT(PM4x10_PORT_LANE_CONNECTION_DB_GET(unit, pm_info,
   1342                                  db_lane_conn, phyn, lane));
   1343             }
   1344         }
   1345 
   1346         _SOC_IF_ERR_EXIT(rv);
   1347     }
   1348 
   1349     if(!SOC_WARM_BOOT(unit)){
   1350         /* Cold Boot  */
   1351 
   1352         for(i = 0 ; i < PM4X10_LANES_PER_CORE ; i++){
   1353             nof_phys = 1;
   1354             rv = PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, &nof_phys, i);
   1355             _SOC_IF_ERR_EXIT(rv);
   1356         }
   1357 
   1358         pm_is_active = 0;
   1359         rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   1360                                 pm_info->wb_vars_ids[isActive], &pm_is_active);
   1361         _SOC_IF_ERR_EXIT(rv);
   1362 
   1363         pm_is_initialized = 0;
   1364         rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   1365                                 pm_info->wb_vars_ids[isInitialized], &pm_is_initialized);
   1366         _SOC_IF_ERR_EXIT(rv);
   1367 
   1368         bypass_enable = 0;
   1369         rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   1370                              pm_info->wb_vars_ids[isBypassed], &bypass_enable);
   1371         _SOC_IF_ERR_EXIT(rv);
   1372 
   1373         three_ports_mode = (info->port_mode_aux_info == portmodModeInfoThreePorts) ? 1 : 0;
   1374         rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, 
   1375                       pm_info->wb_vars_ids[threePortsMode], &three_ports_mode);
   1376         _SOC_IF_ERR_EXIT(rv);
   1377 
   1378          rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1379                     pm_info->wb_vars_ids[phy_type],
   1380                     &PM_4x10_INFO(pm_info)->int_core_access.type, 0);
   1381          _SOC_IF_ERR_EXIT(rv);
   1382 
   1383          for(phyn = 0 ; phyn < MAX_PHYN ; phyn++){
   1384             for(lane = 0 ; lane < PM4X10_LANES_PER_CORE ; lane++){
   1385                  portmod_xphy_lane_connection_t_init(unit, &lane_conn);
   1386                 _SOC_IF_ERR_EXIT(PM4x10_PORT_LANE_CONNECTION_DB_SET(unit, pm_info,
   1387                                  &lane_conn, phyn, lane));
   1388             }
   1389         }
   1390     }
   1391 
   1392 exit:
   1393     if(SOC_FUNC_ERROR){
   1394         pm4x10_pm_destroy(unit, pm_info);
   1395     }
   1396     SOC_FUNC_RETURN;
   1397 }
   1398 
   1399 int
   1400 pm4x10_default_bus_update(int unit, pm_info_t pm_info, const portmod_bus_update_t* update) 
   1401 {
   1402     portmod_default_user_access_t* user_acc;
   1403     soc_error_t rv = SOC_E_NONE;
   1404     SOC_INIT_FUNC_DEFS;
   1405 
   1406     if (update == NULL) /*restore to default*/
   1407     {
   1408         /* if null - use default */
   1409         PM_4x10_INFO(pm_info)->int_core_access.access.bus = &pm4x10_default_bus;
   1410         PM_4x10_INFO(pm_info)->int_core_access.type = phymodDispatchTypeInvalid;
   1411         PM_4x10_INFO(pm_info)->default_bus_is_used = 1;
   1412     
   1413         PM_4x10_INFO(pm_info)->external_fw_loader = pm4x10_default_fw_loader;
   1414         PM_4x10_INFO(pm_info)->default_fw_loader_is_used = 1;
   1415     }
   1416     else
   1417     {
   1418 
   1419         if(PM_4x10_INFO(pm_info)->default_fw_loader_is_used && update->external_fw_loader != NULL) {
   1420             PM_4x10_INFO(pm_info)->external_fw_loader = update->external_fw_loader;
   1421             user_acc = (portmod_default_user_access_t*)PM_4x10_INFO(pm_info)->int_core_access.access.user_acc;
   1422             user_acc->blk_id = (update->blk_id == -1) ? user_acc->blk_id : update->blk_id;
   1423             PM_4x10_INFO(pm_info)->default_fw_loader_is_used = 0;
   1424         }
   1425 
   1426         if(PM_4x10_INFO(pm_info)->default_bus_is_used && update->default_bus != NULL) {
   1427             PM_4x10_INFO(pm_info)->int_core_access.access.bus = update->default_bus; 
   1428             user_acc = (portmod_default_user_access_t*)PM_4x10_INFO(pm_info)->int_core_access.access.user_acc;
   1429             user_acc->blk_id = (update->blk_id == -1) ? user_acc->blk_id : update->blk_id;
   1430             if (PM_4x10_INFO(pm_info)->int_core_access.type >= phymodDispatchTypeCount) {
   1431                 PM_4x10_INFO(pm_info)->int_core_access.type = phymodDispatchTypeInvalid;
   1432             }
   1433             PM_4x10_INFO(pm_info)->default_bus_is_used = 0;
   1434         }
   1435 
   1436         if (update->user_acc != NULL) {
   1437             PM_4x10_INFO(pm_info)->int_core_access.access.user_acc = update->user_acc;
   1438         }
   1439 
   1440     }
   1441 
   1442     /*update warmboot engine*/
   1443     rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   1444         pm_info->wb_vars_ids[phy_type],
   1445         &PM_4x10_INFO(pm_info)->int_core_access.type, 0);
   1446     _SOC_IF_ERR_EXIT(rv);
   1447 
   1448 exit:
   1449     SOC_FUNC_RETURN;
   1450 }
   1451 
   1452 STATIC
   1453 int _pm4x10_port_tricore_lane_info_get(int unit, int port, pm_info_t pm_info,
   1454                                        int *start_lane, int* end_lane,
   1455                                        int *line_start_lane, int* line_end_lane,
   1456                                        uint32 *int_core_lane_mask, 
   1457                                        const portmod_access_get_params_t* params);
   1458 
   1459 STATIC
   1460 int _pm4x10_nof_lanes_get(int unit, int port, pm_info_t pm_info)
   1461 {
   1462     int port_index, rv;
   1463     uint32_t bitmap, bcnt = 0;
   1464 
   1465     rv = _pm4x10_port_index_get (unit, port, pm_info, &port_index,
   1466                                              &bitmap);
   1467     if (rv) return (0); /* bit count is zero will flag error */
   1468 
   1469     while (bitmap) {
   1470         if (bitmap & 0x1) bcnt++;
   1471         bitmap >>= 1;
   1472     }
   1473 
   1474     return (bcnt);
   1475 }
   1476 
   1477 STATIC
   1478 int _pm4x10_an_mode_update (int unit, int port, pm_info_t pm_info,
   1479                             int an_cl37, int an_cl73);
   1480 
   1481 int pm4x10_port_warmboot_db_restore(int unit, int port, pm_info_t pm_info,
   1482                          const portmod_port_interface_config_t *f_intf_config,
   1483                          const portmod_port_init_config_t      *f_init_config,
   1484                          const phymod_operation_mode_t phy_op_mode)
   1485 {
   1486     pm4x10_t pm4x10_data = NULL;
   1487     phymod_phy_access_t                 phy_access[1+MAX_PHYN];
   1488     phymod_phy_inf_config_t            phy_intf_config;
   1489     phymod_autoneg_control_t            an; 
   1490     portmod_encap_t                    encap_mode;
   1491     soc_port_if_t                      interface;
   1492 
   1493     int     phy, nof_phys, port_index, rv = 0, flags = 0;
   1494     uint32  bitmap, an_done, interface_modes = 0, is_interface_restore = 0;
   1495 
   1496     /*
   1497      * if no warmboot db restore is require, just return here.
   1498      */
   1499     if(PM_4x10_INFO(pm_info)->warmboot_skip_db_restore){
   1500         return SOC_E_NONE;
   1501     }
   1502 
   1503     rv = _pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   1504     if (SOC_FAILURE(rv)) return (rv);
   1505 
   1506     pm4x10_data      = pm_info->pm_data.pm4x10_db;
   1507     SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(&phy_intf_config));
   1508 
   1509     rv = PM4x10_IS_HG_SET(unit, pm_info, f_init_config->is_hg, port_index);
   1510     if (SOC_FAILURE(rv)) return (rv);
   1511 
   1512     rv = PM4x10_AN_MODE_SET(unit, pm_info, f_init_config->an_mode, port_index);
   1513     if (SOC_FAILURE(rv)) return (rv);
   1514 
   1515     rv = PM4x10_FS_CL72_SET(unit, pm_info, f_init_config->fs_cl72, port_index);
   1516     if (SOC_FAILURE(rv)) return (rv);
   1517 
   1518     rv = PM4x10_CX4_10G_SET(unit, pm_info, f_init_config->cx4_10g, port_index);
   1519     if (SOC_FAILURE(rv)) return (rv);
   1520 
   1521     rv = PM4x10_AN_CL72_SET(unit, pm_info, f_init_config->an_cl72, port_index);
   1522     if (SOC_FAILURE(rv)) return (rv);
   1523 
   1524     rv = PM4x10_AN_FEC_SET(unit, pm_info, f_init_config->an_fec, port_index);
   1525     if (SOC_FAILURE(rv)) return (rv);
   1526 
   1527     rv = PM4x10_AN_CL37_SET(unit, pm_info, f_init_config->an_cl37, port_index);
   1528     if (SOC_FAILURE(rv)) return (rv);
   1529 
   1530     rv = PM4x10_AN_MASTER_LANE_SET(unit, pm_info,
   1531                                    f_init_config->an_master_lane,
   1532                                    port_index);
   1533     if (SOC_FAILURE(rv)) return (rv);
   1534 
   1535     rv = PM4x10_PORT_FALLBACK_LANE_SET(unit, pm_info,
   1536                                    f_init_config->port_fallback_lane,
   1537                                    port_index);
   1538     if (SOC_FAILURE(rv)) return (rv);
   1539 
   1540     rv = PM4x10_MAX_SPEED_SET(unit, pm_info, f_intf_config->max_speed,
   1541                               port_index);
   1542     if (SOC_FAILURE(rv)) return (rv);
   1543 
   1544     rv = PM4x10_RXAUI_MODE_SET(unit, pm_info, f_init_config->rxaui_mode,
   1545                                port_index);
   1546     if (SOC_FAILURE(rv)) return (rv);
   1547 
   1548 
   1549     rv = PM4x10_INTERFACE_TYPE_SET(unit, pm_info,
   1550                                    f_intf_config->interface,
   1551                                    port_index);
   1552     if (SOC_FAILURE(rv)) return (rv);
   1553 
   1554     rv = PM4x10_SERDES_INTERFACE_TYPE_SET(unit, pm_info,
   1555                                           f_intf_config->serdes_interface,
   1556                                           port_index);
   1557     if (SOC_FAILURE(rv)) return (rv);
   1558 
   1559     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {
   1560         pm4x10_data->first_phy = phy;
   1561         break;
   1562     }
   1563 
   1564     rv = portmod_port_chain_phy_access_get (unit, port, pm_info, phy_access,
   1565                                            (1+MAX_PHYN), &nof_phys);
   1566     if (SOC_FAILURE(rv)) return (rv);
   1567 
   1568     rv = portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   1569                                    0, phymodRefClk156Mhz, &phy_intf_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY);
   1570     if (SOC_FAILURE(rv)) return (rv);
   1571 
   1572     rv = PM4x10_IS_INTERFACE_RESTORE_SET(unit, pm_info, is_interface_restore,
   1573                                          port_index);
   1574     if (SOC_FAILURE(rv)) return (rv);
   1575 
   1576     rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   1577                                     port_index);
   1578     if (SOC_FAILURE(rv)) return (rv);
   1579 
   1580     interface_modes |= phy_intf_config.interface_modes;
   1581 
   1582     rv = PM4x10_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   1583     if (SOC_FAILURE(rv)) return (rv);
   1584 
   1585     rv = portmod_port_interface_type_get (unit, port, &interface);
   1586     if (SOC_FAILURE(rv)) return (rv);
   1587 
   1588     rv = PM4x10_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index);
   1589     if (SOC_FAILURE(rv)) return (rv);
   1590 
   1591     rv = PM4x10_SPEED_SET(unit, pm_info, phy_intf_config.data_rate, port_index);
   1592     if (SOC_FAILURE(rv)) return (rv);
   1593 
   1594     xlmac_encap_get(unit, port, &flags, &encap_mode);
   1595 
   1596     if ((encap_mode == SOC_ENCAP_HIGIG2) || (encap_mode == SOC_ENCAP_HIGIG)) {
   1597         interface_modes |= PHYMOD_INTF_MODES_HIGIG;
   1598         rv = PM4x10_INTERFACE_MODES_SET(unit, pm_info, interface_modes,
   1599                                         port_index);
   1600         if (SOC_FAILURE(rv)) return (rv);
   1601     }
   1602     
   1603     rv = portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &an, &an_done);
   1604     if (SOC_FAILURE(rv)) return (rv);
   1605 
   1606     rv = PM4x10_AN_MODE_SET(unit, pm_info, an.an_mode, port_index);
   1607     if (SOC_FAILURE(rv)) return (rv);
   1608 
   1609     if(an.an_mode == phymod_AN_MODE_NONE){
   1610         _pm4x10_an_mode_update(unit, port, pm_info, f_init_config->an_cl37,
   1611                                f_init_config->an_cl73);
   1612     }
   1613     
   1614     rv = PM4x10_PORT_OP_MODE_SET(unit, pm_info, phy_op_mode, port_index);
   1615     if (SOC_FAILURE(rv)) return (rv);
   1616 
   1617     return (SOC_E_NONE);
   1618 }
   1619 
   1620 STATIC
   1621 int _pm4x10_tsc_reset(int unit, pm_info_t pm_info, int port, int in_reset)
   1622 {
   1623     int phy_acc;
   1624     uint32 reg_val, phy;
   1625     SOC_INIT_FUNC_DEFS;
   1626 
   1627     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1628 
   1629     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {break;};
   1630 
   1631     if(PM_4x10_INFO(pm_info)->in_pm12x10) {
   1632 #ifdef PORTMOD_PM12X10_SUPPORT
   1633 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
   1634         
   1635         if (SOC_IS_APACHE(unit)) {
   1636             _SOC_IF_ERR_EXIT(pm12x10_xgs_pm4x10_tsc_reset(unit, port, phy, in_reset));
   1637         } else
   1638 #endif
   1639         {
   1640             _SOC_IF_ERR_EXIT(pm12x10_pm4x10_tsc_reset(unit, port, phy, in_reset));
   1641         }
   1642 #endif
   1643     } else {
   1644         _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_CTRL_REGr(unit, phy_acc, &reg_val));
   1645 
   1646         soc_reg_field_set (unit, XLPORT_XGXS0_CTRL_REGr, &reg_val, RSTB_HWf,
   1647                            in_reset ? 0 : 1);
   1648         soc_reg_field_set (unit, XLPORT_XGXS0_CTRL_REGr, &reg_val, PWRDWNf,
   1649                            in_reset ? 1 : 0);
   1650         soc_reg_field_set (unit, XLPORT_XGXS0_CTRL_REGr, &reg_val, IDDQf,
   1651                            in_reset ? 1 : 0);
   1652 
   1653         _SOC_IF_ERR_EXIT(WRITE_XLPORT_XGXS0_CTRL_REGr(unit, phy_acc, reg_val));
   1654     }
   1655 
   1656     sal_usleep(1100);
   1657 
   1658 exit:
   1659     SOC_FUNC_RETURN;
   1660 }
   1661 
   1662 static int _xlport_mode_get(int unit, int phy_acc, int bindex, 
   1663                       portmod_core_port_mode_t *core_mode, int *cur_lanes)
   1664 {
   1665     uint32_t rval;
   1666 
   1667     SOC_INIT_FUNC_DEFS;
   1668 
   1669     /* Toggle link bit to notify IPIPE on link up */
   1670     _SOC_IF_ERR_EXIT(READ_XLPORT_MODE_REGr(unit, phy_acc, &rval));
   1671 
   1672     *core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, XPORT0_CORE_PORT_MODEf);
   1673 
   1674     switch (*core_mode) {
   1675         case portmodPortModeQuad:
   1676             *cur_lanes = 1;
   1677             break;
   1678 
   1679         case portmodPortModeTri012: 
   1680             *cur_lanes = (bindex == 2 ? 2 : 1);
   1681             break;
   1682 
   1683         case portmodPortModeTri023:
   1684             *cur_lanes = (bindex == 0 ? 2 : 1);
   1685             break;
   1686 
   1687         case portmodPortModeDual: 
   1688             *cur_lanes = 2;
   1689             break;
   1690 
   1691         case portmodPortModeSingle:
   1692             *cur_lanes = 4;
   1693             break;
   1694 
   1695         default:
   1696             return SOC_E_FAIL;
   1697     }
   1698 
   1699 exit:
   1700     SOC_FUNC_RETURN;
   1701 }
   1702 
   1703 static int _xlport_mode_set(int unit, int phy_acc, portmod_core_port_mode_t cur_mode)
   1704 {
   1705     uint32_t rval; 
   1706     int      mode;
   1707 
   1708     SOC_INIT_FUNC_DEFS;
   1709 
   1710     switch (cur_mode) {
   1711         case portmodPortModeQuad:
   1712             mode = 0;
   1713             break;
   1714 
   1715         case portmodPortModeTri012: 
   1716             mode = 1; 
   1717             break;
   1718 
   1719         case portmodPortModeTri023:
   1720             mode = 2; 
   1721             break;
   1722 
   1723         case portmodPortModeDual: 
   1724             mode = 3; 
   1725             break;
   1726 
   1727         case portmodPortModeSingle:
   1728             mode = 4; 
   1729             break;
   1730 
   1731         default:
   1732             return SOC_E_FAIL;
   1733     }
   1734 
   1735     /* Toggle link bit to notify IPIPE on link up */
   1736     _SOC_IF_ERR_EXIT(READ_XLPORT_MODE_REGr(unit, phy_acc, &rval));
   1737 
   1738     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, mode);
   1739     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, mode);
   1740 
   1741     _SOC_IF_ERR_EXIT(WRITE_XLPORT_MODE_REGr(unit, phy_acc, rval));
   1742 
   1743 exit:
   1744     SOC_FUNC_RETURN;
   1745 }
   1746 
   1747 int pm4x10_port_cntmaxsize_get(int unit, int port, pm_info_t pm_info, int *val)
   1748 {
   1749     int phy_acc;
   1750 
   1751     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1752 
   1753     return (READ_XLPORT_CNTMAXSIZEr(unit, phy_acc, (uint32_t *)val));
   1754 }
   1755 
   1756 int pm4x10_port_cntmaxsize_set(int unit, int port, pm_info_t pm_info, int val)
   1757 {
   1758     uint32 reg_val;
   1759     int phy_acc, rv = 0;
   1760 
   1761     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1762 
   1763     rv = READ_XLPORT_CNTMAXSIZEr(unit, phy_acc, &reg_val);
   1764     if (SOC_FAILURE(rv)) return (rv);
   1765 
   1766     soc_reg_field_set(unit, XLPORT_CNTMAXSIZEr, &reg_val, CNTMAXSIZEf, val);
   1767 
   1768     return(WRITE_XLPORT_CNTMAXSIZEr(unit, phy_acc, reg_val));
   1769 }
   1770 
   1771 int pm4x10_port_mib_reset_toggle(int unit, int port, pm_info_t pm_info, int port_index)
   1772 {
   1773     uint32 reg_val[1];
   1774     int    rv = 0, phy_acc;
   1775 
   1776     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1777 
   1778     rv = READ_XLPORT_MIB_RESETr(unit, phy_acc, reg_val);
   1779     if (SOC_FAILURE(rv)) return (rv);
   1780     SHR_BITSET(reg_val, port_index);
   1781 
   1782     rv = WRITE_XLPORT_MIB_RESETr(unit, phy_acc, *reg_val);
   1783     if (SOC_FAILURE(rv)) return (rv);
   1784     SHR_BITCLR(reg_val, port_index);
   1785 
   1786     return(WRITE_XLPORT_MIB_RESETr(unit, phy_acc, *reg_val));
   1787 }
   1788 int pm4x10_port_modid_set (int unit, int port, pm_info_t pm_info, int value)
   1789 {
   1790     uint32_t rval, modid;
   1791     int      flen, phy_acc;
   1792     SOC_INIT_FUNC_DEFS;
   1793 
   1794     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1795 
   1796     flen = soc_reg_field_length(unit, XLPORT_CONFIGr, MY_MODIDf)? value : 0;
   1797     modid =  (value < (1 <<  flen))? value : 0;
   1798 
   1799     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1800     soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, MY_MODIDf, modid);
   1801     _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, rval));
   1802 
   1803 exit:
   1804     SOC_FUNC_RETURN;
   1805 }
   1806 
   1807 int pm4x10_port_higig2_mode_set (int unit, int port, pm_info_t pm_info, int mode)
   1808 {
   1809     int phy_acc;
   1810     uint32_t rval;
   1811     SOC_INIT_FUNC_DEFS;
   1812 
   1813     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1814 
   1815     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1816     soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG2_MODEf, mode);
   1817     _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, rval));
   1818 
   1819 exit:
   1820     SOC_FUNC_RETURN;
   1821 }
   1822 
   1823 int pm4x10_port_higig_mode_set (int unit, int port, pm_info_t pm_info, int mode)
   1824 {
   1825     int phy_acc;
   1826     uint32_t rval;
   1827     SOC_INIT_FUNC_DEFS;
   1828 
   1829     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1830 
   1831     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1832     soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG_MODEf, mode);
   1833     _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, rval));
   1834 
   1835 exit:
   1836     SOC_FUNC_RETURN;
   1837 }
   1838 
   1839 int pm4x10_port_higig2_mode_get (int unit, int port, pm_info_t pm_info, int *mode)
   1840 {
   1841     int phy_acc;
   1842     uint32_t rval;
   1843     SOC_INIT_FUNC_DEFS;
   1844 
   1845     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1846 
   1847     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1848     *(mode) = soc_reg_field_get(unit, XLPORT_CONFIGr, rval, HIGIG2_MODEf);
   1849 
   1850 exit:
   1851     SOC_FUNC_RETURN;
   1852 }
   1853 
   1854 int pm4x10_port_higig_mode_get (int unit, int port, pm_info_t pm_info, int *mode)
   1855 {
   1856     int phy_acc;
   1857     uint32_t rval;
   1858     SOC_INIT_FUNC_DEFS;
   1859 
   1860     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1861 
   1862     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1863     *(mode) = soc_reg_field_get(unit, XLPORT_CONFIGr, rval, HIGIG_MODEf);
   1864 
   1865 exit:
   1866     SOC_FUNC_RETURN;
   1867 }
   1868 
   1869 int pm4x10_port_encap_set (int unit, int port, pm_info_t pm_info, 
   1870                                 int flags, portmod_encap_t encap)
   1871 {
   1872     return (xlmac_encap_set(unit, port, flags, encap));
   1873 
   1874 }
   1875 
   1876 int pm4x10_port_encap_get (int unit, int port, pm_info_t pm_info, 
   1877                             int *flags, portmod_encap_t *encap)
   1878 {
   1879     return (xlmac_encap_get(unit, port, flags, encap));
   1880 }
   1881 
   1882 int pm4x10_port_config_port_type_set (int unit, int port, pm_info_t pm_info, int type)
   1883 {
   1884     int phy_acc;
   1885     uint32_t rval;
   1886     SOC_INIT_FUNC_DEFS;
   1887 
   1888     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1889 
   1890     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1891     soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, PORT_TYPEf, type);
   1892     _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, rval));
   1893 
   1894 exit:
   1895     SOC_FUNC_RETURN;
   1896 }
   1897 
   1898 int pm4x10_port_config_port_type_get (int unit, int port, pm_info_t pm_info, int *type)
   1899 {
   1900     int phy_acc;
   1901     uint32_t rval;
   1902     SOC_INIT_FUNC_DEFS;
   1903 
   1904     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   1905 
   1906     _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &rval));
   1907     *(type) = soc_reg_field_get(unit, XLPORT_CONFIGr, rval, PORT_TYPEf);
   1908 
   1909 exit:
   1910     SOC_FUNC_RETURN;
   1911 }
   1912 
   1913 int pm4x10_port_led_chain_config (int unit, int port, pm_info_t pm_info, 
   1914                           int value)
   1915 {
   1916     SOC_INIT_FUNC_DEFS;
   1917 
   1918     _SOC_IF_ERR_EXIT(WRITE_XLPORT_LED_CHAIN_CONFIGr (unit, port, value));
   1919 
   1920 exit:
   1921     SOC_FUNC_RETURN;
   1922 }
   1923 
   1924 typedef enum xlmac_port_mode_e{
   1925     XLMAC_4_LANES_SEPARATE  = 0,
   1926     XLMAC_3_TRI_0_1_2_2     = 1,
   1927     XLMAC_3_TRI_0_0_2_3     = 2,
   1928     XLMAC_2_LANES_DUAL      = 3,
   1929     XLMAC_4_LANES_TOGETHER  = 4
   1930 } xlmac_port_mode_t;
   1931 
   1932 STATIC
   1933 int _pm4x10_port_tricore_lane_info_get(int unit, int port, pm_info_t pm_info,
   1934                                        int *start_lane, int* end_lane, 
   1935                                        int *line_start_lane, int* line_end_lane, 
   1936                                        uint32 *int_core_lane_mask, 
   1937                                        const portmod_access_get_params_t* params)
   1938 {
   1939     uint32  iphy_lane_mask, interface_modes = 0;
   1940     int port_index=0;
   1941     int core_num_int;
   1942     int data_rate;
   1943     int phyn = 0;
   1944     uint32 xphy_id = 0;
   1945     phymod_core_access_t core_access;
   1946     int is_legacy_phy;
   1947     SOC_INIT_FUNC_DEFS;
   1948 
   1949     /* get port index and lane mask */
   1950     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &port_index,
   1951                                             &iphy_lane_mask));
   1952 
   1953     *start_lane  = 0;
   1954     *end_lane    = PM4X10_LANES_PER_CORE-1;
   1955     *int_core_lane_mask = 0x0F;
   1956 
   1957     *line_start_lane = 0;
   1958     *line_end_lane = PM4X10_LANES_PER_CORE-1;
   1959 
   1960     core_num_int = PM_4x10_INFO(pm_info)->core_num_int;
   1961                                   
   1962     _SOC_IF_ERR_EXIT(PM4x10_INTERFACE_MODES_GET(unit, pm_info,
   1963                                                 &interface_modes,
   1964                                                 port_index));
   1965 
   1966     if(interface_modes & PHYMOD_INTF_MODES_TRIPLE_CORE) {
   1967        _SOC_IF_ERR_EXIT(PM4x10_SPEED_GET(unit, pm_info,
   1968                                          &data_rate,
   1969                                          port_index));
   1970 
   1971         /* first check if 120G or 127G */
   1972         if (data_rate >= 120000) {
   1973             if(core_num_int == 0){
   1974                 *start_lane  = 0;
   1975                 *end_lane    = PM4X10_LANES_PER_CORE-1;
   1976                 *int_core_lane_mask = 0x0F;
   1977                 *line_start_lane = -1;
   1978                 *line_end_lane = -1;
   1979              } else if (core_num_int == 1) {
   1980                 *start_lane  = 4;
   1981                 *end_lane    = 7;
   1982                 *line_start_lane = 0;
   1983                 *line_end_lane = PM4X10_LANES_PER_CORE-1;
   1984                 *int_core_lane_mask = 0x0F;
   1985             } else if (core_num_int == 2) {
   1986                 *start_lane     = 8;
   1987                 *end_lane       = 11;
   1988                 *int_core_lane_mask = 0x0F;
   1989                 *line_start_lane = -1;
   1990                 *line_end_lane = -1;
   1991             }
   1992 
   1993         } else {
   1994             if(core_num_int == 0){
   1995                 if (interface_modes & PHYMOD_INTF_MODES_TC_244){
   1996                     *start_lane     = 0  ;
   1997                     *end_lane       = 1  ;
   1998                     *int_core_lane_mask = 0x03;
   1999                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_343){
   2000                     *start_lane     = 0  ;  
   2001                     *end_lane       = 2  ;
   2002                     *int_core_lane_mask = 0x07;
   2003                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_442){
   2004                     *start_lane  = 0;
   2005                     *end_lane    = PM4X10_LANES_PER_CORE-1;
   2006                     *int_core_lane_mask = 0x0F;
   2007                 }
   2008                 *line_start_lane = -1;
   2009                 *line_end_lane = -1;
   2010 
   2011             } else if (core_num_int == 1) {
   2012                 if (interface_modes & PHYMOD_INTF_MODES_TC_244){
   2013                     *start_lane     = 2  ;  
   2014                     *end_lane       = 5  ;
   2015                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_343){
   2016                     *start_lane     = 3  ;
   2017                     *end_lane       = 6  ;
   2018                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_442){
   2019                     *start_lane  = 4;
   2020                     *end_lane    = 7;
   2021                 }
   2022                 *line_start_lane = 0;
   2023                 *line_end_lane = PM4X10_LANES_PER_CORE-1;
   2024                 *int_core_lane_mask = 0x0F;
   2025             } else if (core_num_int == 2) {
   2026                 if (interface_modes & PHYMOD_INTF_MODES_TC_244){
   2027                     *start_lane     = 6  ;  
   2028                     *end_lane       = 9  ;
   2029                     *int_core_lane_mask = 0x0F;
   2030                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_343){
   2031                     *start_lane     = 7  ;
   2032                     *end_lane       = 9  ;
   2033                     *int_core_lane_mask = 0x07;
   2034                 } else if (interface_modes & PHYMOD_INTF_MODES_TC_442){
   2035                     *start_lane  = 8;
   2036                     *end_lane    = 9;
   2037                     *int_core_lane_mask = 0x03;
   2038                 }
   2039                 *line_start_lane = -1;
   2040                 *line_end_lane = -1;
   2041             }
   2042             if ( params != NULL ) {
   2043                 phyn = params->phyn;
   2044 
   2045                 /* if phyn is -1, it is looking for outer most phy.
   2046                    assumption is that all lane has same phy depth. */
   2047                 if(phyn < 0) {
   2048                     phyn = PM_4x10_INFO(pm_info)->nof_phys[port_index] - 1;
   2049                 }
   2050 
   2051                 if (phyn > 0) {
   2052                     xphy_id = PM_4x10_INFO(pm_info)->lane_conn[phyn-1][0].xphy_id;
   2053                     _SOC_IF_ERR_EXIT ( portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   2054                     if (core_access.device_op_mode != PHYMOD_INTF_CONFIG_PHY_GEARBOX_ENABLE) {
   2055                         *line_start_lane = *start_lane;
   2056                         *line_end_lane = *end_lane;
   2057                     }
   2058                 }
   2059             }
   2060         }
   2061     }
   2062 exit:
   2063     SOC_FUNC_RETURN;
   2064 }
   2065 
   2066 int pm4x10_port_phy_lane_access_get(int unit, int port, pm_info_t pm_info,
   2067                                      const portmod_access_get_params_t* params,
   2068                                      int max_phys,
   2069                                      phymod_phy_access_t* phy_access,
   2070                                      int* nof_phys, int* is_most_ext)
   2071 {
   2072     int phyn = 0, rv;
   2073     uint32  iphy_lane_mask; 
   2074     int port_index=0;
   2075     int serdes_lane=-1;
   2076     int xphy_lane_mask=0;
   2077     uint32 xphy_id = 0;
   2078     uint32 lane_mask[MAX_NUM_CORES];
   2079     phymod_port_loc_t port_loc[MAX_NUM_CORES];
   2080     int i, is_legacy_phy;
   2081     uint32 xphy_idx;
   2082     uint32 pm_is_bypassed = 0;
   2083     int num_of_phys;
   2084     int done;
   2085     int sys_start_lane=0;
   2086     int sys_end_lane=0;
   2087     int line_start_lane=0;
   2088     int line_end_lane=0;
   2089     int start_lane = 0;
   2090     int end_lane = 0;
   2091     uint32 int_lane_mask = 0xf;
   2092     phymod_core_access_t core_access;
   2093 
   2094 
   2095     SOC_INIT_FUNC_DEFS;
   2096 
   2097     start_lane  = 0;
   2098     end_lane    = PM4X10_LANES_PER_CORE-1;
   2099 
   2100     if(max_phys > MAX_NUM_CORES)
   2101     {
   2102         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2103                (_SOC_MSG("max_phys parameter exceeded the MAX value. max_phys=%d, max allowed %d."),
   2104                        max_phys, MAX_NUM_CORES));
   2105     }
   2106 
   2107     /* get port index and lane mask */
   2108     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &port_index,
   2109                                             &iphy_lane_mask));
   2110 
   2111     _SOC_IF_ERR_EXIT(_pm4x10_port_tricore_lane_info_get(unit, port, pm_info,
   2112                                                         &sys_start_lane, &sys_end_lane,
   2113                                                         &line_start_lane, &line_end_lane,
   2114                                                         &int_lane_mask, params));
   2115 
   2116     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &pm_is_bypassed);
   2117     _SOC_IF_ERR_EXIT(rv);
   2118 
   2119     if(!params->apply_lane_mask){
   2120         int_lane_mask = 0xF;
   2121     }
   2122 
   2123     if(params->phyn >= PM_4x10_INFO(pm_info)->nof_phys[port_index]){
   2124         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2125                (_SOC_MSG("phyn exceeded. max allowed %d. got %d"),
   2126                PM_4x10_INFO(pm_info)->nof_phys[port_index] - 1, params->phyn));
   2127     }
   2128 
   2129 
   2130     for( i = 0 ; i < max_phys; i++) {
   2131         lane_mask[i] = 0;
   2132         _SOC_IF_ERR_EXIT(phymod_phy_access_t_init(&phy_access[i]));
   2133     }
   2134 
   2135     phyn = params->phyn;
   2136 
   2137     /* if phyn is -1, it is looking for outer most phy.
   2138        assumption is that all lane has same phy depth. */
   2139     if(phyn < 0) {
   2140         phyn = PM_4x10_INFO(pm_info)->nof_phys[port_index] - 1;
   2141     }
   2142 
   2143     if( phyn == 0 ) {
   2144         /* internal core */
   2145         sal_memcpy (&phy_access[0], &(PM_4x10_INFO(pm_info)->int_core_access),
   2146                     sizeof(phymod_phy_access_t));
   2147         phy_access[0].access.lane_mask = iphy_lane_mask;
   2148         if (params->lane != -1) {
   2149 
   2150             start_lane  = sys_start_lane;
   2151             end_lane    = sys_end_lane;
   2152 
   2153             if((params->lane >= start_lane) && (params->lane <= end_lane)) { 
   2154                 serdes_lane = port_index + params->lane-start_lane;
   2155                 phy_access[0].access.lane_mask &= (0x1 << serdes_lane );
   2156                 *nof_phys = 1;
   2157             } else {
   2158                 phy_access[0].access.lane_mask &= 0; 
   2159                 *nof_phys = 0;
   2160             }
   2161         } else {
   2162             *nof_phys = 1;
   2163             phy_access[0].access.lane_mask &= int_lane_mask;
   2164         }
   2165         phy_access[0].port_loc = phymodPortLocLine; /* only line is availabe for internal. */
   2166 
   2167         /* PCS bypass flag is set when the underlying device is DNX */
   2168         if ((pm_is_bypassed) && (!PM_4x10_INFO(pm_info)->in_pm12x10)) {
   2169             PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_SET(phy_access[0].device_op_mode);
   2170         }
   2171 
   2172         /* if it is warm boot, get probed information from wb db instead of re-probing. */
   2173         if(SOC_WARM_BOOT(unit)) {
   2174             rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phy_type], &(phy_access[0].type));
   2175             _SOC_IF_ERR_EXIT(rv);
   2176         }
   2177     } else {
   2178 
   2179         /* external phy */
   2180         num_of_phys = 0;
   2181 
   2182         /* xphy idx is 1 less than phyn since internal core does not count */    
   2183         xphy_idx = phyn-1;
   2184     
   2185         if (params->lane != -1){ /* specific lane */
   2186 
   2187             if(params->sys_side == PORTMOD_SIDE_SYSTEM){
   2188                 start_lane = sys_start_lane;
   2189                 end_lane    = sys_end_lane;
   2190             } else { /* PORTMOD_SIDE_LINE */
   2191                 start_lane = line_start_lane;
   2192                 end_lane    = line_end_lane;
   2193             }
   2194 
   2195             if((params->lane >= start_lane) && (params->lane <= end_lane)) { 
   2196                 serdes_lane = port_index + params->lane-start_lane;
   2197             } else {
   2198                 serdes_lane = -1; /* no matching lane in this core. */
   2199                 *nof_phys = 0;
   2200             }
   2201             if( serdes_lane != -1){    
   2202                 xphy_id = PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].xphy_id;
   2203 
   2204                 if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   2205                     _SOC_IF_ERR_EXIT ( portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   2206                     sal_memcpy (&phy_access[num_of_phys], &core_access,
   2207                                 sizeof(phymod_phy_access_t));
   2208                     xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)? PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   2209                                   PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   2210                     if( xphy_lane_mask != -1 ){
   2211                         phy_access[0].access.lane_mask = xphy_lane_mask;
   2212                     }
   2213                     phy_access[0].port_loc = ( params->sys_side == PORTMOD_SIDE_SYSTEM) ?
   2214                                                phymodPortLocSys : phymodPortLocLine;
   2215                     *nof_phys = 1;
   2216                 }
   2217             }
   2218         } else { /* all lanes */
   2219             /* go thru all the lanes related to this port. */
   2220             serdes_lane = 0;
   2221 
   2222             for (serdes_lane = 0; serdes_lane < MAX_PORTS_PER_PM4X10; serdes_lane++) {
   2223                 if (iphy_lane_mask & (1U<<serdes_lane)) {
   2224                     xphy_id = PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].xphy_id;
   2225                     if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   2226                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   2227                         if(num_of_phys == 0 ) {/* first one */
   2228                             sal_memcpy (&phy_access[num_of_phys], &core_access,
   2229                                         sizeof(phymod_phy_access_t));
   2230                             xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   2231                                         PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   2232                                         PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   2233                             if( xphy_lane_mask != -1) {
   2234                                 lane_mask[num_of_phys] |= xphy_lane_mask;
   2235                             }
   2236                                 port_loc[num_of_phys] = ( params->sys_side == PORTMOD_SIDE_SYSTEM) ? 
   2237                                                                 phymodPortLocSys : phymodPortLocLine;
   2238                                 num_of_phys++;
   2239                         } else {
   2240                             /* if not the first one, see if this one sharing core with other 
   2241                                lanes.  */
   2242                             done = 0;
   2243 
   2244                             /* Skip if the lane is used by an inactive port marked with :i in the config
   2245                              *  * property.
   2246                              */
   2247                             if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port+serdes_lane)){
   2248                                 continue;
   2249                             }
   2250 
   2251                             for( i = 0 ; (i < num_of_phys) &&(!done) ; i++) {
   2252                                  if((!sal_memcmp (&phy_access[i], &core_access,
   2253                                                    sizeof(phymod_phy_access_t)))) { /* found a match */
   2254                                     /* update lane */
   2255                                     xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   2256                                                 PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   2257                                                 PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   2258                                     if( xphy_lane_mask != -1) {
   2259                                         lane_mask[i] |= xphy_lane_mask;
   2260                                     }
   2261                                     done = 1;
   2262                                 }
   2263                             }
   2264                             if((!done) && (num_of_phys < max_phys)){
   2265                                 sal_memcpy (&phy_access[num_of_phys], &core_access,
   2266                                 sizeof(phymod_phy_access_t));
   2267                                 xphy_lane_mask = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   2268                                             PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ss_lane_mask:
   2269                                             PM_4x10_INFO(pm_info)->lane_conn[xphy_idx][serdes_lane].ls_lane_mask;
   2270                                 if( xphy_lane_mask != -1) {
   2271                                     lane_mask[num_of_phys] = xphy_lane_mask;
   2272                                 }
   2273                                     port_loc[num_of_phys] = ( params->sys_side == PORTMOD_SIDE_SYSTEM)?
   2274                                                                     phymodPortLocSys : phymodPortLocLine ;
   2275                                     num_of_phys++;
   2276                             } 
   2277                         }
   2278                     }
   2279                 }
   2280             }
   2281             *nof_phys = num_of_phys;
   2282             for( i = 0 ; (i < *nof_phys) ; i++) {
   2283                 phy_access[i].access.lane_mask = lane_mask[i];
   2284                 phy_access[i].port_loc = port_loc[i];
   2285             }
   2286         }
   2287     } /* ext phys */ 
   2288        
   2289     /* assumption is that all logical port have same phy depths, that 
   2290        will not true when simplex introduced , until then we can keep 
   2291        this code. */
   2292     if (is_most_ext) {
   2293         if (phyn == PM_4x10_INFO(pm_info)->nof_phys[port_index]-1) {
   2294             *is_most_ext = 1;
   2295         } else {
   2296             *is_most_ext = 0;
   2297         }
   2298     }
   2299  
   2300 exit:
   2301     SOC_FUNC_RETURN;
   2302 }
   2303 
   2304 int pm4x10_port_mac_rsv_mask_set(int unit, int port, pm_info_t pm_info, uint32 rsv_mask)
   2305 {
   2306         return(WRITE_XLPORT_MAC_RSV_MASKr(unit, port, rsv_mask)); 
   2307 }
   2308 
   2309 STATIC
   2310 int _pm4x10_pm_port_init(int unit, int port, int phy_acc, int internal_port,
   2311                          const portmod_port_add_info_t* add_info, int enable, pm_info_t pm_info)
   2312 {
   2313     int rv;
   2314     uint32 reg_val, flags;
   2315     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   2316     uint32 rsv_mask;
   2317     SOC_INIT_FUNC_DEFS;
   2318 
   2319     if(enable) {
   2320         /* RSV Mask */
   2321         rsv_mask = 0;
   2322         SHR_BITSET(&rsv_mask, 3); /* Receive terminate/code error */
   2323         SHR_BITSET(&rsv_mask, 4); /* CRC error */
   2324         SHR_BITSET(&rsv_mask, 6); /* PGW_MACTruncated/Frame out of Range */
   2325         SHR_BITSET(&rsv_mask, 17); /* RUNT detected*/
   2326 
   2327          rv = __portmod__dispatch__[pm_info->type]->f_portmod_port_mac_rsv_mask_set(unit, port, pm_info, rsv_mask);
   2328         _SOC_IF_ERR_EXIT(rv);
   2329 
   2330 
   2331         /* Soft reset */
   2332         _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   2333         soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, 
   2334                                   port_fields[internal_port], 1);
   2335         _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2336 
   2337         soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, 
   2338                                   port_fields[internal_port], 0);
   2339         _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2340 
   2341         
   2342         /* Port enable */
   2343         _SOC_IF_ERR_EXIT(READ_XLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   2344         soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &reg_val, 
   2345                                    port_fields[internal_port], 1);
   2346         _SOC_IF_ERR_EXIT(WRITE_XLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   2347 
   2348         /* Init MAC */
   2349         flags = 0;
   2350         if(PORTMOD_PORT_ADD_F_RX_SRIP_CRC_GET(add_info)) {
   2351             flags |= XLMAC_INIT_F_RX_STRIP_CRC;
   2352         }
   2353 
   2354         if(PORTMOD_PORT_ADD_F_TX_APPEND_CRC_GET(add_info)) {
   2355             flags |= XLMAC_INIT_F_TX_APPEND_CRC;
   2356         }
   2357 
   2358         if(PORTMOD_PORT_ADD_F_TX_REPLACE_CRC_GET(add_info)) {
   2359             flags |= XLMAC_INIT_F_TX_REPLACE_CRC;
   2360         }
   2361 
   2362         if(PORTMOD_PORT_ADD_F_TX_PASS_THROUGH_CRC_GET(add_info)) {
   2363             flags |= XLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE;
   2364         }
   2365 
   2366         if (IS_HG_PORT(unit,port)){
   2367             flags |= XLMAC_INIT_F_IPG_CHECK_DISABLE;
   2368         } else {
   2369             flags &= ~XLMAC_INIT_F_IPG_CHECK_DISABLE;
   2370         }
   2371 
   2372         if(PHYMOD_INTF_MODES_HIGIG_GET(&(add_info->interface_config))) {
   2373             flags |= XLMAC_INIT_F_IS_HIGIG;
   2374         }
   2375         rv = xlmac_init(unit, port, flags);
   2376         _SOC_IF_ERR_EXIT(rv);
   2377 
   2378         /* LSS */
   2379         _SOC_IF_ERR_EXIT(READ_XLPORT_FAULT_LINK_STATUSr(unit, phy_acc, &reg_val));
   2380         soc_reg_field_set(unit, XLPORT_FAULT_LINK_STATUSr, &reg_val,
   2381                           REMOTE_FAULTf, 1);
   2382         soc_reg_field_set(unit, XLPORT_FAULT_LINK_STATUSr, &reg_val,
   2383                           LOCAL_FAULTf, 1);
   2384         _SOC_IF_ERR_EXIT(WRITE_XLPORT_FAULT_LINK_STATUSr(unit, phy_acc, reg_val)); 
   2385 
   2386         /* Counter MAX size */
   2387         rv = __portmod__dispatch__[pm_info->type]->f_portmod_port_cntmaxsize_set(unit, port, pm_info, 1518);
   2388        _SOC_IF_ERR_EXIT(rv);
   2389  
   2390         /* Reset MIB counters */
   2391         rv = __portmod__dispatch__[pm_info->type]->f_portmod_port_mib_reset_toggle(unit, port, pm_info, internal_port);
   2392        _SOC_IF_ERR_EXIT(rv);
   2393 
   2394     } else {
   2395         /* Port disable */
   2396         _SOC_IF_ERR_EXIT(READ_XLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   2397         soc_reg_field_set (unit, XLPORT_ENABLE_REGr, &reg_val, 
   2398                            port_fields[internal_port], 0);
   2399         _SOC_IF_ERR_EXIT(WRITE_XLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   2400 
   2401          /* Soft reset */
   2402         _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   2403         soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, 
   2404                           port_fields[internal_port], 1);
   2405         _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   2406     }
   2407 
   2408 exit:
   2409     SOC_FUNC_RETURN;
   2410 }
   2411 
   2412 STATIC
   2413 int _pm4x10_ext_phy_interface_check(int unit, int port, phymod_phy_access_t *phy_acc,
   2414                                const portmod_port_interface_config_t *interface_config,
   2415                                soc_port_if_t interface, int *is_valid)
   2416 {
   2417     int rv = 0;
   2418     int num_lanes = 0, data_rate = 0;
   2419     uint32_t interface_mode = 0;
   2420     phymod_interface_t  phymod_intf;
   2421     int is_legacy_phy = 0, xphy_id;
   2422     SOC_INIT_FUNC_DEFS;
   2423 
   2424     num_lanes      = interface_config->port_num_lanes;
   2425     interface_mode = interface_config->interface_modes;
   2426     data_rate      = interface_config->speed;
   2427 
   2428     xphy_id = phy_acc->access.addr;
   2429     _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   2430 
   2431     if (is_legacy_phy) {
   2432         /* if its a legacy PHY let the PHY driver decide the valid interface types */
   2433         *is_valid = 1;
   2434         rv = SOC_E_NONE;
   2435         SOC_EXIT;
   2436     }
   2437 
   2438     /* convert portmod interface to phymod interface */
   2439     rv = portmod_intf_to_phymod_intf(unit, data_rate, interface, &phymod_intf);
   2440     _SOC_IF_ERR_EXIT(rv); 
   2441 
   2442     rv = portmod_port_line_interface_is_valid(unit, phy_acc, port, data_rate, phymod_intf,
   2443                                             num_lanes, interface_mode, is_valid);
   2444     _SOC_IF_ERR_EXIT(rv);  
   2445   
   2446     if (!*is_valid) {
   2447         LOG_ERROR(BSL_LS_BCM_PORT,
   2448               (BSL_META_UP(unit, port,
   2449                "ERROR: u=%d p=%d interface type %d not supported by external PHY for this speed %d \n"),
   2450                unit, port, interface, data_rate));
   2451         rv = SOC_E_PARAM;
   2452         _SOC_IF_ERR_EXIT(rv); 
   2453     }
   2454 
   2455 exit:
   2456     SOC_FUNC_RETURN;
   2457 }
   2458 
   2459 STATIC
   2460 int _pm4x10_interface_check(int unit, int port, pm_info_t pm_info,
   2461                             const portmod_port_interface_config_t *interface_config,
   2462                             soc_port_if_t interface, int *is_valid)
   2463 {
   2464     int is_higig;
   2465     int num_lanes;
   2466 
   2467     *is_valid = 0;
   2468     num_lanes = interface_config->port_num_lanes;
   2469     is_higig = ((interface_config->encap_mode == SOC_ENCAP_HIGIG2) ||
   2470                  (interface_config->encap_mode == SOC_ENCAP_HIGIG) ||
   2471                  PHYMOD_INTF_MODES_HIGIG_GET(interface_config)) ? 1 : 0;
   2472 
   2473     if (SOC_PORT_IF_ILKN == interface) {
   2474         *is_valid = 1;
   2475         return SOC_E_NONE;
   2476     }
   2477 
   2478     switch (interface_config->speed) {
   2479         case 0:
   2480             /* When AN=1 the input speed to portmod may be 0. At
   2481              * this moment the speed is still undecided so there
   2482              * is no reason to invalidate the interface type.
   2483              */
   2484             *is_valid = 1;
   2485             break;
   2486         case 10:
   2487             if (num_lanes == 1) {
   2488                 if ((SOC_PORT_IF_SGMII == interface) ||
   2489                     (SOC_PORT_IF_GMII == interface)) {
   2490                     *is_valid = 1;
   2491                 }
   2492             }
   2493             break;
   2494         case 100:
   2495             if (num_lanes == 1) {
   2496                 if ((SOC_PORT_IF_SGMII == interface) ||
   2497                     (SOC_PORT_IF_GMII == interface)) {
   2498                     *is_valid = 1;
   2499                 }
   2500             }
   2501             break;
   2502         case 1000:
   2503             if (num_lanes == 1) {
   2504                 if ((SOC_PORT_IF_SGMII == interface) ||
   2505                     (SOC_PORT_IF_GMII == interface) ||
   2506                     (SOC_PORT_IF_KX == interface) ||
   2507                     (SOC_PORT_IF_CX == interface) ||
   2508                     ((SOC_PORT_IF_QSGMII == interface) &&
   2509                     (PM_4x10_INFO(pm_info)->is_pm4x10q))) {
   2510                     *is_valid = 1;
   2511                 }
   2512             }
   2513             break;
   2514         case 2500:
   2515             if (num_lanes == 1) {
   2516                 if ((SOC_PORT_IF_SGMII == interface) ||
   2517                     (SOC_PORT_IF_GMII == interface)) {
   2518                     *is_valid = 1;
   2519                 }
   2520             }
   2521             break;
   2522         case 5000:
   2523             if (num_lanes == 1) {
   2524                 if ((SOC_PORT_IF_XFI == interface) ||
   2525                     (SOC_PORT_IF_KR == interface) ||
   2526                     (SOC_PORT_IF_GMII == interface)) {
   2527                     *is_valid = 1;
   2528                 }
   2529             } else if (num_lanes == 2) {
   2530                 if (SOC_PORT_IF_RXAUI == interface) {
   2531                     *is_valid = 1;
   2532                 }
   2533             }
   2534             break;
   2535         case 10000:
   2536         case 11000:
   2537             if (is_higig) {
   2538                 if (num_lanes == 1) {
   2539                     if ((SOC_PORT_IF_XFI == interface) ||
   2540                         (SOC_PORT_IF_SFI == interface) ||
   2541                         (SOC_PORT_IF_KR == interface) ||
   2542                         (SOC_PORT_IF_CR == interface) ||
   2543                         (SOC_PORT_IF_SR == interface)) {
   2544                         *is_valid = 1;
   2545                     }
   2546                 } else if (num_lanes == 2) {
   2547                     if (SOC_PORT_IF_RXAUI == interface) {
   2548                         *is_valid = 1;
   2549                     }
   2550                 } else if (num_lanes == 4) {
   2551                     if ((SOC_PORT_IF_XGMII == interface) ||
   2552                         (SOC_PORT_IF_XLAUI == interface)) {
   2553                         *is_valid = 1;
   2554                     }
   2555                 }
   2556             } else {
   2557                 if (num_lanes == 1) {
   2558                     if ((SOC_PORT_IF_SFI == interface) ||
   2559                         (SOC_PORT_IF_XFI == interface) ||
   2560                         (SOC_PORT_IF_KR == interface) ||
   2561                         (SOC_PORT_IF_CR == interface) ||
   2562                         (SOC_PORT_IF_SR == interface) ||
   2563                         (SOC_PORT_IF_LR == interface) ||
   2564                         (SOC_PORT_IF_ER == interface) ||
   2565                         (SOC_PORT_IF_CX == interface) ||
   2566                         (SOC_PORT_IF_LRM == interface)) {
   2567                         *is_valid = 1;
   2568                     }
   2569                 } else if (num_lanes == 2) {
   2570                     if (SOC_PORT_IF_RXAUI == interface) {
   2571                         *is_valid = 1;
   2572                     }
   2573                 } else if (num_lanes == 4) {
   2574                     if ((SOC_PORT_IF_XGMII == interface) ||
   2575                         (SOC_PORT_IF_XLAUI == interface) ||
   2576                         (SOC_PORT_IF_DNX_XAUI == interface) ||
   2577                         (SOC_PORT_IF_XAUI == interface) ||
   2578                         (SOC_PORT_IF_SFI == interface) ||
   2579                         (SOC_PORT_IF_XFI == interface) ||
   2580                         (SOC_PORT_IF_QSGMII == interface)) {
   2581                         *is_valid = 1;
   2582                     }
   2583                 }
   2584             }
   2585             break;
   2586         case 3125:
   2587         case 5750:
   2588         case 6250:
   2589         case 8125:
   2590         case 8500:
   2591         case 10312:
   2592         case 10937:
   2593         case 11250:
   2594             if (SOC_PORT_IF_ILKN == interface) {
   2595                 /*
   2596                  * COVERITY
   2597                  * It is kept intentionally as a defensive check.
   2598                  */
   2599                 /* coverity[dead_error_line] */
   2600                 *is_valid = 1;
   2601             }
   2602             break;
   2603         case 10500:
   2604         case 12500:
   2605             break;
   2606         case 11500:
   2607             if (num_lanes == 1) {
   2608                 if (SOC_PORT_IF_XFI == interface) {
   2609                     *is_valid = 1;
   2610                 }
   2611             }
   2612             break;
   2613         case 12000:
   2614             if ((num_lanes == 4) &&
   2615                 (SOC_PORT_IF_XGMII == interface)) {
   2616                 *is_valid = 1;
   2617             } else if ((num_lanes == 2) &&
   2618                 (SOC_PORT_IF_RXAUI == interface)) {
   2619                 *is_valid = 1;
   2620             } else if ((num_lanes == 1) &&
   2621                 ((SOC_PORT_IF_XFI == interface) ||
   2622                  (SOC_PORT_IF_SFI == interface) ||
   2623                  (SOC_PORT_IF_SR == interface) ||
   2624                  (SOC_PORT_IF_LR == interface) ||
   2625                  (SOC_PORT_IF_CR == interface) ||
   2626                  (SOC_PORT_IF_KR == interface))) {
   2627                 *is_valid = 1;
   2628             }
   2629             break;
   2630         case 12773:   /*  12733Mbps */
   2631             if (num_lanes == 2) {
   2632                 if (SOC_PORT_IF_RXAUI == interface) {
   2633                     *is_valid = 1;
   2634                 }
   2635             }
   2636             break;
   2637         case 13000:
   2638             if ((num_lanes == 4) &&
   2639                 (SOC_PORT_IF_XGMII == interface)) {
   2640                 *is_valid = 1;
   2641             } else if ((num_lanes == 2) &&
   2642                 (SOC_PORT_IF_RXAUI == interface)) {
   2643                 *is_valid = 1;
   2644             }
   2645             break;
   2646         case 15000:
   2647             if ((num_lanes == 4) &&
   2648                 (SOC_PORT_IF_XGMII == interface)) {
   2649                 *is_valid = 1;
   2650             } else if ((num_lanes == 2) &&
   2651                 (SOC_PORT_IF_RXAUI == interface)) {
   2652                 *is_valid = 1;
   2653             }
   2654             break;
   2655         case 15750:
   2656         case 16000:  /* setting RX66_CONTROL_CC_EN/CC_DATA_SEL failed this 16000 HI_DXGXS mode */
   2657             if ((num_lanes == 4) &&
   2658                 (SOC_PORT_IF_XGMII == interface)) {
   2659                 *is_valid = 1;
   2660             } else if ((num_lanes == 2) &&
   2661                 (SOC_PORT_IF_RXAUI == interface)) {
   2662                 *is_valid = 1;
   2663             }
   2664             break;
   2665         case 20000:
   2666         case 21000:
   2667             if (is_higig) {
   2668                 if (num_lanes == 2) {
   2669                     if ((SOC_PORT_IF_KR2 == interface) ||
   2670                         (SOC_PORT_IF_CR2 == interface) ||
   2671                         (SOC_PORT_IF_RXAUI == interface)) {
   2672                         *is_valid = 1;
   2673                     }
   2674                 } else if (num_lanes == 4) {
   2675                     if (SOC_PORT_IF_XGMII == interface) {
   2676                         *is_valid = 1;
   2677                     }
   2678                 }
   2679             } else {
   2680                 if (num_lanes == 2) {
   2681                     if ((SOC_PORT_IF_KR2 == interface) ||
   2682                         (SOC_PORT_IF_CR2 == interface) ||
   2683                         (SOC_PORT_IF_RXAUI == interface)) {
   2684                         *is_valid = 1;
   2685                     }
   2686                 } else if (num_lanes == 4) {
   2687                     if ((SOC_PORT_IF_XGMII == interface) ||
   2688                         (SOC_PORT_IF_SR4 == interface) ||
   2689                         (SOC_PORT_IF_CR4 == interface) ||
   2690                         (SOC_PORT_IF_KR4 == interface) ||
   2691                         (SOC_PORT_IF_DNX_XAUI == interface)) {
   2692                         *is_valid = 1;
   2693                     }
   2694                 }
   2695             }
   2696             break;
   2697         case 23000:
   2698             if (num_lanes == 2) {
   2699                 if (SOC_PORT_IF_RXAUI == interface) {
   2700                     *is_valid = 1;
   2701                 }
   2702             }
   2703             break;
   2704         case 25000:
   2705         case 25450:
   2706         case 25455:
   2707         case 30000:
   2708         case 31500:
   2709             if (num_lanes == 4) {
   2710                 if ((SOC_PORT_IF_XGMII == interface) ||
   2711                     (SOC_PORT_IF_KR4 == interface)) {
   2712                     *is_valid = 1;
   2713                 }
   2714             } else if (num_lanes == 2) {
   2715                 if (SOC_PORT_IF_KR2 == interface) {
   2716                     *is_valid = 1;
   2717                 }
   2718             } else {
   2719                 if (SOC_PORT_IF_KR == interface) {
   2720                     *is_valid = 1;
   2721                 }
   2722             }
   2723             break;
   2724         case 40000:
   2725             if (is_higig) {
   2726                 if (num_lanes == 4) {
   2727                     if ((SOC_PORT_IF_KR4 == interface) ||
   2728                         (SOC_PORT_IF_CR4 == interface) ||
   2729                         (SOC_PORT_IF_SR4 == interface) ||
   2730                         (SOC_PORT_IF_LR4 == interface) ||
   2731                         (SOC_PORT_IF_ER4 == interface) ||
   2732                         (SOC_PORT_IF_XGMII == interface)) {
   2733                         *is_valid = 1;
   2734                     }
   2735                 }
   2736             } else {
   2737                 if (num_lanes == 4) {
   2738                     if ((SOC_PORT_IF_KR4 == interface) ||
   2739                         (SOC_PORT_IF_CR4 == interface) ||
   2740                         (SOC_PORT_IF_SR4 == interface) ||
   2741                         (SOC_PORT_IF_LR4 == interface) ||
   2742                         (SOC_PORT_IF_ER4 == interface) ||
   2743                         (SOC_PORT_IF_XLAUI == interface) ||
   2744                         (SOC_PORT_IF_XLPPI == interface)) {
   2745                         *is_valid = 1;
   2746                     }
   2747                 }
   2748             }
   2749             break;
   2750         case 42000:
   2751             if (is_higig) {
   2752                 if (num_lanes == 4) {
   2753                     if ((SOC_PORT_IF_KR4 == interface) ||
   2754                         (SOC_PORT_IF_CR4 == interface) ||
   2755                         (SOC_PORT_IF_XLAUI == interface) ||
   2756                         (SOC_PORT_IF_SR4 == interface) ||
   2757                         (SOC_PORT_IF_XGMII == interface)) {
   2758                         *is_valid = 1;
   2759                     }
   2760                 }
   2761             } else {
   2762                 if (num_lanes == 4) {
   2763                     if ((SOC_PORT_IF_KR4 == interface) ||
   2764                         (SOC_PORT_IF_XLAUI == interface)) {
   2765                         *is_valid = 1;
   2766                     }
   2767                 }
   2768             }
   2769             break;
   2770         case 48000:
   2771             if (!is_higig && num_lanes == 4) {
   2772                 if (SOC_PORT_IF_XLAUI == interface) {
   2773                     *is_valid = 1;
   2774                 }
   2775             }
   2776             break;
   2777         case 100000:
   2778             if ((num_lanes == 10) || (num_lanes == 12)) {
   2779                 if ((SOC_PORT_IF_CR10 == interface) ||
   2780                     (SOC_PORT_IF_KR10 == interface) ||
   2781                     (SOC_PORT_IF_LR10 == interface) ||
   2782                     (SOC_PORT_IF_SR10 == interface) ||
   2783                     (SOC_PORT_IF_CAUI == interface)) {
   2784                     *is_valid = 1;
   2785                 }
   2786             }
   2787             break;
   2788         case 106000:
   2789             if ((num_lanes == 10) || (num_lanes == 12)) {
   2790                 if ((SOC_PORT_IF_CR10 == interface) ||
   2791                     (SOC_PORT_IF_KR10 == interface) ||
   2792                     (SOC_PORT_IF_CAUI == interface)) {
   2793                     *is_valid = 1;
   2794                 }
   2795             }
   2796             break;
   2797         case 120000:
   2798             if (num_lanes == 12) {
   2799                 if (SOC_PORT_IF_CAUI == interface) {
   2800                     *is_valid = 1;
   2801                 }
   2802             }
   2803             break;
   2804         case 127000:
   2805             if (num_lanes == 12) {
   2806                 if (SOC_PORT_IF_CAUI == interface) {
   2807                     *is_valid = 1;
   2808                 }
   2809             }
   2810             break;
   2811         default:
   2812             break;
   2813     }
   2814 
   2815     return SOC_E_NONE;
   2816 }
   2817 
   2818 STATIC
   2819 int _pm4x10_default_interface_get(int unit, int port,
   2820                                const portmod_port_interface_config_t *interface_config,
   2821                                soc_port_if_t *interface)
   2822 {
   2823     int is_higig;
   2824     int num_lanes;
   2825     soc_port_if_t interface_tmp = SOC_PORT_IF_NULL;
   2826     SOC_INIT_FUNC_DEFS;
   2827 
   2828     *interface = SOC_PORT_IF_NULL;
   2829     num_lanes = interface_config->port_num_lanes;
   2830     is_higig = ((interface_config->encap_mode == SOC_ENCAP_HIGIG2) ||
   2831                  (interface_config->encap_mode == SOC_ENCAP_HIGIG)) ? 1 : 0;
   2832     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(interface_config, &interface_tmp));
   2833 
   2834     switch (interface_config->speed) {
   2835         case 10:
   2836             *interface = SOC_PORT_IF_SGMII;
   2837             break;
   2838         case 100:
   2839             *interface = SOC_PORT_IF_SGMII;
   2840             break;
   2841         case 1000:
   2842             if (PHYMOD_INTF_MODES_FIBER_GET(interface_config)) {
   2843                 *interface = SOC_PORT_IF_GMII;
   2844             } else if(interface_tmp == SOC_PORT_IF_KX) {
   2845                 *interface = SOC_PORT_IF_KX;
   2846             } else {
   2847                 *interface = SOC_PORT_IF_SGMII;
   2848             }
   2849             break;
   2850         case 2500:
   2851             *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2852                                         SOC_PORT_IF_GMII: SOC_PORT_IF_SGMII;
   2853             break;
   2854         case 5000:
   2855             if (num_lanes == 1) {
   2856                 *interface = SOC_PORT_IF_XFI;
   2857             } else if (num_lanes == 2) {
   2858                 *interface = SOC_PORT_IF_RXAUI;
   2859             } else {
   2860                 *interface = SOC_PORT_IF_XFI;
   2861             }
   2862             break;
   2863         case 10000:
   2864         case 11000:
   2865             if (num_lanes == 2) {
   2866                 *interface = SOC_PORT_IF_RXAUI;
   2867             } else if (num_lanes == 4) {
   2868                 *interface = SOC_PORT_IF_XGMII;
   2869             } else {
   2870                 *interface = PHYMOD_INTF_MODES_FIBER_GET(interface_config)?
   2871                                     SOC_PORT_IF_SFI : SOC_PORT_IF_XFI;
   2872             }
   2873             break;
   2874         case 3125:
   2875         case 5750:
   2876         case 6250:
   2877         case 8125:
   2878         case 8500:
   2879         case 10312:
   2880         case 10937:
   2881         case 11250:
   2882             *interface = SOC_PORT_IF_ILKN;
   2883             break;
   2884         case 10500:
   2885         case 12500:
   2886             break;
   2887         case 20000:
   2888         case 21000:
   2889             if (num_lanes == 4) {
   2890                 *interface = SOC_PORT_IF_XGMII;
   2891             } else {
   2892                 *interface = SOC_PORT_IF_RXAUI;
   2893             }
   2894             break;
   2895         case 23000:
   2896               *interface = SOC_PORT_IF_RXAUI;
   2897             break;
   2898         case 25000:
   2899         case 25450:
   2900         case 25455:
   2901         case 30000:
   2902         case 31500:
   2903             if (num_lanes == 4) {
   2904                 *interface = SOC_PORT_IF_KR4;
   2905             } else if (num_lanes == 2) {
   2906                 *interface = SOC_PORT_IF_KR2;
   2907             } else {
   2908                 *interface = SOC_PORT_IF_KR;
   2909             }
   2910             break;
   2911         case 40000:
   2912             if (is_higig) {
   2913                 *interface = SOC_PORT_IF_XGMII;
   2914             } else {
   2915                 *interface = SOC_PORT_IF_XLAUI;
   2916             }
   2917             break;
   2918         case 42000:
   2919             if (is_higig) {
   2920                 *interface = SOC_PORT_IF_XGMII;
   2921             } else {
   2922                 *interface = SOC_PORT_IF_KR4;
   2923             }
   2924             break;
   2925         case 100000:
   2926             *interface = SOC_PORT_IF_CAUI;
   2927             break;
   2928         case 106000:
   2929             *interface = SOC_PORT_IF_CAUI;
   2930             break;
   2931         case 120000:
   2932             *interface = SOC_PORT_IF_CAUI;
   2933             break;
   2934         case 127000:
   2935             *interface = SOC_PORT_IF_CAUI;
   2936             break;
   2937         default:
   2938             if (num_lanes == 1) {
   2939                 if (interface_config->speed >= 10000) {
   2940                     *interface = SOC_PORT_IF_CR;
   2941                 } else {
   2942                     *interface = SOC_PORT_IF_SGMII;
   2943                 }
   2944             } else if (num_lanes == 2) {
   2945                 if (is_higig) {
   2946                     *interface = SOC_PORT_IF_RXAUI;
   2947                 } else {
   2948                     *interface = SOC_PORT_IF_CR2;
   2949                 }
   2950             } else if (num_lanes == 4) {
   2951                 if (interface_config->speed >= 40000) {
   2952                     if (is_higig){
   2953                         *interface = SOC_PORT_IF_CR4;
   2954                     } else{
   2955                         *interface = SOC_PORT_IF_XLAUI;
   2956                     }
   2957                 } else {
   2958                     *interface = SOC_PORT_IF_XGMII;
   2959                 }
   2960             } else if (num_lanes == 10) {
   2961                     *interface = SOC_PORT_IF_CAUI;
   2962             } else if (num_lanes == 12) {
   2963                     *interface = SOC_PORT_IF_CAUI;
   2964             } else {
   2965                 *interface = SOC_PORT_IF_ILKN;
   2966             }
   2967             break;
   2968     }
   2969 
   2970 exit:
   2971     SOC_FUNC_RETURN;
   2972 }
   2973 
   2974 STATIC
   2975 int _pm4x10_line_side_phymod_interface_get(int unit, int port,
   2976                                 pm_info_t pm_info, int rxaui_mode,
   2977                                 const portmod_port_interface_config_t *config,
   2978                                 phymod_interface_t *interface_type)
   2979 {
   2980     int port_index = 0;
   2981     int is_valid = 0, nof_phys = 0;
   2982     uint32 bitmap;
   2983     soc_port_if_t interface = SOC_PORT_IF_NULL;
   2984     phymod_phy_access_t phy_access_arr[1+MAX_PHYN];
   2985     SOC_INIT_FUNC_DEFS;
   2986 
   2987     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &port_index,
   2988                                             &bitmap));
   2989 
   2990     _SOC_IF_ERR_EXIT
   2991             (portmod_port_chain_phy_access_get(unit, port, pm_info,
   2992                                                phy_access_arr ,(1+MAX_PHYN),
   2993                                                &nof_phys));
   2994 
   2995     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface));
   2996 
   2997     if (nof_phys > 1) {
   2998         /* EXT PHY interface */
   2999         _SOC_IF_ERR_EXIT
   3000             (_pm4x10_ext_phy_interface_check(unit, port, &phy_access_arr[nof_phys-1], config, interface,
   3001                                                  &is_valid));
   3002     } else if (nof_phys == 1) {
   3003         _SOC_IF_ERR_EXIT(_pm4x10_interface_check(unit, port, pm_info, config, interface, &is_valid));
   3004     }
   3005     
   3006     if (!is_valid) {
   3007         /* interface check validation for internal sedes failed */ 
   3008         LOG_ERROR(BSL_LS_BCM_PORT,
   3009               (BSL_META_UP(unit, port,
   3010                "ERROR: u=%d p=%d interface type %d not supported by internal SERDES for this speed %d \n"),
   3011                unit, port, interface, config->speed));
   3012         _SOC_IF_ERR_EXIT(SOC_E_PARAM);    
   3013     }
   3014 
   3015     
   3016     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed,
   3017                                                  interface, interface_type));
   3018     if ((config->speed == 10000) && (config->port_num_lanes == 2)) {
   3019         if (rxaui_mode == 0x2) {
   3020             *interface_type = phymodInterfaceRXAUI;
   3021         }
   3022         else if (rxaui_mode) {
   3023             *interface_type = phymodInterfaceX2;
   3024         } else {
   3025             *interface_type = phymodInterfaceRXAUI;
   3026         }
   3027     }
   3028 
   3029 exit:
   3030     SOC_FUNC_RETURN;
   3031 }
   3032 
   3033 int _pm4x10_phymod_interface_mode_set(int unit, int port,pm_info_t pm_info,
   3034                                    const portmod_port_interface_config_t *config,
   3035                                    phymod_phy_inf_config_t *phy_config,
   3036                                    int is_legacy_phy_callback)
   3037 {
   3038     int port_index = 0;
   3039     uint32 bitmap;
   3040     soc_port_if_t interface = SOC_PORT_IF_NULL;
   3041     SOC_INIT_FUNC_DEFS;
   3042 
   3043     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &port_index,
   3044                                             &bitmap));
   3045 
   3046     _SOC_IF_ERR_EXIT(PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &interface,
   3047                                                port_index));
   3048     phy_config->interface_modes = config->interface_modes;
   3049 
   3050     switch (config->speed) {
   3051         case 6250:
   3052             if (PHYMOD_INTF_MODES_OS2_GET(config)) {/* for dual rate OS2 is required */
   3053                 PHYMOD_INTF_MODES_OS2_SET(phy_config);
   3054             }
   3055             break;
   3056         case 10000:
   3057             if (config->port_num_lanes == 2) {
   3058                 if (PHYMOD_INTF_MODES_SCR_GET(config)) {
   3059                     PHYMOD_INTF_MODES_SCR_SET(phy_config);
   3060                 }
   3061             }
   3062             break;
   3063         case 20000:
   3064             if (config->port_num_lanes == 4) {
   3065                 if (PHYMOD_INTF_MODES_SCR_GET(config)) {
   3066                     PHYMOD_INTF_MODES_SCR_SET(phy_config);
   3067                 }
   3068             }
   3069             break;
   3070         case 100000:
   3071         case 106000:
   3072         case 107000:
   3073         case 120000:
   3074         case 127000:
   3075           if ((phy_config->interface_type == phymodInterfaceSR10) ||
   3076               (phy_config->interface_type == phymodInterfaceLR10))  {
   3077               PHYMOD_INTF_MODES_FIBER_SET(phy_config);
   3078           }
   3079           break;            
   3080         default:
   3081             break;
   3082     }
   3083 
   3084     /*
   3085      * tsce/tscf relies on the interface type and interface mode specified in phy_config
   3086      * to determine the exact interface type written into or read from the registers. For
   3087      * instance, SR4 and KR4 share the same speed ID (reg value) from TSCE's perspective
   3088      * and their difference is the medium type specified in the interface mode. SR4 is
   3089      * optical while KR4 is not. Below we prevent updating the medium type in the port
   3090      * mode provided to the internal PHY if phy_config is to be provided to the internal
   3091      * PHY in the legacy ext PHY callback scenario. Reason is because interface used in
   3092      * the function call below is meant for the outmost PHY instead of the internal PHY.
   3093      * portmod_port_phychain_interface_config_set() has a similar protection mechanism
   3094      * to change the medium type of the port mode based on internal PHY's interface type.
   3095      * However, that only works when the config property "serdes_if_type" is specified.
   3096      */
   3097     if (!is_legacy_phy_callback) {
   3098     _SOC_IF_ERR_EXIT(portmod_media_type_from_port_intf(unit, interface,
   3099                                                        phy_config));
   3100     }
   3101 exit:
   3102     SOC_FUNC_RETURN;
   3103 }
   3104 
   3105 /*
   3106 *   overwrite default tx params from config file.
   3107 *   set phy_init_config in PM.
   3108 */
   3109 STATIC
   3110 int _pm4x10_port_tx_config_init_set(int unit, pm_info_t pm_info,
   3111                                     int lane_mask,
   3112                                     int core_start_lane,
   3113                                     int core_end_lane,
   3114                                     phymod_tx_t *tx_params_default,
   3115                                     const phymod_tx_t user_tx_params[],
   3116                                     const int *config_flag,
   3117                                     phymod_tx_t phy_tx_params[],
   3118                                     int *tx_params_update)
   3119 {
   3120     int lane_index, user_cfg_index, phy_param_index, start_cfg_index = core_start_lane, find_first_active_lane = 0;
   3121     
   3122     if(core_start_lane==-1){
   3123         start_cfg_index = 0;
   3124     }
   3125 
   3126     /*
   3127      * Read user configuration into the parameter array which will be passed to Phymod driver.
   3128      * For consecutive physical lanes, Phymod driver expect each item in the parameter array
   3129      * indicate the value for every active lane.
   3130      * For inconsecutive physical lanes, it's a little different.
   3131      * For exampe, there are two active lane: lane 0 and lane 2, Phymod driver expect the first
   3132      * item indicate lane 0 and the third item indicate lane 2.
   3133      */
   3134     *tx_params_update = 0;
   3135     for (lane_index = 0, user_cfg_index = start_cfg_index, phy_param_index = 0; lane_index < PHYMOD_MAX_LANES_PER_PORT; lane_index++) {
   3136         if (lane_mask & (0x1<<lane_index)) {
   3137             phy_tx_params[phy_param_index].pre = tx_params_default->pre;
   3138             phy_tx_params[phy_param_index].main = tx_params_default->main;
   3139             phy_tx_params[phy_param_index].post = tx_params_default->post;
   3140             phy_tx_params[phy_param_index].post2 = tx_params_default->post2;
   3141             phy_tx_params[phy_param_index].post3 = tx_params_default->post3;
   3142             phy_tx_params[phy_param_index].amp = tx_params_default->amp;
   3143             phy_tx_params[phy_param_index].drivermode = tx_params_default->drivermode;
   3144 
   3145             if (config_flag[user_cfg_index] & PORTMOD_USER_SET_TX_PREEMPHASIS_BY_CONFIG) {
   3146                 phy_tx_params[phy_param_index].pre = user_tx_params[user_cfg_index].pre;
   3147                 phy_tx_params[phy_param_index].main = user_tx_params[user_cfg_index].main;
   3148                 phy_tx_params[phy_param_index].post = user_tx_params[user_cfg_index].post;
   3149         }
   3150 
   3151             if (config_flag[user_cfg_index] & PORTMOD_USER_SET_TX_AMP_BY_CONFIG) {
   3152                 phy_tx_params[phy_param_index].amp = user_tx_params[user_cfg_index].amp;
   3153         }
   3154 
   3155 
   3156             if ((config_flag[user_cfg_index] & PORTMOD_USER_SET_TX_PREEMPHASIS_BY_CONFIG)
   3157                  || (config_flag[user_cfg_index] & PORTMOD_USER_SET_TX_AMP_BY_CONFIG)){
   3158                 *tx_params_update = 1;
   3159     }
   3160 
   3161             user_cfg_index++;
   3162 
   3163             if (!find_first_active_lane) {
   3164                 find_first_active_lane = 1;
   3165             }
   3166         }
   3167 
   3168         if (find_first_active_lane) {
   3169             phy_param_index++;
   3170         }
   3171     }
   3172 
   3173     return SOC_E_NONE;
   3174 }
   3175 
   3176 STATIC
   3177 int _pm4x10_port_timestamp_adjust_wb_get(int unit, int port, pm_info_t pm_info,
   3178                                             int speed, portmod_port_ts_adjust_t *ts_adjust)
   3179 {
   3180     int rv = 0;
   3181     int port_index, adjust_index;
   3182     uint32_t bitmap;
   3183     portmod_port_ts_adjust_t port_ts_adjust;
   3184 
   3185     SOC_INIT_FUNC_DEFS;
   3186     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   3187     for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM; adjust_index++) {
   3188          rv = PM4x10_PORT_TIME_STAMP_ADJUST_GET(unit, pm_info, &port_ts_adjust, adjust_index, port_index);
   3189          if ((port_ts_adjust.speed == speed)  ||
   3190              (port_ts_adjust.speed == -1)) {
   3191              sal_memcpy(ts_adjust, &port_ts_adjust, sizeof(portmod_port_ts_adjust_t));
   3192              break;
   3193          }
   3194     }
   3195 
   3196     _SOC_IF_ERR_EXIT(rv);
   3197 exit:
   3198     SOC_FUNC_RETURN;
   3199 }
   3200 
   3201 /*
   3202  *  clear pm_info's phy_interface_config, and set few members of phy_interface_config
   3203  *  initialize phy_init_config tx params and set registers 
   3204 */
   3205 int _pm4x10_port_interface_config_init_set(int unit, int port, 
   3206                         pm_info_t pm_info, 
   3207                         const portmod_port_interface_config_t* config,
   3208                         const portmod_port_init_config_t* init_config,
   3209                         phymod_tx_t serdes_tx_params[],
   3210                         phymod_tx_t ext_phy_tx_params[])
   3211 {
   3212     uint32 reg_val, pm_is_bypassed = 0; 
   3213     int    nof_phys = 0, rv = 0, phy_acc, flags = 0;
   3214     int    tx_params_update = 0, mac_ts_enable;
   3215     int    core_start_lane=-1, core_end_lane=-1, line_start_lane=-1, line_end_lane=-1;
   3216     uint32 int_lane_mask=0xf, port_dynamic_state = 0;
   3217     phymod_phy_access_t phy_access[1 + MAX_PHYN];
   3218     phymod_phy_inf_config_t     phy_interface_config;
   3219     phymod_tx_t                 phymod_tx;
   3220     int                         port_index, is_legacy_phy = 0;
   3221     int                         is_higig, rxaui_mode, xphy_id;
   3222     uint32_t                    bitmap;
   3223 	phymod_interface_t phymod_interface = phymodInterfaceCount;
   3224     portmod_port_ts_adjust_t ts_adjust;
   3225 
   3226     SOC_INIT_FUNC_DEFS;
   3227 
   3228     sal_memset(&ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   3229 
   3230     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   3231 
   3232     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   3233                                              &bitmap));
   3234 
   3235     _SOC_IF_ERR_EXIT(phymod_tx_t_init(&phymod_tx));
   3236 
   3237     is_higig =  ((config->encap_mode == SOC_ENCAP_HIGIG2) ||
   3238                  (config->encap_mode == SOC_ENCAP_HIGIG) ||
   3239                  PHYMOD_INTF_MODES_HIGIG_GET(config)) ? 1 : 0;
   3240 
   3241     rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   3242                                 pm_info->wb_vars_ids[isBypassed], 
   3243                                 &pm_is_bypassed);
   3244     _SOC_IF_ERR_EXIT(rv);
   3245    
   3246     if(!pm_is_bypassed){
   3247         /* set HiG mode */
   3248         _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &reg_val));
   3249         soc_reg_field_set (unit, XLPORT_CONFIGr, &reg_val, HIGIG2_MODEf, is_higig);
   3250         _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, reg_val));
   3251     
   3252         /* set port speed */
   3253         flags = XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   3254         _SOC_IF_ERR_EXIT(xlmac_speed_set(unit, port, flags, config->speed));
   3255 
   3256         if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
   3257             _SOC_IF_ERR_EXIT
   3258                 (pm4x10_port_mac_timestamp_enable_get(unit, port, pm_info, &mac_ts_enable));
   3259         } else {
   3260             mac_ts_enable = 1;
   3261         }
   3262         _SOC_IF_ERR_EXIT(PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   3263                                           &port_dynamic_state, port_index));
   3264         if (mac_ts_enable) {
   3265             /*Set MAC Timestamp Delay*/
   3266             if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   3267                 _SOC_IF_ERR_EXIT(_pm4x10_port_timestamp_adjust_wb_get(unit, port, pm_info, config->speed, &ts_adjust));
   3268                 _SOC_IF_ERR_EXIT(xlmac_timestamp_delay_set(unit, port, ts_adjust, config->speed));
   3269             }
   3270             _SOC_IF_ERR_EXIT(xlmac_timestamp_byte_adjust_set(unit, port, 0, config->speed));
   3271         }
   3272 
   3273         /* set encapsulation */
   3274         flags = XLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS;
   3275         rv = xlmac_encap_set (unit, port, flags, is_higig ?  SOC_ENCAP_HIGIG2 : 
   3276                                                              SOC_ENCAP_IEEE);
   3277         _SOC_IF_ERR_EXIT(rv);
   3278 
   3279         rv = xlmac_strict_preamble_set(unit, port, (!is_higig && (config->speed >= 10000)));
   3280 
   3281         _SOC_IF_ERR_EXIT(rv);
   3282 
   3283     }
   3284 
   3285     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, 
   3286                                                        phy_access ,(1+MAX_PHYN),
   3287                                                        &nof_phys));
   3288 
   3289     _SOC_IF_ERR_EXIT(PM4x10_RXAUI_MODE_GET(unit, pm_info,
   3290                                            &rxaui_mode, port_index));
   3291 
   3292     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init (&phy_interface_config));
   3293     _SOC_IF_ERR_EXIT(_pm4x10_line_side_phymod_interface_get(unit, port,
   3294                                                             pm_info, rxaui_mode,
   3295                                                             config,
   3296                                                             &phymod_interface));
   3297     phy_interface_config.interface_type = phymod_interface;
   3298     _SOC_IF_ERR_EXIT(_pm4x10_phymod_interface_mode_set(unit, port,
   3299                                                        pm_info, config,
   3300                                                        &phy_interface_config,
   3301                                                        0));
   3302 
   3303     phy_interface_config.data_rate       = config->speed;
   3304     phy_interface_config.pll_divider_req = config->pll_divider_req;
   3305     phy_interface_config.ref_clock       = PM_4x10_INFO(pm_info)->ref_clk;
   3306 
   3307     _SOC_IF_ERR_EXIT(PM4x10_SPEED_SET(unit, pm_info,
   3308                                       config->speed, port_index));
   3309 
   3310 
   3311     /* find the start_lane and end_lane of the current core */
   3312     _SOC_IF_ERR_EXIT(_pm4x10_port_tricore_lane_info_get(unit, port, pm_info,
   3313                                                         &core_start_lane, &core_end_lane,
   3314                                                         &line_start_lane, &line_end_lane,
   3315                                                         &int_lane_mask, NULL));
   3316 
   3317     if(nof_phys > 1)
   3318     {   /* external phy. */
   3319         /* get most external phy default tx params */
   3320         xphy_id = phy_access[nof_phys-1].access.addr;
   3321         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   3322         if (!is_legacy_phy) {
   3323             _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(&phy_access[nof_phys-1], phymodMediaTypeChipToChip, &phymod_tx));
   3324         }
   3325 
   3326         /* overlap most external phy  preemphasis and amp from config */
   3327         tx_params_update = 0;
   3328         _SOC_IF_ERR_EXIT(
   3329                 _pm4x10_port_tx_config_init_set(unit, pm_info,
   3330                                        phy_access[nof_phys-1].access.lane_mask,
   3331                                        core_start_lane,
   3332                                        core_end_lane, &phymod_tx,
   3333                                        init_config->ext_phy_tx_params,
   3334                                        init_config->ext_phy_tx_params_user_flag,
   3335                                        ext_phy_tx_params,
   3336                                        &tx_params_update));
   3337         if (tx_params_update) {
   3338             PORTMOD_PORT_DEFAULT_EXT_PHY_TX_PARAMS_UPDATED_SET(port_dynamic_state);
   3339             PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info, port_dynamic_state, port_index);
   3340         }
   3341     }
   3342 
   3343     /* get serdes default tx params */
   3344     _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(phy_access, phymodMediaTypeChipToChip, &phymod_tx));
   3345 
   3346     /* overlap serdes preemphasis and amp from config */
   3347     tx_params_update = 0;
   3348     _SOC_IF_ERR_EXIT(
   3349             _pm4x10_port_tx_config_init_set(unit, pm_info,
   3350                                             phy_access[0].access.lane_mask,
   3351                                             core_start_lane,
   3352                                             core_end_lane, &phymod_tx,
   3353                                             init_config->tx_params,
   3354                                             init_config->tx_params_user_flag,
   3355                                             serdes_tx_params,
   3356                                             &tx_params_update));
   3357     if (tx_params_update) {
   3358         PORTMOD_PORT_DEFAULT_TX_PARAMS_UPDATED_SET(port_dynamic_state);
   3359         PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info, port_dynamic_state, port_index);
   3360     }
   3361 
   3362     /* set the outmost external PHY tx. internal and intermediary phy will be modified in portmod_port_phychain_phy_init*/
   3363     if (nof_phys > 1){
   3364         SOC_IF_ERROR_RETURN(
   3365                 portmod_port_phychain_tx_set(unit, phy_access, nof_phys,
   3366                                              ext_phy_tx_params));
   3367     }
   3368     
   3369     /* update the interface type in the scache buffer */
   3370     _SOC_IF_ERR_EXIT(PM4x10_PORT_OP_MODE_SET(unit, pm_info,
   3371                                              config->port_op_mode,
   3372                                              port_index));
   3373 
   3374 exit:
   3375     SOC_FUNC_RETURN;
   3376 }
   3377 
   3378 
   3379 STATIC
   3380 int _pm4x10_pm_disable (int unit, int port, pm_info_t pm_info, int phy_acc)
   3381 {
   3382     uint32 reg_val;
   3383     int rv = 0;
   3384 
   3385     /* put MAC in reset */
   3386     rv = READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val);
   3387     if (rv) return (rv);
   3388 
   3389     soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 1);
   3390     rv = WRITE_XLPORT_MAC_CONTROLr(unit, phy_acc, reg_val);
   3391     if (rv) return (rv);
   3392 
   3393     /* Put Serdes in reset*/
   3394     if(PM_4x10_INFO(pm_info)->portmod_phy_external_reset) {
   3395         rv = PM_4x10_INFO(pm_info)->portmod_phy_external_reset(unit, port, 1);
   3396     } else {
   3397         if ( _pm4x10_port_tsc_is_master_pll(unit, port, pm_info) != TRUE) {  /* Not master PLL PM, reset it */
   3398             rv = _pm4x10_tsc_reset(unit, pm_info, port, 1);
   3399         }
   3400     }
   3401 
   3402     return (rv);
   3403 }
   3404 
   3405 STATIC
   3406 int _pm4x10_pm_xlport_init (int unit, int port, pm_info_t pm_info,
   3407                             int port_index, int phy_acc, const portmod_port_add_info_t* add_info)
   3408 {
   3409     uint32 reg_val, port_mode;
   3410     int    three_ports_mode, rv;
   3411     pm_version_t pm_version;
   3412     int interface = add_info->interface_config.interface;
   3413     int timestamp_mode = add_info->flags & PORTMOD_PORT_ADD_F_EGR_1588_TIMESTAMP_MODE_48BIT ? 1 : 0;
   3414     uint32 *txpi_lane_select = (uint32 *)add_info->init_config.lane_map[0].lane_map_tx;
   3415     SOC_INIT_FUNC_DEFS;
   3416 
   3417     /* Power Save */
   3418     _SOC_IF_ERR_EXIT(READ_XLPORT_POWER_SAVEr(unit, phy_acc, &reg_val));
   3419     soc_reg_field_set(unit, XLPORT_POWER_SAVEr, &reg_val, XPORT_CORE0f, 0); 
   3420     _SOC_IF_ERR_EXIT(WRITE_XLPORT_POWER_SAVEr(unit, phy_acc, reg_val));
   3421 
   3422     /* Port configuration */
   3423     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, 
   3424                pm_info->wb_vars_ids[threePortsMode], &three_ports_mode);
   3425     _SOC_IF_ERR_EXIT(rv);
   3426 
   3427     if(PM4x10_QUAD_MODE_IF(interface)) {
   3428         /* This is WAR for shim issue on Merlin16 MGMT port, XLPORT_MODE_REG is
   3429          * set as dual-port mode for XAUI mode
   3430          */
   3431         if (PM_4x10_INFO(pm_info)->port_mode_aux_info == portmodModeInfoTwoDualModePorts) {
   3432             port_mode = XLMAC_2_LANES_DUAL;
   3433         } else {
   3434             port_mode = XLMAC_4_LANES_TOGETHER;
   3435         }
   3436     } else if(PM4x10_DUAL_MODE_IF(interface)){
   3437         port_mode = (!three_ports_mode) ?  XLMAC_2_LANES_DUAL :
   3438                       ((port_index < 2) ?  XLMAC_3_TRI_0_0_2_3 : 
   3439                                            XLMAC_3_TRI_0_1_2_2);
   3440     } else { /*single mode*/
   3441         if (PM_4x10_INFO(pm_info)->port_mode_aux_info == portmodModeInfoTwoDualModePorts) {
   3442             port_mode = XLMAC_2_LANES_DUAL;
   3443         } else {
   3444         port_mode = (!three_ports_mode) ? XLMAC_4_LANES_SEPARATE :
   3445                      ((port_index < 2) ?  XLMAC_3_TRI_0_1_2_2 :
   3446                                           XLMAC_3_TRI_0_0_2_3);
   3447     }
   3448     }
   3449 
   3450     _SOC_IF_ERR_EXIT(READ_XLPORT_MODE_REGr(unit, phy_acc, &reg_val));
   3451     soc_reg_field_set (unit, XLPORT_MODE_REGr, &reg_val, XPORT0_CORE_PORT_MODEf, port_mode);
   3452     soc_reg_field_set (unit, XLPORT_MODE_REGr, &reg_val, XPORT0_PHY_PORT_MODEf,  port_mode);
   3453     soc_reg_field_set (unit, XLPORT_MODE_REGr, &reg_val, EGR_1588_TIMESTAMPING_MODEf, timestamp_mode); 
   3454     _SOC_IF_ERR_EXIT(WRITE_XLPORT_MODE_REGr(unit, phy_acc, reg_val));
   3455 
   3456     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   3457     if (PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   3458         /* Set txpi lane select */
   3459         _SOC_IF_ERR_EXIT(_pm4x10_txpi_lane_select_set(unit, port, pm_info, txpi_lane_select));
   3460     }
   3461 
   3462     /* Get Serdes OOR */
   3463     if(PM_4x10_INFO(pm_info)->portmod_phy_external_reset) {
   3464         if(!((interface == SOC_PORT_IF_CAUI)&&(PM_4x10_INFO(pm_info)->core_num_int))) {
   3465             _SOC_IF_ERR_EXIT(PM_4x10_INFO(pm_info)->portmod_phy_external_reset(unit, port, 1));
   3466             _SOC_IF_ERR_EXIT(PM_4x10_INFO(pm_info)->portmod_phy_external_reset(unit, port, 0));
   3467         }
   3468     } else {
   3469         if ( _pm4x10_port_tsc_is_master_pll(unit, port, pm_info) != TRUE) {  /* Not master PLL PM, reset it */
   3470             _SOC_IF_ERR_EXIT(_pm4x10_tsc_reset(unit, pm_info, port, 1));
   3471             _SOC_IF_ERR_EXIT(_pm4x10_tsc_reset(unit, pm_info, port, 0));
   3472         }
   3473     }
   3474 
   3475     /* Bring MAC OOR */
   3476     _SOC_IF_ERR_EXIT(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   3477     soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 0);
   3478     /* Disable MAC timestamp by default */
   3479     if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
   3480         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val, XLMAC_TS_DISABLEf, 1);
   3481     }
   3482     _SOC_IF_ERR_EXIT(WRITE_XLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   3483 
   3484 exit:
   3485     SOC_FUNC_RETURN;        
   3486 }
   3487 
   3488 static phymod_dispatch_type_t pm4x10_serdes_list[] =
   3489 {
   3490     phymodDispatchTypeTsce,
   3491     phymodDispatchTypeTsce16,
   3492     phymodDispatchTypeTsce_dpll,
   3493     phymodDispatchTypeQsgmiie,
   3494     phymodDispatchTypeInvalid
   3495 };
   3496 
   3497 STATIC
   3498 int _pm4x10_pm_core_probe (int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   3499 {
   3500     int     rv = SOC_E_NONE;
   3501     int    temp, phy;
   3502     portmod_pbmp_t port_phys_in_pm;
   3503     int probe =0;
   3504     uint32 xphy_id;
   3505     uint32 nof_ext_phys =0;
   3506     int i, is_legacy_phy;
   3507     int core_probed;
   3508     phymod_core_access_t core_access;
   3509     phymod_firmware_load_method_t fw_load_method;
   3510     SOC_INIT_FUNC_DEFS;
   3511 
   3512     /* probe phys (both internal and external cores. */
   3513 
   3514     /* Get the first phy related to this port */
   3515     PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   3516     PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x10_INFO(pm_info)->phys);
   3517 
   3518     /* if internal core is not probe, probe it. Currently checking to type to see
   3519        phymodDispatchTypeInvalid, later need to move to WB.  */
   3520     _SOC_IF_ERR_EXIT(portmod_common_serdes_probe(pm4x10_serdes_list, &PM_4x10_INFO(pm_info)->int_core_access, &probe));
   3521 
   3522     /* save probed phy type to wb. */
   3523     if(probe) {
   3524          rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   3525                      pm_info->wb_vars_ids[phy_type],
   3526                      &PM_4x10_INFO(pm_info)->int_core_access.type);
   3527          _SOC_IF_ERR_EXIT(rv);
   3528     }
   3529 
   3530     /* probe ext core related to this logical port. */
   3531     temp = 0;
   3532     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {
   3533         if(PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)) {
   3534             if( PM_4x10_INFO(pm_info)->nof_phys[temp] >= 2 ){
   3535                 nof_ext_phys = PM_4x10_INFO(pm_info)->nof_phys[temp]-1;
   3536                 for(i=0 ; i<nof_ext_phys ; i++) {
   3537                     xphy_id = PM_4x10_INFO(pm_info)->lane_conn[i][temp].xphy_id;
   3538                     if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   3539                         _SOC_IF_ERR_EXIT(portmod_xphy_core_probed_get(unit, xphy_id, &core_probed));
   3540                             _SOC_IF_ERR_EXIT(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   3541                         if( !core_probed ){
   3542                             _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   3543                             probe = 0;
   3544                             if(SOC_E_NONE != (portmod_common_ext_phy_probe(unit, port, &core_access, &probe))) {
   3545                                 /* 
   3546                                  * Remove un-probed external PHY from phy number count.
   3547                                  * Also save it to warmboot memory. 
   3548                                  */
   3549                                 PM_4x10_INFO(pm_info)->nof_phys[temp] = i + 1;
   3550                                 rv = PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, &(PM_4x10_INFO(pm_info)->nof_phys[temp]), temp);
   3551                                 _SOC_IF_ERR_EXIT(rv);
   3552                                 /* Set firmware download method to phymodFirmwareLoadMethodNone to avoid image download for unprobed XPHY */
   3553                                 fw_load_method = phymodFirmwareLoadMethodNone;
   3554                             } else {
   3555                                 if (!probe) {
   3556                                 /* 
   3557                                  * case where port_phy_addr is specified and phy is not connetced.
   3558                                  * Remove un-probed external PHY from phy number count.
   3559                                  * Also save it to warmboot memory. 
   3560                                  */
   3561                                 PM_4x10_INFO(pm_info)->nof_phys[temp] = i + 1;
   3562                                 rv = PM4x10_PORT_NUM_PHYS_SET(unit, pm_info,&(PM_4x10_INFO(pm_info)->nof_phys[temp]), temp);
   3563                                 _SOC_IF_ERR_EXIT(rv);
   3564                                 /* Set firmware download method to phymodFirmwareLoadMethodNone to avoid image download for unprobed XPHY */
   3565                                 fw_load_method = phymodFirmwareLoadMethodNone;
   3566                                 } else {
   3567                                     core_probed = 1;
   3568                                 }
   3569                             }
   3570                             _SOC_IF_ERR_EXIT(portmod_xphy_core_probed_set(unit, xphy_id, core_probed));
   3571                             _SOC_IF_ERR_EXIT(portmod_xphy_fw_load_method_set(unit, xphy_id, fw_load_method));
   3572                             /* Check if after the probe the ext phy is legacy, so we dont overrun the current value */
   3573                             _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   3574                             _SOC_IF_ERR_EXIT(portmod_xphy_core_access_set(unit, xphy_id, &core_access, is_legacy_phy));
   3575                         }
   3576                     }
   3577                 }
   3578             }
   3579         }
   3580         temp++;
   3581     }
   3582 
   3583    /*update warmboot engine*/
   3584     rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   3585         pm_info->wb_vars_ids[phy_type],
   3586         &PM_4x10_INFO(pm_info)->int_core_access.type, 0);
   3587     _SOC_IF_ERR_EXIT(rv);
   3588 
   3589 exit:
   3590     SOC_FUNC_RETURN;
   3591 }
   3592 
   3593 STATIC
   3594 int _pm4x10_pm_serdes_core_init(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   3595 {
   3596     int     rv;
   3597     phymod_core_init_config_t core_conf;
   3598     phymod_core_status_t core_status;
   3599     const portmod_port_interface_config_t* config;
   3600     uint32 core_is_initialized;
   3601     uint32 init_flags, is_bypass;
   3602     soc_port_if_t interface = SOC_PORT_IF_NULL;
   3603     pm_version_t pm_version;
   3604     SOC_INIT_FUNC_DEFS;
   3605 
   3606     config = &(add_info->interface_config);
   3607 
   3608     _SOC_IF_ERR_EXIT(phymod_core_init_config_t_init(&core_conf));
   3609 
   3610     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &is_bypass);
   3611     _SOC_IF_ERR_EXIT(rv);
   3612     /* set internal setting. */
   3613 
   3614     core_conf.firmware_load_method = PM_4x10_INFO(pm_info)->fw_load_method;
   3615     core_conf.firmware_loader = PM_4x10_INFO(pm_info)->external_fw_loader;
   3616     if (PM_4x10_INFO(pm_info)->is_pm4x10q) {
   3617         core_conf.lane_map = add_info->init_config.lane_map[0];
   3618     } else {
   3619     core_conf.lane_map = PM_4x10_INFO(pm_info)->lane_map;
   3620     }
   3621 
   3622     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&core_conf.interface));
   3623     _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface));
   3624     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed,
   3625                         interface, &core_conf.interface.interface_type));
   3626     core_conf.interface.data_rate = config->speed;
   3627     core_conf.interface.interface_modes = config->interface_modes;
   3628     core_conf.interface.ref_clock = PM_4x10_INFO(pm_info)->ref_clk;
   3629     core_conf.interface.pll_divider_req = add_info->init_config.pll_divider_req;
   3630 
   3631     _SOC_IF_ERR_EXIT(phymod_core_status_t_init(&core_status));
   3632 
   3633     if(PORTMOD_PORT_ADD_F_FIRMWARE_LOAD_VERIFY_GET(add_info)) {
   3634         PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_SET(&core_conf);
   3635     }
   3636 
   3637     init_flags = PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) | PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info);
   3638     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   3639         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_SET(&core_conf);
   3640     }
   3641 
   3642     if(PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   3643         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_SET(&core_conf);
   3644     }
   3645 
   3646     core_conf.op_datapath = add_info->phy_op_datapath;
   3647 
   3648     /* deal witn internal serdes first */
   3649     rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   3650                                 pm_info->wb_vars_ids[isInitialized],
   3651                                 &core_is_initialized);
   3652      _SOC_IF_ERR_EXIT(rv);
   3653 
   3654     if (!PORTMOD_CORE_INIT_FLAG_INITIALZIED_GET(core_is_initialized)) {
   3655         /* firmware load will happen after init_pass1 */
   3656         if (!PORTMOD_CORE_INIT_FLAG_FIRMWARE_LOADED_GET(core_is_initialized) ||
   3657            PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   3658            _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   3659 
   3660            if (PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   3661                 portmod_vcos_speed_config_t speed_config;
   3662                 phymod_dual_plls_t init_plls;
   3663 
   3664                 init_plls.pll0_div = phymod_TSCE_PLL_DIV66;
   3665                 init_plls.pll1_div = phymod_TSCE_PLL_DIV40;
   3666 
   3667                 portmod_vcos_speed_config_t_init(unit, &speed_config);
   3668                 speed_config.higig_mode = add_info->init_config.is_hg;
   3669                 speed_config.speed = add_info->interface_config.speed;
   3670                 speed_config.num_lanes = add_info->interface_config.port_num_lanes;
   3671 
   3672                 _SOC_IF_ERR_EXIT(_pm4x10_init_plls_get(unit, port, pm_info, &speed_config, 1, &init_plls));
   3673                 core_conf.pll0_div_init_value = init_plls.pll0_div;
   3674                 core_conf.pll1_div_init_value = init_plls.pll1_div;
   3675             }
   3676 
   3677             if ((is_bypass) && (!PM_4x10_INFO(pm_info)->in_pm12x10)) {
   3678                 PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_SET(PM_4x10_INFO(pm_info)->int_core_access.device_op_mode);
   3679             }
   3680             _SOC_IF_ERR_EXIT(phymod_core_init(&PM_4x10_INFO(pm_info)->int_core_access,
   3681                                               &core_conf,
   3682                                               &core_status));
   3683 
   3684             if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || init_flags == 0) { 
   3685                 PORTMOD_CORE_INIT_FLAG_FIRMWARE_LOADED_SET(core_is_initialized);
   3686                 rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   3687                                         pm_info->wb_vars_ids[isInitialized],
   3688                                         &core_is_initialized);
   3689                 _SOC_IF_ERR_EXIT(rv);
   3690             }
   3691             if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info) || init_flags == 0) { 
   3692                 PORTMOD_CORE_INIT_FLAG_INITIALZIED_SET(core_is_initialized);
   3693                 rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   3694                                         pm_info->wb_vars_ids[isInitialized],
   3695                                         &core_is_initialized);
   3696                 _SOC_IF_ERR_EXIT(rv);
   3697             }
   3698         }
   3699     }
   3700 
   3701     /*update warmboot engine*/
   3702     rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   3703         pm_info->wb_vars_ids[phy_type],
   3704         &PM_4x10_INFO(pm_info)->int_core_access.type, 0);
   3705     _SOC_IF_ERR_EXIT(rv);
   3706 
   3707     exit:
   3708         SOC_FUNC_RETURN;
   3709 }
   3710 
   3711 STATIC
   3712 int _pm4x10_pm_ext_phy_core_init(int unit, pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   3713 {
   3714     int    temp, phy;
   3715     phymod_core_init_config_t core_conf;
   3716     phymod_core_status_t core_status;
   3717     portmod_pbmp_t port_phys_in_pm;
   3718     uint32 xphy_id;
   3719     uint32 nof_ext_phys =0;
   3720     int i;
   3721     int is_initialized;
   3722     int lane;
   3723     int init_all;
   3724     phymod_firmware_load_method_t fw_load_method;
   3725     int force_fw_load;
   3726     phymod_lane_map_t lane_map;
   3727     phymod_core_access_t core_access;
   3728     uint32 primary_core_num;
   3729     int is_legacy_phy;
   3730     SOC_INIT_FUNC_DEFS;
   3731 
   3732     init_all = (!PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) &&
   3733                     !PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) &&
   3734                     !PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) ? 1 : 0;
   3735 
   3736     /* Get the first phy related to this port */
   3737     PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   3738     PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x10_INFO(pm_info)->phys);
   3739 
   3740     /* core init (both internal and external cores. */
   3741 
   3742     _SOC_IF_ERR_EXIT(phymod_core_init_config_t_init(&core_conf));
   3743 
   3744     core_conf.interface.pll_divider_req =
   3745                           add_info->init_config.pll_divider_req;
   3746 
   3747     _SOC_IF_ERR_EXIT(phymod_core_status_t_init(&core_status));
   3748 
   3749 
   3750     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   3751         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_SET(&core_conf);
   3752     }
   3753 
   3754     if(PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   3755         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_SET(&core_conf);
   3756     }
   3757 
   3758     core_conf.op_datapath = add_info->phy_op_datapath;
   3759 
   3760     /* deal with ext phys now ... */
   3761     if(PORTMOD_PORT_ADD_F_PORT_ATTACH_EXT_PHY_SKIP_GET(add_info)) {
   3762         return(SOC_E_NONE);
   3763     }
   3764 
   3765     /* adjust config setup for external phys. */
   3766 
   3767     /* for external phys, FW load method is default to Internal
   3768        unless it is force to NONE. */
   3769 
   3770 
   3771     core_conf.firmware_load_method = (PM_4x10_INFO(pm_info)->fw_load_method ==
   3772                                         phymodFirmwareLoadMethodNone) ?
   3773                                         phymodFirmwareLoadMethodNone :
   3774                                         phymodFirmwareLoadMethodInternal;
   3775     core_conf.firmware_loader = NULL;
   3776 
   3777     /* config "no swap" for external phys.set later using APIs*/
   3778     for(lane=0 ; lane < (core_conf.lane_map.num_of_lanes); lane++) {
   3779         core_conf.lane_map.lane_map_rx[lane] = lane;
   3780         core_conf.lane_map.lane_map_tx[lane] = lane;
   3781     }
   3782 
   3783 
   3784     temp = 0;
   3785     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {
   3786         if(PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)) {
   3787             if( PM_4x10_INFO(pm_info)->nof_phys[temp] >= 2 ){
   3788                 nof_ext_phys = PM_4x10_INFO(pm_info)->nof_phys[temp]-1;
   3789                 for(i=0 ; i<nof_ext_phys ; i++) {
   3790                     xphy_id = PM_4x10_INFO(pm_info)->lane_conn[i][temp].xphy_id;
   3791                     if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   3792 
   3793                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   3794                         _SOC_IF_ERR_EXIT(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   3795                         _SOC_IF_ERR_EXIT(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   3796                         _SOC_IF_ERR_EXIT(portmod_xphy_lane_map_get(unit, xphy_id, &lane_map));
   3797                         _SOC_IF_ERR_EXIT(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   3798 
   3799                         /* for external phys, FW load method is default to Internal
   3800                         unless it is force to NONE. */
   3801                         core_conf.firmware_load_method = fw_load_method;
   3802                         core_conf.firmware_loader = NULL;
   3803 
   3804                         if (force_fw_load == phymodFirmwareLoadForce) {
   3805                             PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_conf);
   3806                         }
   3807                         else if (force_fw_load == phymodFirmwareLoadAuto) {
   3808                             PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_conf);
   3809                         }
   3810 
   3811                         /* config "no swap" for external phys.set later using APIs*/
   3812                         for(lane=0 ; lane < lane_map.num_of_lanes; lane++) {
   3813                             core_conf.lane_map.lane_map_rx[lane] = lane_map.lane_map_rx[lane];
   3814                             core_conf.lane_map.lane_map_tx[lane] = lane_map.lane_map_tx[lane];
   3815                         }
   3816                         if (xphy_id == primary_core_num) {
   3817                             _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   3818                              /* Very first time this function gets called, honor the call and 
   3819                               * ignore the flags */
   3820                              if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   3821                                  if (PM_4x10_INFO(pm_info)->first_phy == phy) {
   3822                                     _SOC_IF_ERR_EXIT(portmod_xphy_core_config_set(unit, xphy_id, &core_conf));
   3823                                  }
   3824                              }
   3825                         } else {
   3826                             _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_get(unit, primary_core_num, &is_initialized));
   3827                         } 
   3828 
   3829 
   3830                         if ((PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || init_all) &&
   3831                             (is_initialized & PHYMOD_CORE_INIT_F_EXECUTE_PASS1))
   3832                             continue;
   3833 
   3834                         if ((PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info) || init_all) &&
   3835                             (is_initialized & PHYMOD_CORE_INIT_F_EXECUTE_PASS2)) {
   3836                             continue;
   3837                         }
   3838 
   3839                         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   3840                         if (is_legacy_phy) {
   3841                             /* Dont do a core init for legacy Phys.*/
   3842                         } else {
   3843                            _SOC_IF_ERR_EXIT(phymod_core_init(&core_access, &core_conf, &core_status));
   3844                         }
   3845 
   3846                         if (init_all) {
   3847                             is_initialized = (PHYMOD_CORE_INIT_F_EXECUTE_PASS2 | PHYMOD_CORE_INIT_F_EXECUTE_PASS1);
   3848                         }
   3849                         else if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) {
   3850                             is_initialized |= PHYMOD_CORE_INIT_F_EXECUTE_PASS2;
   3851                         } else {
   3852                             is_initialized = PHYMOD_CORE_INIT_F_EXECUTE_PASS1;
   3853                         }
   3854 
   3855                         _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   3856 
   3857                         if (xphy_id != primary_core_num) {
   3858                             _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_set(unit, primary_core_num, is_initialized));
   3859                         }
   3860                     }
   3861                 }
   3862             }
   3863         }
   3864         temp++;
   3865     }
   3866 
   3867 exit:
   3868     SOC_FUNC_RETURN;
   3869 }
   3870 
   3871 
   3872 
   3873 STATIC
   3874 int _pm4x10_pm_core_init (int unit, int port,  pm_info_t pm_info, const portmod_port_add_info_t* add_info)
   3875 {
   3876     SOC_INIT_FUNC_DEFS;
   3877     _SOC_IF_ERR_EXIT(_pm4x10_pm_serdes_core_init(unit, port, pm_info, add_info));
   3878     _SOC_IF_ERR_EXIT(_pm4x10_pm_ext_phy_core_init(unit,pm_info,add_info));
   3879 
   3880 exit:
   3881     SOC_FUNC_RETURN;
   3882 }
   3883 
   3884 
   3885 STATIC
   3886 int _pm4x10_port_attach_core_probe (int unit, int port, pm_info_t pm_info, 
   3887                         const portmod_port_add_info_t* add_info)
   3888 {
   3889     int        port_index = -1, rv = 0, phy, i, phys_count = 0;
   3890     uint32     pm_is_active = 0;
   3891     portmod_pbmp_t port_phys_in_pm;
   3892     int first_phy = -1, phy_acc;
   3893     int prev_phy = -1;
   3894     int adjust_index = 0, three_ports_mode;
   3895     SOC_INIT_FUNC_DEFS;
   3896 
   3897     /* Get the first phy related to this port */
   3898     PORTMOD_PBMP_ASSIGN(port_phys_in_pm, add_info->phys);
   3899     PORTMOD_PBMP_AND(port_phys_in_pm, PM_4x10_INFO(pm_info)->phys);
   3900     PORTMOD_PBMP_COUNT(port_phys_in_pm, phys_count);
   3901 
   3902     /* if first phy is initialized and use it, default is -1 anyways */
   3903     first_phy = PM_4x10_INFO(pm_info)->first_phy;
   3904 
   3905     i = 0;
   3906     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {
   3907         if (prev_phy != -1) {
   3908             i += phy - prev_phy;
   3909         }
   3910 
   3911         if(PORTMOD_PBMP_MEMBER(port_phys_in_pm, phy)) {
   3912             rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD,
   3913                              pm_info->wb_vars_ids[ports], &port, i);
   3914             port_index = (port_index == -1 ? i : port_index);
   3915             _SOC_IF_ERR_EXIT(rv);
   3916             first_phy = (first_phy == -1) ? phy : first_phy;
   3917         }
   3918         prev_phy = phy;
   3919     }
   3920 
   3921 
   3922     PM_4x10_INFO(pm_info)->first_phy = first_phy;
   3923 
   3924     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   3925 
   3926     if(port_index<0 || port_index>=PM4X10_LANES_PER_CORE) {
   3927         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   3928                            (_SOC_MSG("can't attach port %d. can't find relevant phy"), port));
   3929     }
   3930 
   3931      rv = PM4x10_IS_HG_SET(unit, pm_info, add_info->init_config.is_hg,
   3932                           port_index);
   3933     _SOC_IF_ERR_EXIT(rv);
   3934     rv = PM4x10_AN_MODE_SET(unit, pm_info, add_info->init_config.an_mode,
   3935                             port_index);
   3936     _SOC_IF_ERR_EXIT(rv);
   3937     rv = PM4x10_FS_CL72_SET(unit, pm_info, add_info->init_config.fs_cl72,
   3938                             port_index);
   3939     _SOC_IF_ERR_EXIT(rv);
   3940     rv = PM4x10_CX4_10G_SET(unit, pm_info, add_info->init_config.cx4_10g,
   3941                             port_index);
   3942     _SOC_IF_ERR_EXIT(rv);
   3943     rv = PM4x10_AN_CL72_SET(unit, pm_info, add_info->init_config.an_cl72,
   3944                             port_index);
   3945     _SOC_IF_ERR_EXIT(rv);
   3946     rv = PM4x10_AN_FEC_SET(unit, pm_info, add_info->init_config.an_fec,
   3947                            port_index);
   3948     _SOC_IF_ERR_EXIT(rv);
   3949     rv = PM4x10_AN_CL37_SET(unit, pm_info, add_info->init_config.an_cl37,
   3950                             port_index);
   3951     _SOC_IF_ERR_EXIT(rv);
   3952     rv = PM4x10_AN_MASTER_LANE_SET(unit, pm_info,
   3953                                    add_info->init_config.an_master_lane,
   3954                                    port_index);
   3955     _SOC_IF_ERR_EXIT(rv);
   3956     rv = PM4x10_CL37_SGMII_CNT_SET(unit, pm_info,
   3957                                    add_info->init_config.cl37_sgmii_cnt,
   3958                                    port_index);
   3959     _SOC_IF_ERR_EXIT(rv);
   3960     rv = PM4x10_CL37_SGMII_RESTART_CNT_SET(unit, pm_info,
   3961                                   add_info->init_config.cl37_sgmii_RESTART_CNT,
   3962                                   port_index);
   3963     _SOC_IF_ERR_EXIT(rv);
   3964     rv = PM4x10_PORT_FALLBACK_LANE_SET(unit, pm_info,
   3965                                        add_info->init_config.port_fallback_lane,
   3966                                        port_index);
   3967     _SOC_IF_ERR_EXIT(rv);
   3968     rv = PM4x10_RXAUI_MODE_SET(unit, pm_info,
   3969                                add_info->init_config.rxaui_mode,
   3970                                port_index);
   3971     _SOC_IF_ERR_EXIT(rv);
   3972     rv = PM4x10_MAX_SPEED_SET(unit, pm_info,
   3973                               add_info->interface_config.max_speed, port_index);
   3974     _SOC_IF_ERR_EXIT(rv);
   3975     rv = PM4x10_INTERFACE_TYPE_SET(unit, pm_info,
   3976                                    add_info->interface_config.interface,
   3977                                    port_index);
   3978     _SOC_IF_ERR_EXIT(rv);
   3979     rv = PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info,
   3980                                                add_info->interface_config.interface,
   3981                                                port_index);
   3982     _SOC_IF_ERR_EXIT(rv); 
   3983     rv = PM4x10_SERDES_INTERFACE_TYPE_SET(unit, pm_info,
   3984                               add_info->interface_config.serdes_interface,
   3985                               port_index);
   3986     _SOC_IF_ERR_EXIT(rv);
   3987     rv = PM4x10_INTERFACE_MODES_SET(unit, pm_info,
   3988                                     add_info->interface_config.interface_modes,
   3989                                     port_index);
   3990     _SOC_IF_ERR_EXIT(rv);
   3991     rv = PM4x10_PORT_OP_MODE_SET(unit, pm_info,
   3992                                  add_info->interface_config.port_op_mode,
   3993                                  port_index);
   3994     _SOC_IF_ERR_EXIT(rv);
   3995 
   3996     rv = PM4x10_PORT_PLL_DIVIDER_REQ_SET(unit, pm_info,
   3997                                  add_info->init_config.pll_divider_req,
   3998                                  port_index);
   3999     _SOC_IF_ERR_EXIT(rv);
   4000 
   4001     for (adjust_index = 0; adjust_index < PORTMOD_TS_ADJUST_NUM; adjust_index++) {
   4002          rv = PM4x10_PORT_TIME_STAMP_ADJUST_SET(unit, pm_info,
   4003                                      &add_info->init_config.port_ts_adjust[adjust_index],
   4004                                      adjust_index, port_index);
   4005          _SOC_IF_ERR_EXIT(rv);
   4006     }
   4007 
   4008     if (add_info->init_config.polarity_overwrite == 1) {
   4009         sal_memcpy(&PM_4x10_INFO(pm_info)->polarity,
   4010             &add_info->init_config.polarity[PM_4x10_INFO(pm_info)->core_num_int],
   4011                sizeof(phymod_polarity_t));
   4012     }
   4013     if (add_info->init_config.lane_map_overwrite == 1) {
   4014         sal_memcpy(&PM_4x10_INFO(pm_info)->lane_map,
   4015             &add_info->init_config.lane_map[PM_4x10_INFO(pm_info)->core_num_int],
   4016                sizeof(phymod_lane_map_t));
   4017     }
   4018     if (add_info->init_config.ref_clk_overwrite == 1) {
   4019         PM_4x10_INFO(pm_info)->ref_clk = add_info->init_config.ref_clk;
   4020     }
   4021     if (add_info->init_config.fw_load_method_overwrite == 1) {
   4022         PM_4x10_INFO(pm_info)->fw_load_method =
   4023             add_info->init_config.fw_load_method[PM_4x10_INFO(pm_info)->core_num_int];
   4024     }
   4025     if (add_info->interface_config.interface == SOC_PORT_IF_QSGMII) {
   4026         PM_4x10_INFO(pm_info)->is_pm4x10q = 1;
   4027     }
   4028     /* port_index is 0, 1, 2, or 3 */
   4029     rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD,
   4030                             pm_info->wb_vars_ids[isActive], &pm_is_active);
   4031     _SOC_IF_ERR_EXIT(rv);
   4032 
   4033     /* if not active - initalize PM */
   4034     if(!pm_is_active){
   4035 #ifdef PORTMOD_PM12X10_SUPPORT
   4036         if(PM_4x10_INFO(pm_info)->in_pm12x10) {
   4037             PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {break;}
   4038             /* this will be redirected to pm12x10 */
   4039 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
   4040             
   4041             if (SOC_IS_APACHE(unit)) {
   4042                 rv = pm12x10_xgs_pm4x10_enable(unit, port, phy, 1);
   4043                 _SOC_IF_ERR_EXIT(rv);
   4044             } else
   4045 #endif
   4046             {
   4047                 rv = pm12x10_pm4x10_enable(unit, port, phy, 1);
   4048                 _SOC_IF_ERR_EXIT(rv);
   4049             }
   4050         }
   4051 #endif /* PORTMOD_PM12X10_SUPPORT */
   4052         three_ports_mode = (add_info->init_config.port_mode_aux_info == portmodModeInfoThreePorts) ? 1 : 0;
   4053         rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   4054                       pm_info->wb_vars_ids[threePortsMode], &three_ports_mode);
   4055         _SOC_IF_ERR_EXIT(rv);
   4056 
   4057         rv = _pm4x10_pm_xlport_init (unit, port, pm_info, port_index,
   4058                  phy_acc, add_info);
   4059         _SOC_IF_ERR_EXIT(rv);
   4060 
   4061         pm_is_active = 1;
   4062         rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   4063              pm_info->wb_vars_ids[isActive], &pm_is_active);
   4064         _SOC_IF_ERR_EXIT(rv);
   4065     }
   4066 
   4067     /*probe the core*/
   4068     rv = _pm4x10_pm_core_probe(unit, port, pm_info, add_info);
   4069     _SOC_IF_ERR_EXIT(rv);
   4070 
   4071 exit:
   4072     SOC_FUNC_RETURN;
   4073 }
   4074 
   4075 STATIC
   4076 int _pm4x10_port_attach_resume_fw_load (int unit, int port, pm_info_t pm_info, 
   4077                         const portmod_port_add_info_t* add_info)
   4078 {
   4079     int        port_index = -1, rv = 0, i, nof_phys, port_i;
   4080     uint32     bitmap;
   4081     int my_i, phy_acc, is_bypass, found_first_active_lane, itf_update = 0;
   4082     int fec_enable = 0;
   4083     phymod_interface_t          phymod_serdes_interface = phymodInterfaceCount; 
   4084     phymod_phy_init_config_t    phy_init_config;
   4085     phymod_phy_inf_config_t     *phy_interface_config = &phy_init_config.interface;
   4086     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4087     phymod_phy_access_t phy_access_lane;
   4088     portmod_port_ability_t port_ability;
   4089     portmod_access_get_params_t params;
   4090     soc_port_if_t interface = SOC_PORT_IF_NULL;
   4091     pm_version_t pm_version;
   4092     SOC_INIT_FUNC_DEFS;
   4093     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   4094 
   4095     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &is_bypass);
   4096     _SOC_IF_ERR_EXIT(rv);
   4097 
   4098     /* initialze phys */
   4099 
   4100     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   4101                                              &bitmap));
   4102 
   4103     /* clean up polarity and tx of phy_init_config */
   4104     _SOC_IF_ERR_EXIT(phymod_phy_init_config_t_init(&phy_init_config));
   4105 
   4106     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   4107     _SOC_IF_ERR_EXIT(pm4x10_port_phy_lane_access_get(unit, port, pm_info,
   4108                                 &params, 1, &phy_access_lane, &nof_phys, NULL));
   4109 
   4110     /*init the core*/
   4111     rv = _pm4x10_pm_core_init(unit, port, pm_info, add_info);
   4112     _SOC_IF_ERR_EXIT(rv);
   4113 
   4114     /* initalize port */
   4115     rv = _pm4x10_pm_port_init(unit, port, phy_acc, port_index, add_info, 1, pm_info);
   4116     _SOC_IF_ERR_EXIT(rv);
   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     my_i = 0;
   4122     found_first_active_lane = 0;
   4123     for(i=0 ; i<PM4X10_LANES_PER_CORE ; i++) {
   4124 
   4125         rv = SOC_WB_ENGINE_GET_ARR (unit, SOC_WB_ENGINE_PORTMOD,
   4126                          pm_info->wb_vars_ids[ports], &port_i, i);
   4127         _SOC_IF_ERR_EXIT(rv);
   4128 
   4129         if(port_i != port) {
   4130             /* There is a difference between XGS and DNX devices. For DNX, a port can consist inconsecutive physical lanes.
   4131              * For example, a port can consist lane 1 and 3 of the same core. For XGS, on the other hand, a port always consist 
   4132              * consecutive physical lanes. Therefore my_i below needs not be incremented for XGS devices. 
   4133              */
   4134             if(PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(PM_4x10_INFO(pm_info)->int_core_access.device_op_mode) && found_first_active_lane){
   4135                 my_i++;
   4136             }
   4137             continue;
   4138         } else {
   4139             found_first_active_lane = 1;
   4140         }
   4141 
   4142         if(SHR_BITGET(&PM_4x10_INFO(pm_info)->polarity.tx_polarity,i)) {
   4143             SHR_BITSET(&phy_init_config.polarity.tx_polarity, my_i);
   4144         }
   4145 
   4146         if(SHR_BITGET(&PM_4x10_INFO(pm_info)->polarity.rx_polarity,i)) {
   4147             SHR_BITSET(&phy_init_config.polarity.rx_polarity, my_i);
   4148         }
   4149         my_i++;
   4150     }
   4151 
   4152     _SOC_IF_ERR_EXIT(PM4x10_PORT_OP_MODE_SET(unit, pm_info,
   4153                                              add_info->phy_op_mode,
   4154                                              port_index));
   4155 
   4156     
   4157     _SOC_IF_ERR_EXIT(_pm4x10_port_interface_config_init_set(unit, port, pm_info,
   4158                                             &add_info->interface_config,
   4159                                             &add_info->init_config,
   4160                                             phy_init_config.tx,
   4161                                             phy_init_config.ext_phy_tx));
   4162 
   4163     /* get phy interface config details */
   4164 
   4165     _SOC_IF_ERR_EXIT(PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &interface,
   4166                                                port_index));
   4167     _SOC_IF_ERR_EXIT(
   4168             PM4x10_INTERFACE_MODES_GET(unit, pm_info,
   4169                                        &phy_interface_config->interface_modes,
   4170                                        port_index));
   4171 
   4172     /* add_info->interface_config->interface comes from soc_esw_portctrl_config_get()
   4173      * and is a very general value based on the port speed, number of lanes, and
   4174      * encap regardless of the underlying PM type and whether there is an ext PHY
   4175      * on the port. Here pm4x10 may change the default interface type under certain
   4176      * situations during system init according to the more fine-grained conditions.
   4177      */ 
   4178     if (nof_phys == 1) {
   4179         if ((add_info->interface_config.interface != add_info->interface_config.serdes_interface)
   4180             && (add_info->interface_config.serdes_interface != SOC_PORT_IF_NULL)) {
   4181             _SOC_IF_ERR_EXIT(_pm4x10_interface_check(unit, port, pm_info, &add_info->interface_config,
   4182                                                      add_info->interface_config.serdes_interface, &itf_update));
   4183             if (itf_update) {
   4184                 interface = add_info->interface_config.serdes_interface;
   4185             }
   4186         }
   4187 
   4188     if ((add_info->interface_config.speed == 42000 ||
   4189          add_info->interface_config.speed == 40000 ) &&
   4190             (phy_interface_config->interface_modes & PHYMOD_INTF_MODES_HIGIG) && !itf_update) {
   4191        _SOC_IF_ERR_EXIT(_pm4x10_default_interface_get(unit, port,
   4192                             &(add_info->interface_config), &interface));
   4193            itf_update = 1;
   4194         }
   4195 
   4196        /* Since the interface type written into the outmost PHY has changed,
   4197         * the software state also needs to be updated so that "ps" will show
   4198         * the correct interface type.
   4199         */
   4200        if (itf_update) {
   4201        _SOC_IF_ERR_EXIT
   4202            (PM4x10_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   4203        _SOC_IF_ERR_EXIT
   4204            (PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   4205     }
   4206     }
   4207 
   4208     _SOC_IF_ERR_EXIT(PM4x10_PORT_OP_MODE_GET(unit, pm_info,
   4209                                              &phy_init_config.op_mode,
   4210                                              port_index));
   4211 
   4212     _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit,
   4213                                add_info->interface_config.speed,
   4214                                interface,
   4215                                &phy_interface_config->interface_type));
   4216     phy_interface_config->data_rate = add_info->interface_config.speed;
   4217     phy_interface_config->pll_divider_req =
   4218                     add_info->init_config.pll_divider_req;
   4219     phy_interface_config->ref_clock = PM_4x10_INFO(pm_info)->ref_clk;
   4220 
   4221     _SOC_IF_ERR_EXIT(portmod_port_phychain_phy_init(unit, phy_access, nof_phys,
   4222                                                     &phy_init_config));
   4223 
   4224     /* enable fec if set, should be done before setting the speed */
   4225     fec_enable = add_info->init_config.serdes_fec_enable;
   4226 
   4227     if (fec_enable) {
   4228         int value = 0;
   4229 
   4230         /* FEC CL91 not supported on TSCE */
   4231         if (fec_enable != PORTMOD_PORT_FEC_CL74) {
   4232             _SOC_IF_ERR_EXIT(SOC_E_PARAM);
   4233         }
   4234 
   4235         value |= TRUE;
   4236         rv = pm4x10_port_fec_enable_set(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, value);
   4237         _SOC_IF_ERR_EXIT(rv);
   4238     }
   4239 
   4240     if (add_info->interface_config.serdes_interface != SOC_PORT_IF_NULL) {
   4241         _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, 
   4242                                 add_info->interface_config.speed, 
   4243                                 add_info->interface_config.serdes_interface, 
   4244                                 &phymod_serdes_interface));
   4245     }
   4246 
   4247     /* store the speed in PM database */
   4248     _SOC_IF_ERR_EXIT(PM4x10_SPEED_SET(unit, pm_info,
   4249                                       add_info->interface_config.speed,
   4250                                       port_index));
   4251 
   4252 
   4253     /* Apply to ALL PHY with same interface config */
   4254     _SOC_IF_ERR_EXIT(
   4255             portmod_port_phychain_interface_config_set(unit, port, phy_access, nof_phys,
   4256                                           add_info->interface_config.flags ,
   4257                                           phy_interface_config,
   4258                                           phymod_serdes_interface,
   4259                                           PM_4x10_INFO(pm_info)->ref_clk,
   4260                                           PORTMOD_INIT_F_ALL_PHYS));
   4261 
   4262 
   4263     if(add_info->init_config.fs_cl72) {
   4264        /* config port_init_cl72 is used to enable fs cl72 only in the serdes,
   4265         do not enable cl72 on external phys. Set the no of phys argument to 1 to avoid setting cl72 enable 
   4266         on ext phys */
   4267        /* need to check if multi core and not pcs by pass mode */
   4268        if ((phy_interface_config->data_rate >= 100000) &&
   4269            (phy_interface_config->interface_type != phymodInterfaceBypass)) {
   4270             uint32_t temp_flag = add_info->interface_config.flags;
   4271             if (temp_flag == PHYMOD_INTF_F_SET_SPD_NO_TRIGGER) {
   4272                 _SOC_IF_ERR_EXIT(portmod_port_phychain_cl72_set(unit, port, phy_access, 1, 1));
   4273             }
   4274        } else {
   4275                 _SOC_IF_ERR_EXIT(portmod_port_phychain_cl72_set(unit, port, phy_access, 1, 1));
   4276        }
   4277     }
   4278     /* set the default advert ability */
   4279     _SOC_IF_ERR_EXIT
   4280         (pm4x10_port_ability_local_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &port_ability));
   4281     _SOC_IF_ERR_EXIT
   4282         (pm4x10_port_ability_advert_set(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &port_ability));
   4283 
   4284     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   4285     if (PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   4286         /* Set PMD TXPI mode */
   4287         _SOC_IF_ERR_EXIT(_pm4x10_port_phy_txpi_mode_set(unit, port, pm_info, add_info->init_config.txpi_mode));
   4288     }
   4289 
   4290     /* De-Assert SOFT_RESET */
   4291         _SOC_IF_ERR_EXIT(pm4x10_port_soft_reset(unit, port, pm_info, 0));
   4292 
   4293 exit:
   4294     SOC_FUNC_RETURN;
   4295 
   4296 }
   4297 
   4298 STATIC
   4299 int _pm4x10_an_mode_update (int unit, int port, pm_info_t pm_info,
   4300                             int an_cl37, int an_cl73)
   4301 {
   4302     int is_hg, rv;
   4303     phymod_an_mode_type_t an_mode;
   4304     int    port_index;
   4305     uint32_t bitmap;
   4306 
   4307     SOC_INIT_FUNC_DEFS;
   4308     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   4309                                              &bitmap));
   4310 
   4311     rv = PM4x10_IS_HG_GET(unit, pm_info, &is_hg, port_index);
   4312     _SOC_IF_ERR_EXIT(rv);
   4313     rv = PM4x10_AN_MODE_GET(unit, pm_info, &an_mode, port_index);
   4314     _SOC_IF_ERR_EXIT(rv);
   4315     if(is_hg) {
   4316         an_mode = phymod_AN_MODE_CL37BAM ;
   4317         if (an_cl37 == PORTMOD_CL37_W_BAM_HG) {
   4318             an_mode = phymod_AN_MODE_CL37BAM_10P9375G_VCO;
   4319         }
   4320     } else {
   4321         if (an_cl73) {
   4322             switch (an_cl73) {
   4323                 case PORTMOD_CL73_W_BAM:
   4324                     an_mode = phymod_AN_MODE_CL73BAM;
   4325                     break;
   4326              /* case PORTMOD_CL73_WO_BAM:
   4327               *     an_mode = phymod_AN_MODE_CL73;
   4328               *     break;
   4329               */
   4330                 default:
   4331                     an_mode = phymod_AN_MODE_CL73;
   4332                     break;
   4333             }
   4334         } else {
   4335             switch (an_cl37) {
   4336                 case PORTMOD_CL37_SGMII_COMBO:
   4337                     an_mode = phymod_AN_MODE_CL37_SGMII;
   4338                     break;
   4339                 case PORTMOD_CL37_W_BAM:
   4340                     an_mode = phymod_AN_MODE_CL37BAM;
   4341                     break;
   4342                 case PORTMOD_CL37_WO_BAM:
   4343                     an_mode = phymod_AN_MODE_CL37;
   4344                     break;
   4345                 default:
   4346                     an_mode = phymod_AN_MODE_CL37;
   4347                     break;
   4348             }
   4349         }
   4350     }
   4351 
   4352     rv = PM4x10_AN_MODE_SET(unit, pm_info, an_mode, port_index);
   4353     _SOC_IF_ERR_EXIT(rv);
   4354 exit:
   4355     SOC_FUNC_RETURN;
   4356 }
   4357 
   4358 
   4359 int pm4x10_port_attach (int unit, int port, pm_info_t pm_info, 
   4360                         const portmod_port_add_info_t* add_info)
   4361 {
   4362     phymod_phy_access_t serdes_access;
   4363 
   4364     int init_all = (!PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) &&
   4365                     !PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) &&
   4366                     !PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info)) ? 1 : 0;
   4367 
   4368     if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) || (init_all)) {
   4369         SOC_IF_ERROR_RETURN(_pm4x10_port_attach_core_probe (unit, port, pm_info, add_info));
   4370     }
   4371 
   4372     if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) &&
   4373         !PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   4374         return (SOC_E_NONE);
   4375     }
   4376 
   4377     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info) || (init_all)) {
   4378 
   4379         if (!PORTMOD_PORT_ADD_F_AUTONEG_CONFIG_SKIP_GET(add_info))
   4380         {
   4381             SOC_IF_ERROR_RETURN(_pm4x10_an_mode_update (unit, port, pm_info,
   4382                                               add_info->init_config.an_cl37,
   4383                                               add_info->init_config.an_cl73));
   4384         }
   4385 
   4386         if (PM_4x10_INFO(pm_info)->rescal != -1) {
   4387             sal_memcpy(&serdes_access, &(PM_4x10_INFO(pm_info)->int_core_access), sizeof(phymod_phy_access_t));
   4388             phymod_phy_rescal_set(&serdes_access, 1, PM_4x10_INFO(pm_info)->rescal);
   4389         }
   4390 
   4391         SOC_IF_ERROR_RETURN(_pm4x10_pm_core_init(unit, port, pm_info, add_info));
   4392     }
   4393 
   4394     if (PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) {
   4395         return (SOC_E_NONE);
   4396     }
   4397 
   4398     SOC_IF_ERROR_RETURN(_pm4x10_port_attach_resume_fw_load (unit, port, pm_info, add_info));
   4399 
   4400     return (SOC_E_NONE);
   4401 }
   4402 
   4403 
   4404 int pm4x10_port_detach(int unit, int port, pm_info_t pm_info)
   4405 {
   4406     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4407     phymod_phy_inf_config_t phy_interface_config;
   4408 
   4409     int     tmp_port, i=0, rv=0, port_index = -1, nof_phys;
   4410     int     invalid_port = -1, is_last_one = TRUE, phy_acc;
   4411     int     phytype;
   4412     uint32  inactive = 0;
   4413 
   4414     SOC_INIT_FUNC_DEFS;
   4415 
   4416     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   4417 
   4418     /* in case of 100G disable the speed for the port */
   4419     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,(1+MAX_PHYN), &nof_phys));
   4420 
   4421    if( (nof_phys > 1) && (phy_access[nof_phys-1].access.lane_mask == 0) ) {
   4422         nof_phys = 1;
   4423     }
   4424 
   4425     _SOC_IF_ERR_EXIT(portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   4426                                    0, PM_4x10_INFO(pm_info)->ref_clk, &phy_interface_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   4427 
   4428     if ( phy_interface_config.data_rate >= 100000 ) {
   4429         _SOC_IF_ERR_EXIT(portmod_port_phychain_interface_config_set(unit, port, phy_access, nof_phys,
   4430                                    PHYMOD_INTF_F_SET_SPD_DISABLE,
   4431                                    &phy_interface_config, phy_interface_config.interface_type, 
   4432                                    PM_4x10_INFO(pm_info)->ref_clk,
   4433                                    PORTMOD_INIT_F_ALL_PHYS ));
   4434         _SOC_IF_ERR_EXIT(portmod_port_phychain_interface_config_set(unit, port, phy_access, nof_phys,
   4435                                    PHYMOD_INTF_F_SPEED_CONFIG_CLEAR,
   4436                                    &phy_interface_config, phy_interface_config.interface_type,
   4437                                    PM_4x10_INFO(pm_info)->ref_clk,
   4438                                    PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   4439     }
   4440 
   4441 
   4442     /*remove from array and check if it was the last one*/
   4443     for( i = 0 ; i < MAX_PORTS_PER_PM4X10; i++) {
   4444        rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, 
   4445                     pm_info->wb_vars_ids[ports], &tmp_port, i);
   4446        _SOC_IF_ERR_EXIT(rv);
   4447 
   4448        if(tmp_port == port){
   4449            port_index = (port_index == -1 ? i : port_index);
   4450            rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, 
   4451                     pm_info->wb_vars_ids[ports], &invalid_port, i);
   4452            _SOC_IF_ERR_EXIT(rv);
   4453        } else if (tmp_port != -1) {
   4454            is_last_one = FALSE;
   4455        }
   4456     }
   4457 
   4458     if(port_index == -1) { 
   4459         _SOC_EXIT_WITH_ERR(SOC_E_PORT,(_SOC_MSG("Port %d wasn't found"),port));
   4460     }   
   4461 
   4462     rv = _pm4x10_pm_port_init(unit, port, phy_acc, port_index, NULL, 0, pm_info);
   4463     _SOC_IF_ERR_EXIT(rv);
   4464 
   4465     /*deinit PM in case of last one*/
   4466     if (is_last_one) {
   4467        rv = _pm4x10_pm_disable(unit, port, pm_info, phy_acc);
   4468        _SOC_IF_ERR_EXIT(rv);
   4469 
   4470        PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_CLR(PM_4x10_INFO(pm_info)->int_core_access.device_op_mode);
   4471 
   4472 #ifdef PORTMOD_PM12X10_SUPPORT
   4473        if(PM_4x10_INFO(pm_info)->in_pm12x10) {
   4474            uint32 phy;
   4475            PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy) {break;};
   4476             /* this will be redirected to pm12x10 */
   4477 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
   4478             
   4479             if (SOC_IS_APACHE(unit)) {
   4480                 rv = pm12x10_xgs_pm4x10_enable(unit, port, phy, 1);
   4481                 _SOC_IF_ERR_EXIT(rv);
   4482             } else
   4483 #endif
   4484             {
   4485                 rv = pm12x10_pm4x10_enable(unit, port, phy, 0);
   4486                 _SOC_IF_ERR_EXIT(rv);
   4487             }
   4488         }
   4489 #endif /* PORTMOD_PM12X10_SUPPORT */
   4490 
   4491        rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, 
   4492                              pm_info->wb_vars_ids[isActive], &inactive);
   4493        _SOC_IF_ERR_EXIT(rv);
   4494 
   4495        rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   4496                                    pm_info->wb_vars_ids[isInitialized],
   4497                                    &inactive);
   4498        _SOC_IF_ERR_EXIT(rv);
   4499 
   4500        rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD,
   4501                                    pm_info->wb_vars_ids[isBypassed], &inactive);
   4502        _SOC_IF_ERR_EXIT(rv);
   4503        /* Updating phymod type in pm_info structure and warmboot engine */
   4504        phytype = phymodDispatchTypeInvalid;
   4505        rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phy_type], &phytype, 0);
   4506        _SOC_IF_ERR_EXIT(rv);
   4507        PM_4x10_INFO(pm_info)->int_core_access.type = phymodDispatchTypeInvalid;
   4508        PM_4x10_INFO(pm_info)->is_pm4x10q = 0;
   4509     }
   4510 
   4511 exit:
   4512     SOC_FUNC_RETURN;
   4513 }
   4514 
   4515 int pm4x10_port_replace(int unit, int port, pm_info_t pm_info, int new_port)
   4516 {
   4517     int i, tmp_port;
   4518     int rv = 0;
   4519     SOC_INIT_FUNC_DEFS;
   4520 
   4521     /* replace old port with new port */
   4522     for (i = 0; i < MAX_PORTS_PER_PM4X10; i++) {
   4523         rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, 
   4524                      pm_info->wb_vars_ids[ports], &tmp_port, i);
   4525         _SOC_IF_ERR_EXIT(rv);
   4526        
   4527         if (tmp_port == port){
   4528             rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, 
   4529                              pm_info->wb_vars_ids[ports], &new_port, i);
   4530             _SOC_IF_ERR_EXIT(rv);                
   4531         }
   4532     }
   4533         
   4534 exit:
   4535     SOC_FUNC_RETURN; 
   4536     
   4537 }
   4538 
   4539 int pm4x10_pm_bypass_set(int unit, pm_info_t pm_info, int bypass_enable)
   4540 {
   4541     int     rv = 0;
   4542     uint32  pm_is_active = 0;
   4543     uint32 is_bypass;
   4544 
   4545     SOC_INIT_FUNC_DEFS;
   4546 
   4547     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &is_bypass);
   4548     _SOC_IF_ERR_EXIT(rv);
   4549 
   4550     if (bypass_enable != is_bypass) {
   4551         rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active);
   4552         _SOC_IF_ERR_EXIT(rv);
   4553 
   4554         if(pm_is_active) {
   4555             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("can't chenge bypass mode for active pm")));
   4556         }
   4557 
   4558         rv = SOC_WB_ENGINE_SET_VAR (unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isBypassed], &bypass_enable);
   4559         _SOC_IF_ERR_EXIT(rv);
   4560 
   4561     }
   4562 
   4563 
   4564 exit:
   4565     SOC_FUNC_RETURN;
   4566 }
   4567 
   4568 int pm4x10_pm_core_info_get(int unit, pm_info_t pm_info, int phyn, portmod_pm_core_info_t* core_info)
   4569 {
   4570     core_info->ref_clk = PM_4x10_INFO(pm_info)->ref_clk;
   4571     return SOC_E_NONE;
   4572 }
   4573 
   4574 int pm4x10_pm_phys_get(int unit, pm_info_t pm_info, portmod_pbmp_t* phys)
   4575 {
   4576     SOC_INIT_FUNC_DEFS;
   4577     PORTMOD_PBMP_ASSIGN(*phys, PM_4x10_INFO(pm_info)->phys);
   4578     SOC_FUNC_RETURN;
   4579 }
   4580 
   4581 int pm4x10_port_enable_set (int unit, int port, pm_info_t pm_info, 
   4582                             int flags, int enable)
   4583 {
   4584     uint32  is_bypassed = 0, phychain_flag;
   4585     int     rv = 0, rst_flags = 0;
   4586     int     actual_flags = flags, nof_phys = 0, xlmac_flags = 0;
   4587     phymod_phy_power_t           phy_power;
   4588     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4589 
   4590     SOC_INIT_FUNC_DEFS;
   4591 
   4592     /* If no Rx/Tx flags - set both */
   4593     if ((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && 
   4594         (!PORTMOD_PORT_ENABLE_RX_GET(flags)))
   4595     {
   4596         PORTMOD_PORT_ENABLE_RX_SET(actual_flags);
   4597         PORTMOD_PORT_ENABLE_TX_SET(actual_flags);
   4598     }
   4599 
   4600     /* If no Mac/Phy flags - set both */
   4601     if ((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) &&
   4602         (!PORTMOD_PORT_ENABLE_MAC_GET(flags)))
   4603     {
   4604         PORTMOD_PORT_ENABLE_PHY_SET(actual_flags);
   4605         PORTMOD_PORT_ENABLE_MAC_SET(actual_flags);
   4606     }
   4607 
   4608      /* if MAC is set and either RX or TX set is invalid combination */
   4609     if( (PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) ) {
   4610         if((!PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) || (!PORTMOD_PORT_ENABLE_RX_GET(actual_flags))){
   4611             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("MAC RX and TX can't be enabled separately")));
   4612         }
   4613     }
   4614 
   4615     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, 
   4616                                pm_info->wb_vars_ids[isBypassed], &is_bypassed);
   4617     _SOC_IF_ERR_EXIT(rv);
   4618 
   4619     _SOC_IF_ERR_EXIT(phymod_phy_power_t_init(&phy_power));
   4620     phy_power.rx = phymodPowerNoChange;
   4621     phy_power.tx = phymodPowerNoChange;
   4622 
   4623     if(PORTMOD_PORT_ENABLE_RX_GET(actual_flags)){
   4624         phy_power.rx = (enable) ? phymodPowerOn : phymodPowerOff;
   4625         xlmac_flags |= XLMAC_ENABLE_SET_FLAGS_RX_EN;
   4626     }
   4627     if(PORTMOD_PORT_ENABLE_TX_GET(actual_flags)){
   4628         phy_power.tx = (enable) ? phymodPowerOn : phymodPowerOff;
   4629         xlmac_flags |= XLMAC_ENABLE_SET_FLAGS_TX_EN;
   4630     }
   4631 
   4632     /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/
   4633     phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 
   4634         PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 
   4635         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ;
   4636 
   4637     if(enable){
   4638         if((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!is_bypassed)){
   4639               if(PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   4640                 rst_flags |= XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
   4641             }    
   4642             rv = xlmac_enable_set(unit, port, rst_flags, 1);
   4643             _SOC_IF_ERR_EXIT(rv);
   4644               if(PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   4645                 _SOC_IF_ERR_EXIT(pm4x10_port_soft_reset(unit, port, pm_info, 0));
   4646             }
   4647         }
   4648 
   4649         if(PORTMOD_PORT_ENABLE_PHY_GET(actual_flags))
   4650         {
   4651             _SOC_IF_ERR_EXIT
   4652                 (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4653                                                   phy_access ,(1+MAX_PHYN),
   4654                                                   &nof_phys));
   4655 
   4656             _SOC_IF_ERR_EXIT
   4657                 (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power));
   4658 
   4659                 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   4660                     _SOC_IF_ERR_EXIT
   4661                     (portmod_port_phychain_tx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag,
   4662                                                            phymodTxSquelchOff));
   4663                 }
   4664 
   4665                 if(PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   4666                     _SOC_IF_ERR_EXIT
   4667                     (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag,
   4668                                                           phymodRxSquelchOff));  
   4669                 }
   4670 
   4671         }
   4672     } else {
   4673         if (PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) {
   4674             _SOC_IF_ERR_EXIT
   4675                 (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   4676                                                   phy_access ,(1+MAX_PHYN),
   4677                                                    &nof_phys));
   4678 
   4679                 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   4680                     _SOC_IF_ERR_EXIT
   4681                     (portmod_port_phychain_tx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag,
   4682                                                            phymodTxSquelchOn));
   4683                 }
   4684 
   4685                 if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   4686                     _SOC_IF_ERR_EXIT
   4687                     (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag,
   4688                                                           phymodRxSquelchOn));  
   4689                 }
   4690 
   4691             _SOC_IF_ERR_EXIT
   4692                 (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power));
   4693         }
   4694 
   4695         /* if((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags))  && (!is_bypassed)){ */
   4696         /* Not checking is_bypassed as if clmac was enable before bypass was set */
   4697         if((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) ){
   4698             rv = xlmac_enable_set(unit, port, xlmac_flags, 0);
   4699             _SOC_IF_ERR_EXIT(rv);
   4700         }
   4701     }
   4702 
   4703 exit:
   4704     SOC_FUNC_RETURN;
   4705 }
   4706 
   4707 int pm4x10_port_enable_get (int unit, int port, pm_info_t pm_info, int flags, 
   4708                             int* enable)
   4709 {
   4710     uint32  is_bypassed = 0, phychain_flag;
   4711     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4712     int nof_phys = 0;
   4713     phymod_phy_tx_lane_control_t tx_control = phymodTxSquelchOn;
   4714     phymod_phy_rx_lane_control_t rx_control = phymodRxSquelchOn;
   4715     int phy_enable = 1, mac_enable = 1;
   4716     int mac_rx_enable = 0, mac_tx_enable = 0;
   4717     int actual_flags = flags;
   4718     SOC_INIT_FUNC_DEFS;
   4719     SOC_NULL_CHECK(pm_info);
   4720 
   4721     /* If no RX\TX flags - set both*/
   4722     if((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && (!PORTMOD_PORT_ENABLE_RX_GET(flags))){
   4723         PORTMOD_PORT_ENABLE_RX_SET(actual_flags);
   4724         PORTMOD_PORT_ENABLE_TX_SET(actual_flags);
   4725     }
   4726 
   4727     /* if no MAC\Phy flags - set both*/
   4728     if((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) && (!PORTMOD_PORT_ENABLE_MAC_GET(flags))){
   4729         PORTMOD_PORT_ENABLE_PHY_SET(actual_flags);
   4730         PORTMOD_PORT_ENABLE_MAC_SET(actual_flags);
   4731     }
   4732 
   4733     /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/
   4734     phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 
   4735         PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 
   4736         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ;
   4737 
   4738     if (PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) {
   4739 
   4740         _SOC_IF_ERR_EXIT
   4741             (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys));
   4742 
   4743         _SOC_IF_ERR_EXIT
   4744             (portmod_port_phychain_tx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &tx_control));
   4745         _SOC_IF_ERR_EXIT
   4746             (portmod_port_phychain_rx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &rx_control));
   4747 
   4748         phy_enable = 0;
   4749 
   4750         if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   4751             phy_enable |= (rx_control == phymodRxSquelchOn) ? 0 : 1;
   4752         } 
   4753         if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   4754             phy_enable |= (tx_control == phymodTxSquelchOn) ? 0 : 1;
   4755         }
   4756     } 
   4757 
   4758     _SOC_IF_ERR_EXIT(SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, 
   4759                      pm_info->wb_vars_ids[isBypassed], &is_bypassed));
   4760 
   4761     if ((PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!is_bypassed)) {
   4762 
   4763         mac_enable = 0;
   4764 
   4765         if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) {
   4766             _SOC_IF_ERR_EXIT(xlmac_enable_get(unit, port, XLMAC_ENABLE_SET_FLAGS_RX_EN, &mac_rx_enable));
   4767             mac_enable |= (mac_rx_enable) ? 1 : 0;
   4768         }
   4769         if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) {
   4770             _SOC_IF_ERR_EXIT(xlmac_enable_get(unit, port, XLMAC_ENABLE_SET_FLAGS_TX_EN, &mac_tx_enable));
   4771             mac_enable |= (mac_tx_enable) ? 1 : 0;
   4772         }
   4773     }
   4774 
   4775     *enable = (mac_enable && phy_enable);
   4776 
   4777 exit:
   4778     SOC_FUNC_RETURN;
   4779 }
   4780 
   4781 int pm4x10_port_interface_check(int unit, int port, pm_info_t pm_info,
   4782                                 const portmod_port_interface_config_t* config,
   4783                                 int is_ext_phy, soc_port_if_t interface,
   4784                                 int* is_valid)
   4785 {
   4786     int nof_phys = 0;
   4787     phymod_phy_access_t phy_access[1+MAX_PHYN];
   4788     SOC_INIT_FUNC_DEFS;
   4789 
   4790     _SOC_IF_ERR_EXIT
   4791         (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys));
   4792 
   4793     if (is_ext_phy && nof_phys < 2) {
   4794         return SOC_E_PARAM;
   4795     }
   4796 
   4797     if (is_ext_phy) {
   4798         _SOC_IF_ERR_EXIT(_pm4x10_ext_phy_interface_check(unit, port, &phy_access[nof_phys-1], config,
   4799                                                          interface, is_valid));
   4800     } else {
   4801         _SOC_IF_ERR_EXIT(_pm4x10_interface_check(unit, port, pm_info, config, interface, is_valid));
   4802     }
   4803 
   4804 exit:
   4805     SOC_FUNC_RETURN;
   4806 }
   4807 
   4808 int pm4x10_port_interface_config_set(int unit, int port, 
   4809                         pm_info_t pm_info, 
   4810                         const portmod_port_interface_config_t* config,
   4811                         int phy_init_flags)
   4812 {
   4813     uint32 reg_val;
   4814     uint32 pm_is_bypassed = 0, pm_is_initialized = 0; 
   4815     int    nof_phys = 0, rv = 0, phy_acc, flags = 0;
   4816     phymod_phy_access_t phy_access_arr[1+MAX_PHYN];
   4817     phymod_phy_access_t         phy_access;
   4818     phymod_phy_inf_config_t     phy_interface_config, cur_phy_if_config;
   4819     portmod_access_get_params_t params;
   4820     int                         port_index;
   4821     uint32_t                    bitmap;
   4822     portmod_port_interface_config_t  config_temp ;
   4823     phymod_interface_t   phymod_interface;
   4824     phymod_interface_t   phymod_serdes_interface = phymodInterfaceCount;
   4825     phymod_tx_t          tx_params[PHYMOD_MAX_LANES_PER_CORE];
   4826     phymod_tx_t          ext_phy_tx_params[PHYMOD_MAX_LANES_PER_CORE];
   4827     soc_port_if_t        interface = SOC_PORT_IF_NULL;
   4828     int is_legacy_phy = 0;
   4829     int i, xphy_id;
   4830     int is_higig, rxaui_mode, fs_cl72;
   4831     uint32 is_interface_restore, interface_modes, port_dynamic_state;
   4832     int is_legacy_phy_callback = 0;
   4833     portmod_port_ts_adjust_t ts_adjust;
   4834     int mac_ts_enable;
   4835 #ifdef PORTMOD_PM12X10_SUPPORT
   4836     soc_100g_lane_config_t          lane_config=0;
   4837 #endif
   4838     SOC_INIT_FUNC_DEFS;
   4839 
   4840     sal_memset(&ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   4841 
   4842     /* 
   4843      * Ignore the call to interface config set if the pm is not iniialized.
   4844      * This happens if the legacy external phy does a call back prior to initializing
   4845      * and probing internal phys 
   4846      */  
   4847     rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   4848                                 pm_info->wb_vars_ids[isInitialized], 
   4849                                 &pm_is_initialized);
   4850     _SOC_IF_ERR_EXIT(rv);
   4851     if (!pm_is_initialized) return (SOC_E_NONE);
   4852 
   4853 
   4854     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   4855 
   4856     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   4857                                              &bitmap));
   4858     _SOC_IF_ERR_EXIT(PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   4859                                             &port_dynamic_state, port_index));
   4860 
   4861     if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
   4862         _SOC_IF_ERR_EXIT(pm4x10_port_mac_timestamp_enable_get(unit, port, pm_info,
   4863                                                               &mac_ts_enable));
   4864     } else {
   4865         mac_ts_enable = 1;
   4866     }
   4867 
   4868     is_higig =  ((config->encap_mode == SOC_ENCAP_HIGIG2) ||
   4869                  (config->encap_mode == SOC_ENCAP_HIGIG) ||
   4870                  PHYMOD_INTF_MODES_HIGIG_GET(config)) ? 1 : 0;
   4871 
   4872     if (config->flags & PHYMOD_INTF_F_UPDATE_SPEED_LINKUP) {
   4873         int mac_speed = 0, serdes_speed = 0, mac_only = 0;
   4874         int nof_lanes = SOC_INFO(unit).port_num_lanes[port];
   4875 
   4876         _SOC_IF_ERR_EXIT(portmod_port_speed_get(unit, port, &serdes_speed));
   4877         if (config->speed == serdes_speed) {
   4878             xlmac_speed_get(unit, port, &mac_speed);
   4879             mac_speed *= nof_lanes;
   4880             if (config->speed == mac_speed) {
   4881                 SOC_FUNC_RETURN;
   4882             }
   4883 
   4884             mac_only = 1;
   4885         }
   4886 
   4887         flags = XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   4888         _SOC_IF_ERR_EXIT(xlmac_speed_set(unit, port, flags, config->speed));
   4889 
   4890         if (mac_ts_enable) {
   4891             /*Set MAC Timestamp Delay*/
   4892             if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   4893                 _SOC_IF_ERR_EXIT(_pm4x10_port_timestamp_adjust_wb_get(unit, port, pm_info, config->speed, &ts_adjust));
   4894                 _SOC_IF_ERR_EXIT(xlmac_timestamp_delay_set(unit, port, ts_adjust, config->speed));
   4895             }
   4896             _SOC_IF_ERR_EXIT(xlmac_timestamp_byte_adjust_set(unit, port, 0, config->speed));
   4897         }
   4898 
   4899         if (mac_only) {
   4900             /* line side speed and SerDes speed are equal, no need update SerDes configuration */
   4901             SOC_FUNC_RETURN;
   4902         }
   4903 
   4904         phy_init_flags = PORTMOD_INIT_F_ALL_PHYS;
   4905     }
   4906 
   4907     if ((config->encap_mode == SOC_ENCAP_HIGIG2) ||
   4908         (config->encap_mode == SOC_ENCAP_HIGIG)  ||
   4909         (PHYMOD_INTF_MODES_HIGIG_GET(config))) {
   4910         rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   4911                                         port_index);
   4912         _SOC_IF_ERR_EXIT(rv);
   4913         interface_modes |= PHYMOD_INTF_MODES_HIGIG;
   4914         rv = PM4x10_INTERFACE_MODES_SET(unit, pm_info, interface_modes,
   4915                                         port_index);
   4916         _SOC_IF_ERR_EXIT(rv);
   4917     } else if ((config->encap_mode == SOC_ENCAP_IEEE)) {
   4918         rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   4919         _SOC_IF_ERR_EXIT(rv);
   4920         interface_modes &= ~PHYMOD_INTF_MODES_HIGIG;
   4921         rv = PM4x10_INTERFACE_MODES_SET(unit, pm_info, interface_modes, port_index);
   4922         _SOC_IF_ERR_EXIT(rv);
   4923     }
   4924 
   4925     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   4926     params.phyn = 0;
   4927     params.lane = -1;
   4928     params.sys_side = PORTMOD_SIDE_LINE;
   4929 
   4930     _SOC_IF_ERR_EXIT(pm4x10_port_phy_lane_access_get(unit, port, pm_info,
   4931                                     &params, 1, &phy_access, &nof_phys, NULL));
   4932 
   4933     _SOC_IF_ERR_EXIT
   4934         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   4935             phy_access_arr ,(1+MAX_PHYN), &nof_phys));
   4936 
   4937     rv = SOC_WB_ENGINE_GET_VAR (unit, SOC_WB_ENGINE_PORTMOD, 
   4938                                 pm_info->wb_vars_ids[isBypassed], 
   4939                                 &pm_is_bypassed);
   4940     _SOC_IF_ERR_EXIT(rv);
   4941 
   4942     if(config->flags & PHYMOD_INTF_F_INTF_PARAM_SET_ONLY) {
   4943         /* Update the software state of the interface type. Note that currently
   4944          * the legacy ext PHY does not raise the PHYMOD_INTF_F_INTF_PARAM_SET_ONLY
   4945          * flag so that the following function call cannot be reached when a legacy
   4946          * ext PHY uses the portmod callback function to set the interface type
   4947          * of the internal PHY.
   4948          */
   4949             rv = PM4x10_INTERFACE_TYPE_SET(unit, pm_info, config->interface,
   4950                                            port_index);
   4951             _SOC_IF_ERR_EXIT(rv);
   4952 
   4953             is_interface_restore = 1;
   4954             rv = PM4x10_IS_INTERFACE_RESTORE_SET(unit, pm_info,
   4955                                                  is_interface_restore, port_index);
   4956             _SOC_IF_ERR_EXIT(rv);
   4957 
   4958         SOC_FUNC_RETURN;
   4959     }
   4960 
   4961     rv = PM4x10_IS_INTERFACE_RESTORE_GET(unit, pm_info, &is_interface_restore,
   4962                                              port_index);
   4963     _SOC_IF_ERR_EXIT(rv);
   4964     /*
   4965          * if the interface is already set with PARAM_SET_ONLY
   4966          * h/w interface needs to be updated during speed set.
   4967          * So load the interface information and clear the flag;
   4968          */
   4969     if(is_interface_restore) {
   4970         rv = PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index);
   4971         _SOC_IF_ERR_EXIT(rv);
   4972         ((portmod_port_interface_config_t*)config)->interface = interface;
   4973 
   4974         is_interface_restore = 0;
   4975         rv = PM4x10_IS_INTERFACE_RESTORE_SET(unit, pm_info,
   4976                                        is_interface_restore, port_index);
   4977         _SOC_IF_ERR_EXIT(rv);
   4978     }
   4979 
   4980     if (!(config->flags & (PHYMOD_INTF_F_SET_SPD_TRIGGER | PHYMOD_INTF_F_UPDATE_SPEED_LINKUP)) && (!pm_is_bypassed)){
   4981 
   4982         rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   4983                                         port_index);
   4984         _SOC_IF_ERR_EXIT(rv);
   4985         /* set HiG mode */
   4986         _SOC_IF_ERR_EXIT(READ_XLPORT_CONFIGr(unit, phy_acc, &reg_val));
   4987         soc_reg_field_set (unit, XLPORT_CONFIGr, &reg_val, HIGIG2_MODEf, 
   4988                            (interface_modes & PHYMOD_INTF_MODES_HIGIG)? 1: 0);
   4989         _SOC_IF_ERR_EXIT(WRITE_XLPORT_CONFIGr(unit, phy_acc, reg_val));
   4990 
   4991         /* set port speed */
   4992         flags = XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   4993         rv = xlmac_speed_set(unit, port, flags, config->speed);
   4994         _SOC_IF_ERR_EXIT(rv);
   4995 
   4996         /*Set Timestamp Mac Delays*/
   4997         if (mac_ts_enable) {
   4998             if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   4999                 _SOC_IF_ERR_EXIT
   5000                     (_pm4x10_port_timestamp_adjust_wb_get(unit,
   5001                                                           port,
   5002                                                           pm_info,
   5003                                                           config->speed,
   5004                                                           &ts_adjust));
   5005                 _SOC_IF_ERR_EXIT(xlmac_timestamp_delay_set(unit,
   5006                                                            port,
   5007                                                            ts_adjust,
   5008                                                            config->speed));
   5009             }
   5010             _SOC_IF_ERR_EXIT(xlmac_timestamp_byte_adjust_set(unit, port, 0, config->speed));
   5011         }
   5012 
   5013         /* set encapsulation */
   5014         flags = XLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS;
   5015         rv = xlmac_encap_set (unit, port, flags, config->encap_mode);
   5016         _SOC_IF_ERR_EXIT(rv);
   5017 
   5018         rv = xlmac_strict_preamble_set(unit, port, (!is_higig && (config->speed >= 10000)));
   5019         _SOC_IF_ERR_EXIT(rv);
   5020 
   5021         /* De-Assert SOFT_RESET */
   5022         rv = pm4x10_port_soft_reset(unit, port, pm_info, 0);
   5023         _SOC_IF_ERR_EXIT(rv);
   5024     }
   5025 
   5026     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init (&phy_interface_config));
   5027 
   5028     _SOC_IF_ERR_EXIT(PM4x10_RXAUI_MODE_GET(unit, pm_info,
   5029                                            &rxaui_mode, port_index));
   5030 
   5031     _SOC_IF_ERR_EXIT(_pm4x10_line_side_phymod_interface_get(unit, port,
   5032                                                             pm_info, rxaui_mode,
   5033                                                             config,
   5034                                                             &phymod_interface));
   5035     phy_interface_config.interface_type = phymod_interface;
   5036 
   5037     if (phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY && nof_phys > 1) {
   5038         is_legacy_phy_callback = 1;
   5039     }
   5040 
   5041     _SOC_IF_ERR_EXIT(_pm4x10_phymod_interface_mode_set(unit, port, pm_info, config,
   5042                                                        &phy_interface_config,
   5043                                                        is_legacy_phy_callback));
   5044     _SOC_IF_ERR_EXIT(PM4x10_SPEED_SET(unit, pm_info,
   5045                                       config->speed, port_index));
   5046 
   5047     phy_interface_config.data_rate       = config->speed;
   5048     phy_interface_config.pll_divider_req = config->pll_divider_req;
   5049     phy_interface_config.ref_clock       = PM_4x10_INFO(pm_info)->ref_clk;
   5050 
   5051     /*
   5052      * copy const *config to config_temp cause
   5053      * config.interface may come from storage
   5054      */
   5055     _SOC_IF_ERR_EXIT(portmod_port_interface_config_t_init(unit, &config_temp));
   5056     sal_memcpy(&config_temp, config, sizeof(portmod_port_interface_config_t));
   5057 
   5058     rv = PM4x10_IS_INTERFACE_RESTORE_GET(unit, pm_info,
   5059                                          &is_interface_restore, port_index);
   5060     _SOC_IF_ERR_EXIT(rv);
   5061 
   5062     if(is_interface_restore) {
   5063         /* overwrite config->interface form storage */
   5064          rv = PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index);
   5065          _SOC_IF_ERR_EXIT(rv);
   5066         config_temp.interface  = interface ;
   5067         is_interface_restore = 0;
   5068         rv = PM4x10_IS_INTERFACE_RESTORE_SET(unit, pm_info,
   5069                                           is_interface_restore, port_index);
   5070         _SOC_IF_ERR_EXIT(rv);
   5071     }
   5072 
   5073     _SOC_IF_ERR_EXIT(PM4x10_FS_CL72_GET(unit, pm_info, &fs_cl72, port_index));
   5074     if(fs_cl72) {
   5075         /*
   5076          * PHYMOD_INTF_F_CL72_REQUESTED_BY_CNFG config is only honoured
   5077          * by tsce. incase if the external phys start using this flag,
   5078          * cl72 should not be set for the external phys. Because port_init_cl72
   5079          * should enable cl72 only on the serdes.
   5080          */
   5081         config_temp.flags |= PHYMOD_INTF_F_CL72_REQUESTED_BY_CNFG ;
   5082     }
   5083 
   5084     rv = PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   5085                                       &port_dynamic_state, port_index);
   5086     _SOC_IF_ERR_EXIT(rv);
   5087 
   5088     if( nof_phys > 1 ){
   5089         /* external phy preemphasis and current */
   5090         if (!(config->flags & (PHYMOD_INTF_F_SET_SPD_TRIGGER | PHYMOD_INTF_F_UPDATE_SPEED_LINKUP))) {
   5091             xphy_id = phy_access_arr[nof_phys-1].access.addr;
   5092             _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   5093             if (!is_legacy_phy && !PORTMOD_PORT_IS_DEFAULT_EXT_PHY_TX_PARAMS_UPDATED(port_dynamic_state)) {
   5094                 for(i=0; i < PHYMOD_MAX_LANES_PER_CORE; i++){
   5095                     _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(&phy_access_arr[nof_phys-1], phymodMediaTypeChipToChip,
   5096                                                                   &(ext_phy_tx_params[i])));
   5097                 }
   5098                 _SOC_IF_ERR_EXIT(
   5099                     portmod_port_phychain_tx_set(unit, &phy_access_arr[nof_phys-1],
   5100                                                  1, ext_phy_tx_params));
   5101             }
   5102         }
   5103     }
   5104 
   5105 #ifdef PORTMOD_PM12X10_SUPPORT
   5106     if ((nof_phys > 1) &&  (config->interface_modes & PHYMOD_INTF_MODES_TRIPLE_CORE)) {
   5107         /* external phy TRI-CORE MODE */
   5108         xphy_id = phy_access_arr[nof_phys-1].access.addr;
   5109         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   5110         if((SOC_INFO(unit).port_speed_max[port] >= 100000) && !is_legacy_phy) {
   5111             /* read the portmap config to get the map info */
   5112             lane_config = SOC_INFO(unit).port_100g_lane_config[port];
   5113             /* convert SOC level lane config to interface mode setting */
   5114             switch(lane_config) {
   5115                 case SOC_LANE_CONFIG_100G_4_4_2:
   5116                     phy_interface_config.interface_modes |= PHYMOD_INTF_MODES_TC_442; 
   5117                     break;
   5118                 case SOC_LANE_CONFIG_100G_3_4_3:
   5119                     phy_interface_config.interface_modes |= PHYMOD_INTF_MODES_TC_343; 
   5120                     break;
   5121                 case SOC_LANE_CONFIG_100G_2_4_4:
   5122                     phy_interface_config.interface_modes |= PHYMOD_INTF_MODES_TC_244; 
   5123                 default:
   5124                     break;
   5125             }
   5126         }
   5127     }
   5128 #endif
   5129 
   5130     /* internal phy preemphasis and current */
   5131     if (!(config->flags & (PHYMOD_INTF_F_SET_SPD_TRIGGER | PHYMOD_INTF_F_UPDATE_SPEED_LINKUP))) {
   5132         if (!PORTMOD_PORT_IS_DEFAULT_TX_PARAMS_UPDATED(port_dynamic_state)) {
   5133             _SOC_IF_ERR_EXIT
   5134                 (portmod_port_phychain_interface_config_get(unit, port, phy_access_arr, nof_phys,
   5135                                                             0,  PM_4x10_INFO(pm_info)->ref_clk,
   5136                                                             &cur_phy_if_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   5137             if ((phy_interface_config.data_rate != cur_phy_if_config.data_rate) ||
   5138                 (phy_interface_config.interface_modes != cur_phy_if_config.interface_modes)) {
   5139                 for(i=0; i<PHYMOD_MAX_LANES_PER_CORE; i++){
   5140                     _SOC_IF_ERR_EXIT(phymod_phy_media_type_tx_get(&phy_access_arr[0], phymodMediaTypeChipToChip,
   5141                                                                   &(tx_params[i])));
   5142                 }
   5143                 _SOC_IF_ERR_EXIT(
   5144                     portmod_port_phychain_tx_set(unit, phy_access_arr, 1, tx_params));
   5145             }
   5146         }
   5147     }
   5148 
   5149     if (config->serdes_interface != SOC_PORT_IF_NULL) {
   5150         _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, 
   5151                         config->speed,  
   5152                         config->serdes_interface, 
   5153                         &phymod_serdes_interface));
   5154         _SOC_IF_ERR_EXIT(PM4x10_SERDES_INTERFACE_TYPE_SET(unit, pm_info,
   5155                                                           config->serdes_interface,
   5156                                                           port_index));
   5157     }
   5158     _SOC_IF_ERR_EXIT
   5159         (portmod_port_phychain_interface_config_set(unit, port, phy_access_arr, nof_phys,
   5160                                                 config_temp.flags,
   5161                                                 &phy_interface_config, 
   5162                                                 phymod_serdes_interface, 
   5163                                                 PM_4x10_INFO(pm_info)->ref_clk,
   5164                                                 phy_init_flags));
   5165 
   5166     /* The interface type software state needs to be stored even if the config flags
   5167      * does not include PHYMOD_INTF_F_INTF_PARAM_SET_ONLY. For example, when changing
   5168      * the encap, portctrl tries to config the PHY interface type and speed in one
   5169      * shot without setting the PHYMOD_INTF_F_INTF_PARAM_SET_ONLY flag. However,
   5170      * when the current function is called by the legacy ext PHY through the portmod
   5171      * callback function, the interface type software state should not be modified
   5172      * since PM4x10_INTERFACE_TYPE_GET() should return the outmost PHY interface type. 
   5173      */
   5174     if (!(nof_phys > 1 && phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY)) {
   5175         _SOC_IF_ERR_EXIT
   5176             (portmod_intf_from_phymod_intf(unit, phy_interface_config.interface_type, &interface));
   5177         _SOC_IF_ERR_EXIT
   5178             (PM4x10_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   5179         _SOC_IF_ERR_EXIT
   5180             (PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   5181     }
   5182 
   5183 exit:
   5184     SOC_FUNC_RETURN;
   5185 }
   5186 
   5187 int pm4x10_port_interface_config_get (int unit, int port, pm_info_t pm_info, 
   5188                                       portmod_port_interface_config_t* config, int phy_init_flags)
   5189 {
   5190     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5191     phymod_phy_inf_config_t      phy_interface_config;
   5192     int                          port_index, pll_divider_req;
   5193     uint32_t                     bitmap;
   5194     int flags=0, nof_phys = 0, rv = 0, ref_clock, max_speed;
   5195     phymod_interface_t           prev_phymod_if;
   5196     soc_port_if_t   interface = SOC_PORT_IF_NULL;
   5197     phymod_autoneg_status_t an_status;
   5198     
   5199     SOC_INIT_FUNC_DEFS;
   5200     
   5201     ref_clock = PM_4x10_INFO(pm_info)->ref_clk;
   5202 
   5203     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5204                                              &bitmap));
   5205 
   5206     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_interface_config));
   5207 
   5208     _SOC_IF_ERR_EXIT
   5209         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5210                                           phy_access ,(1+MAX_PHYN),
   5211                                            &nof_phys));
   5212 
   5213     rv = PM4x10_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index);
   5214     _SOC_IF_ERR_EXIT(rv);
   5215 
   5216     rv = PM4x10_OUTMOST_PHY_INTERFACE_TYPE_GET(unit, pm_info, &interface, port_index);
   5217     _SOC_IF_ERR_EXIT(rv);
   5218 
   5219     phy_interface_config.data_rate =  max_speed;
   5220     phy_interface_config.ref_clock =  ref_clock;
   5221 
   5222     _SOC_IF_ERR_EXIT( portmod_intf_to_phymod_intf(unit, max_speed, interface,
   5223                                                   &prev_phymod_if));
   5224     _SOC_IF_ERR_EXIT
   5225         (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   5226                                                     0, ref_clock,
   5227                                                     &phy_interface_config, phy_init_flags));
   5228     _SOC_IF_ERR_EXIT
   5229         (portmod_phy_port_autoneg_status_get(unit, port, pm_info, &an_status));
   5230     /* It is possible that the underlying phymod interface get API does not
   5231      * distinguish among certain interface types. For example, CR2 and KR2
   5232      * are treated the same from TSCE's perspective. In these cases portmod
   5233      * has to rely on the software state to retrieve the most-recently used
   5234      * interface type written into phymod.
   5235      */
   5236     if (phy_interface_config.interface_type != prev_phymod_if &&
   5237         prev_phymod_if != phymodInterfaceCount &&
   5238         !(nof_phys >1 && phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY)) {
   5239         if (!(an_status.enabled && an_status.locked)) {
   5240             /*If an is enabled and locked, use the interface getting from phymod*/
   5241         phy_interface_config.interface_type = prev_phymod_if;
   5242     }
   5243     }
   5244 
   5245     config->speed           = phy_interface_config.data_rate;
   5246     config->interface_modes = phy_interface_config.interface_modes;
   5247     config->flags           = 0;
   5248     config->interface       = interface;
   5249 
   5250     rv = PM4x10_PORT_PLL_DIVIDER_REQ_GET(unit, pm_info,
   5251                                          &pll_divider_req,
   5252                                          port_index);
   5253 
   5254     config->pll_divider_req = pll_divider_req;
   5255 
   5256     _SOC_IF_ERR_EXIT(
   5257                 PM4x10_SERDES_INTERFACE_TYPE_GET(unit, pm_info,
   5258                                                  &config->serdes_interface,
   5259                                                  port_index));
   5260 
   5261 #if 1
   5262     rv = portmod_intf_from_phymod_intf (unit, 
   5263              phy_interface_config.interface_type, &(config->interface));
   5264     _SOC_IF_ERR_EXIT(rv);
   5265 #endif
   5266 
   5267     rv = xlmac_encap_get (unit, port, &flags, &config->encap_mode); 
   5268     _SOC_IF_ERR_EXIT(rv);
   5269                           
   5270     rv = PM4x10_PORT_OP_MODE_GET(unit, pm_info, &config->port_op_mode,
   5271                                  port_index);
   5272     _SOC_IF_ERR_EXIT(rv);
   5273 
   5274     config->port_num_lanes = SOC_INFO(unit).port_num_lanes[port];
   5275 
   5276     rv = PM4x10_MAX_SPEED_GET(unit, pm_info, &config->max_speed, port_index);
   5277     _SOC_IF_ERR_EXIT(rv);
   5278 
   5279     rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &config->interface_modes,
   5280                                     port_index);
   5281     _SOC_IF_ERR_EXIT(rv);
   5282 
   5283 
   5284 
   5285 exit:
   5286     SOC_FUNC_RETURN;
   5287 }
   5288 
   5289 int pm4x10_port_default_interface_get(int unit, int port, pm_info_t pm_info,
   5290                                       const portmod_port_interface_config_t* config,
   5291                                       soc_port_if_t* interface)
   5292 {
   5293     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5294     int nof_phys = 0;
   5295     int is_legacy_present, xphy_id;
   5296     portmod_port_interface_config_t interface_config;
   5297     SOC_INIT_FUNC_DEFS;
   5298 
   5299     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   5300                                            phy_access ,(1+MAX_PHYN),
   5301                                            &nof_phys));
   5302     if (nof_phys==1) {
   5303         _SOC_IF_ERR_EXIT
   5304             (_pm4x10_default_interface_get(unit, port, config, interface));
   5305     } else {
   5306         xphy_id = phy_access[nof_phys - 1].access.addr;
   5307         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_present));
   5308 
   5309         if (!is_legacy_present) {
   5310             _SOC_IF_ERR_EXIT
   5311                 (portmod_port_phymod_xphy_default_interface_get(unit, &(phy_access[nof_phys-1]),
   5312                                                                 config, interface));
   5313         } else {
   5314             interface_config = *config;
   5315             _SOC_IF_ERR_EXIT
   5316                 (portmod_common_default_interface_get(&interface_config));
   5317 
   5318             /* A TD2P+G28 40G/42G HG2 port is of XLAUI interface type on the
   5319              * line side historically. On the system side, the int PHY should
   5320              * be of BRCM mode (XGMII) and this is taken care by
   5321              * portmod_port_line_to_sys_intf_map().
   5322              */
   5323             if ((config->encap_mode == SOC_ENCAP_HIGIG || 
   5324                  config->encap_mode == SOC_ENCAP_HIGIG2) &&
   5325                 (config->speed == 40000 || 
   5326                  config->speed == 42000)) {
   5327                 interface_config.interface = SOC_PORT_IF_XLAUI; 
   5328             }
   5329 
   5330             *interface = interface_config.interface;
   5331         }
   5332     }
   5333 
   5334 exit:
   5335     SOC_FUNC_RETURN;
   5336 }
   5337 
   5338 int pm4x10_port_cl72_set(int unit, int port, pm_info_t pm_info, uint32 enable)
   5339 {
   5340     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5341     int   nof_phys = 0;
   5342 
   5343     SOC_INIT_FUNC_DEFS;
   5344 
   5345     _SOC_IF_ERR_EXIT
   5346         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5347                                            phy_access ,(1+MAX_PHYN),
   5348                                            &nof_phys));
   5349 
   5350     _SOC_IF_ERR_EXIT
   5351         (portmod_port_phychain_cl72_set(unit, port, phy_access, nof_phys, enable));
   5352 
   5353 exit:
   5354     SOC_FUNC_RETURN;
   5355 }
   5356 int pm4x10_port_cl72_get(int unit, int port, pm_info_t pm_info, uint32* enable)
   5357 {
   5358     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5359     int   nof_phys = 0;
   5360 
   5361     SOC_INIT_FUNC_DEFS;
   5362 
   5363     _SOC_IF_ERR_EXIT
   5364         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5365                                            phy_access ,(1+MAX_PHYN),
   5366                                            &nof_phys));
   5367 
   5368     _SOC_IF_ERR_EXIT
   5369         (portmod_port_phychain_cl72_get(unit, phy_access, nof_phys, enable));
   5370 
   5371 exit:
   5372     SOC_FUNC_RETURN;
   5373 }
   5374 
   5375 int pm4x10_port_cl72_status_get(int unit, int port, pm_info_t pm_info, phymod_cl72_status_t* status)
   5376 {
   5377     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5378     int   nof_phys = 0;
   5379 
   5380     SOC_INIT_FUNC_DEFS;
   5381 
   5382     _SOC_IF_ERR_EXIT
   5383         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5384                                            phy_access ,(1+MAX_PHYN),
   5385                                            &nof_phys));
   5386 
   5387     _SOC_IF_ERR_EXIT
   5388         (portmod_port_phychain_cl72_status_get(unit, phy_access, nof_phys, status));
   5389 
   5390 exit:
   5391     SOC_FUNC_RETURN;
   5392 }
   5393 
   5394 
   5395 int pm4x10_port_loopback_get(int unit, int port, pm_info_t pm_info, 
   5396                  portmod_loopback_mode_t loopback_type, int* enable)
   5397 {
   5398     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5399     int                 nof_phys;
   5400     uint32_t tmp_enable=0;
   5401     phymod_loopback_mode_t phymod_lb_type;
   5402     int rv = PHYMOD_E_NONE;
   5403     int port_index;
   5404     uint32 bitmap;
   5405 
   5406     SOC_INIT_FUNC_DEFS;
   5407 
   5408     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5409                                              &bitmap));
   5410 
   5411     switch(loopback_type){
   5412         case portmodLoopbackMacOuter:
   5413             _SOC_IF_ERR_EXIT(xlmac_loopback_get(unit, port, enable));
   5414             break;
   5415 
   5416         case portmodLoopbackPhyRloopPCS:
   5417         case portmodLoopbackPhyGloopPMD:
   5418         case portmodLoopbackPhyRloopPMD: /*slide*/
   5419         case portmodLoopbackPhyGloopPCS: /*slide*/
   5420              if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   5421                 (*enable) = 0; /* No phy --> no phy loopback*/
   5422              } else {
   5423                 _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, 
   5424                                                 loopback_type, &phymod_lb_type));
   5425                 _SOC_IF_ERR_EXIT
   5426                     (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5427                                                       phy_access ,(1+MAX_PHYN),
   5428                                                       &nof_phys));
   5429 
   5430                 rv = portmod_port_phychain_loopback_get(unit, port, phy_access,
   5431                                                     nof_phys,
   5432                                                     phymod_lb_type,
   5433                                                     &tmp_enable);
   5434                 if (rv == PHYMOD_E_UNAVAIL) {
   5435                     rv = PHYMOD_E_NONE;
   5436                     tmp_enable = 0;
   5437                 }
   5438 
   5439                 _SOC_IF_ERR_EXIT(rv);
   5440                 *enable = tmp_enable;
   5441 
   5442              }
   5443              break;
   5444         default:
   5445             (*enable) = 0; /* not supported --> no loopback */
   5446             break;
   5447     }
   5448 
   5449 exit:
   5450     SOC_FUNC_RETURN;
   5451 }
   5452 
   5453 int pm4x10_port_loopback_set (int unit, int port, pm_info_t pm_info, 
   5454                   portmod_loopback_mode_t loopback_type, int enable)
   5455 {
   5456     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5457     int                 nof_phys;
   5458     phymod_loopback_mode_t phymod_lb_type;
   5459     int port_index;
   5460     uint32 bitmap;
   5461 
   5462     SOC_INIT_FUNC_DEFS;
   5463 
   5464     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5465                                              &bitmap));
   5466 
   5467     /* loopback type validation*/
   5468     switch(loopback_type){
   5469     case portmodLoopbackMacOuter:
   5470         _SOC_IF_ERR_EXIT(xlmac_loopback_set(unit, port, enable));
   5471         break;
   5472 
   5473     case portmodLoopbackPhyRloopPCS:
   5474     case portmodLoopbackPhyRloopPMD: /*slide*/
   5475     case portmodLoopbackPhyGloopPMD:
   5476     case portmodLoopbackPhyGloopPCS: /*slide*/
   5477         if(PM_4x10_INFO(pm_info)->nof_phys[port_index] != 0) {
   5478             if (enable) {
   5479                 _SOC_IF_ERR_EXIT(xlmac_loopback_set(unit, port, 0));
   5480             }
   5481             _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, 
   5482                                                 loopback_type, &phymod_lb_type));
   5483             
   5484             _SOC_IF_ERR_EXIT
   5485                 (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5486                                                   phy_access ,(1+MAX_PHYN),
   5487                                                   &nof_phys));
   5488 
   5489             _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_set(unit, port,  phy_access, 
   5490                                                                 nof_phys, 
   5491                                                                 phymod_lb_type, 
   5492                                                                 enable));
   5493          }
   5494          break;
   5495     default:
   5496         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (
   5497                   _SOC_MSG("unsupported loopback type %d"), loopback_type));
   5498             break;
   5499     }
   5500     if (enable)
   5501         _SOC_IF_ERR_EXIT(PM_DRIVER(pm_info)->f_portmod_port_lag_failover_status_toggle(unit, port, pm_info));
   5502 
   5503 exit:
   5504     SOC_FUNC_RETURN; 
   5505 }
   5506 
   5507 int pm4x10_port_rx_mac_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   5508 {
   5509     SOC_INIT_FUNC_DEFS;
   5510 
   5511     _SOC_IF_ERR_EXIT(xlmac_rx_enable_set(unit, port, enable));
   5512 
   5513 exit:
   5514     SOC_FUNC_RETURN;
   5515 
   5516 }
   5517 
   5518 int pm4x10_port_rx_mac_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   5519 {
   5520     SOC_INIT_FUNC_DEFS;
   5521 
   5522     _SOC_IF_ERR_EXIT(xlmac_rx_enable_get(unit, port, enable));
   5523 
   5524 exit:
   5525     SOC_FUNC_RETURN;
   5526 
   5527 }
   5528 
   5529 int pm4x10_port_tx_mac_enable_set(int unit, int port, pm_info_t pm_info, int enable)
   5530 {
   5531     SOC_INIT_FUNC_DEFS;
   5532 
   5533     _SOC_IF_ERR_EXIT(xlmac_tx_enable_set(unit, port, enable));
   5534 
   5535 exit:
   5536     SOC_FUNC_RETURN;
   5537 
   5538 }
   5539 
   5540 int pm4x10_port_tx_mac_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
   5541 {
   5542     SOC_INIT_FUNC_DEFS;
   5543 
   5544     _SOC_IF_ERR_EXIT(xlmac_tx_enable_get(unit, port, enable));
   5545 
   5546 exit:
   5547     SOC_FUNC_RETURN;
   5548 
   5549 }
   5550 
   5551 int pm4x10_port_ability_local_get (int unit, int port, pm_info_t pm_info, uint32 phy_flags,
   5552                                    portmod_port_ability_t* ability)
   5553 {
   5554     portmod_port_ability_t legacy_phy_ability;
   5555     int                 fiber_pref, port_index;
   5556     int                 max_speed = 11000;
   5557     int                 num_of_lanes = 0;
   5558     uint32              bitmap, tmpbit, interface_modes;
   5559     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5560     int                 nof_phys, xphy_id, is_legacy_phy, rv = SOC_E_NONE;
   5561     pm_version_t pm_version;
   5562 
   5563     SOC_INIT_FUNC_DEFS;
   5564 
   5565     sal_memset(ability, 0, sizeof(portmod_port_ability_t));
   5566     sal_memset(&legacy_phy_ability, 0, sizeof(portmod_port_ability_t));
   5567 
   5568     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   5569 
   5570     _SOC_IF_ERR_EXIT
   5571         (portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,
   5572                                            (1+MAX_PHYN), &nof_phys));
   5573 
   5574     _SOC_IF_ERR_EXIT
   5575         (_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   5576     
   5577     rv = PM4x10_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index);
   5578     _SOC_IF_ERR_EXIT(rv);
   5579 
   5580     rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   5581                                     port_index);
   5582     _SOC_IF_ERR_EXIT(rv);
   5583 
   5584     fiber_pref = (interface_modes & PHYMOD_INTF_MODES_FIBER)? 1 : 0;
   5585 
   5586     tmpbit = bitmap ;
   5587     while(tmpbit) {
   5588         num_of_lanes += ((tmpbit&1)?1:0) ;
   5589         tmpbit >>= 1 ;
   5590     }
   5591 
   5592     ability->loopback  = SOC_PA_LB_PHY | SOC_PA_LB_MAC;
   5593     ability->medium    = SOC_PA_MEDIUM_FIBER | SOC_PA_MEDIUM_COPPER | SOC_PA_MEDIUM_BACKPLANE;
   5594     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   5595     ability->fec       = SOC_PA_FEC_NONE | SOC_PA_FEC_CL74;
   5596     ability->flags     = SOC_PA_AUTONEG;
   5597     ability->speed_half_duplex  = SOC_PA_ABILITY_NONE;
   5598     ability->encap     = SOC_PA_ENCAP_IEEE | SOC_PA_ENCAP_HIGIG | SOC_PA_ENCAP_HIGIG2;
   5599     ability->channel   = SOC_PA_CHANNEL_LONG;
   5600 
   5601     if (num_of_lanes == 1) {
   5602         if (interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   5603             switch(max_speed) {
   5604                 case 10000: max_speed = 11000 ; break ;
   5605                 default:  break;
   5606             }
   5607             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5608             _SOC_IF_ERR_EXIT(rv);
   5609         } else {
   5610             /* 10M, 100M, 1G, 2.5G, 5G don't have equivalent HiGig speeds
   5611                Should only be supported on a non-HiGig port
   5612              */
   5613             if (!fiber_pref) {
   5614                 ability->speed_full_duplex |= SOC_PA_SPEED_10MB;
   5615             }
   5616             ability->speed_full_duplex |= SOC_PA_SPEED_100MB;
   5617             ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   5618 
   5619             switch(max_speed) {
   5620                 case 11000: max_speed = 10000; break;
   5621                 default:  break;
   5622             }
   5623             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5624             _SOC_IF_ERR_EXIT(rv);
   5625 
   5626             /* Must include all supported speeds */
   5627             switch(max_speed) {
   5628                 case 12000:
   5629                 case 11000:
   5630                 case 10000:
   5631                 case 5000:
   5632                     ability->speed_full_duplex |= SOC_PA_SPEED_5000MB;
   5633                 case 2500:
   5634                     /* Need to revisit: 2500MB for copper mode */
   5635                     ability->speed_full_duplex |= SOC_PA_SPEED_2500MB;
   5636                 default: break;
   5637             }
   5638         }
   5639         switch(max_speed) {  /* Must include all the supported speeds */
   5640             case 12000:
   5641                 ability->speed_full_duplex |= SOC_PA_SPEED_12GB;
   5642             case 11000:
   5643                 ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   5644             case 10000:
   5645                 ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   5646             default:
   5647                 break;
   5648         }
   5649         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   5650         ability->interface = SOC_PA_INTF_GMII | SOC_PA_INTF_SGMII;
   5651         if (max_speed >= 10000) {
   5652             ability->interface |= SOC_PA_INTF_XGMII;
   5653         }
   5654 
   5655         /* single lane port */
   5656         ability->flags = SOC_PA_AUTONEG;
   5657     } else if (num_of_lanes == 2) {
   5658         if(interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   5659             switch(max_speed) {
   5660                 case 10000: max_speed = 11000 ; break ;
   5661                 case 20000: max_speed = 21000 ; break ;
   5662                 default:  break ;
   5663             }
   5664             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5665             _SOC_IF_ERR_EXIT(rv);
   5666         } else {
   5667             switch(max_speed) {
   5668                 case 11000: max_speed = 10000 ; break ;
   5669                 case 21000: max_speed = 20000 ; break ;
   5670                 default:  break ;
   5671             }
   5672             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5673             _SOC_IF_ERR_EXIT(rv);
   5674         }
   5675         switch(max_speed) {  /* must include all the supported speedss */
   5676             case 21000:
   5677                 ability->speed_full_duplex |= SOC_PA_SPEED_21GB;
   5678             case 20000:
   5679                 ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   5680             case 16000:
   5681                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5682                     ability->speed_full_duplex |= SOC_PA_SPEED_16GB;
   5683                 }
   5684             case 15000:
   5685                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5686                     ability->speed_full_duplex |= SOC_PA_SPEED_15GB;
   5687                 }
   5688             case 13000:
   5689                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5690                     ability->speed_full_duplex |= SOC_PA_SPEED_13GB;
   5691                 }
   5692             case 12000:
   5693                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5694                     ability->speed_full_duplex |= SOC_PA_SPEED_12GB;
   5695                 }
   5696             case 11000:
   5697                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5698                     ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   5699                 }
   5700             case 10000:
   5701                 if (!PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   5702                     ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   5703                 }
   5704             default:
   5705                 break;
   5706         }
   5707         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   5708         ability->interface = SOC_PA_INTF_XGMII;
   5709         ability->flags = 0;
   5710     } else {
   5711         if(interface_modes & PHYMOD_INTF_MODES_HIGIG) {
   5712             switch(max_speed) {
   5713                 case 10000: max_speed = 11000 ; break ;
   5714                 case 20000: max_speed = 21000 ; break ;
   5715                 case 40000: max_speed = 42000 ; break ;
   5716                 case 100000: max_speed = 106000 ; break ;
   5717                 case 120000: max_speed = 127000 ; break ;
   5718                 default:  break ;
   5719             }
   5720             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5721             _SOC_IF_ERR_EXIT(rv);
   5722         } else {
   5723             switch(max_speed) {
   5724                 case 11000: max_speed = 10000 ; break ;
   5725                 case 21000: max_speed = 20000 ; break ;
   5726                 case 42000: max_speed = 40000 ; break ;
   5727                 case 106000: max_speed = 100000 ; break ;
   5728                 case 127000: max_speed = 120000 ; break ;
   5729                 default:  break ;
   5730             }
   5731             rv = PM4x10_MAX_SPEED_SET(unit, pm_info, max_speed, port_index);
   5732             _SOC_IF_ERR_EXIT(rv);
   5733         }
   5734         switch(max_speed) {
   5735             case 127000:
   5736                 ability->speed_full_duplex |= SOC_PA_SPEED_127GB;
   5737             case 120000:
   5738                 ability->speed_full_duplex |= SOC_PA_SPEED_120GB;
   5739             case 106000:
   5740                 ability->speed_full_duplex |= SOC_PA_SPEED_106GB;
   5741             case 100000:
   5742                 ability->speed_full_duplex |= SOC_PA_SPEED_100GB;
   5743                 break; /* PM12x10 with lanes >=10 only supports above speeds */
   5744             case 42000:
   5745                 ability->speed_full_duplex |= SOC_PA_SPEED_42GB;
   5746             case 40000:
   5747                 ability->speed_full_duplex |= SOC_PA_SPEED_40GB;
   5748             case 30000:
   5749                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5750                     ability->speed_full_duplex |= SOC_PA_SPEED_30GB;
   5751                 }
   5752             case 25000:
   5753                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5754                     ability->speed_full_duplex |= SOC_PA_SPEED_25GB;
   5755                 }
   5756             case 21000:
   5757                 if (!PORTMOD_PM4x10_IS_GEN2_16nm(pm_version)) {
   5758                     ability->speed_full_duplex |= SOC_PA_SPEED_21GB;
   5759                 }
   5760             case 20000:
   5761                 ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   5762             case 16000:
   5763                 if (!PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   5764                     ability->speed_full_duplex |= SOC_PA_SPEED_16GB;
   5765                 }
   5766             case 15000:
   5767                 if (!PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
   5768                     ability->speed_full_duplex |= SOC_PA_SPEED_15GB;
   5769                 }
   5770             case 13000:
   5771                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5772                     ability->speed_full_duplex |= SOC_PA_SPEED_13GB;
   5773                 }
   5774             case 12000:
   5775                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5776                     ability->speed_full_duplex |= SOC_PA_SPEED_12GB;
   5777                 }
   5778             case 11000:
   5779                 if (!(PORTMOD_PM4x10_IS_GEN2_16nm(pm_version) || PORTMOD_PM4x10_IS_GEN3_28nm(pm_version))) {
   5780                     ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   5781                 }
   5782             case 10000:
   5783                 ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   5784             default:
   5785                 break;
   5786         }
   5787         ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   5788         ability->interface = SOC_PA_INTF_XGMII;
   5789         ability->flags     = SOC_PA_AUTONEG;
   5790     }
   5791 
   5792     /* If legacy external phy presents, retrieve the local ability from the
   5793      * external phy as it has more variants and the ability might vary for each.
   5794      * However, if this function is called by the legacy ext PHY driver through
   5795      * the PORTMOD callback function portmod_ext_to_int_cmd_get(), the returned
   5796      * data should be of the internal SERDES. portmod_ext_to_int_cmd_get() uses
   5797      * PORTMOD_USER_ACC_CMD_FOR_PHY_SET() to hint its callees that the target
   5798      * of data retrieving is the internal SERDES.
   5799      */
   5800     if (nof_phys > 1 && !(phy_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY)) {
   5801         /* check if the legacy phy present */
   5802         xphy_id = phy_access[nof_phys-1].access.addr;
   5803         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   5804         if(is_legacy_phy) {
   5805             /* call portmod phy chain function to retrieve the ability */
   5806             _SOC_IF_ERR_EXIT
   5807                 (portmod_port_phychain_local_ability_get(unit, port, phy_access,
   5808                                                          nof_phys, &legacy_phy_ability));
   5809             /* PHY driver returns all the speeds supported by PHY
   5810              * Advertise only the speeds supported by both PortMacro and the PHY
   5811              */
   5812             legacy_phy_ability.speed_full_duplex &= ability->speed_full_duplex;
   5813             /* PHY driver may not return all supported encap modes
   5814              * Advertise encap modes supported by both PortMacro and the PHY
   5815              */
   5816             legacy_phy_ability.encap |= ability->encap;
   5817             *ability = legacy_phy_ability;
   5818         } else {
   5819             /* We might need to consider calling portmod phy chain for
   5820              * non legacy phys as well*/
   5821         }
   5822     }
   5823 
   5824     LOG_INFO(BSL_LS_SOC_PHY,
   5825              (BSL_META_U(unit,
   5826                          "%-22s:unit=%d p=%d sp=%08x bitmap=%x\n"),
   5827               __FUNCTION__, unit, port, ability->speed_full_duplex, bitmap));
   5828 
   5829 exit:
   5830     SOC_FUNC_RETURN;
   5831 
   5832 }
   5833 
   5834 int pm4x10_port_autoneg_set (int unit, int port, pm_info_t pm_info, uint32 phy_flags, 
   5835                              const phymod_autoneg_control_t* an)
   5836 {
   5837     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5838     int nof_phys, rv;
   5839     int port_index, an_cl37, cl37_sgmii_cnt;
   5840     uint32_t bitmap, an_done, port_dynamic_state;
   5841     phymod_autoneg_control_t  *pAn = (phymod_autoneg_control_t*)an;
   5842     phymod_firmware_lane_config_t fw_config;
   5843     phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer;
   5844     SOC_INIT_FUNC_DEFS;
   5845 
   5846     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5847                                              &bitmap));
   5848 
   5849     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   5850         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("AN isn't supported")));
   5851     } else {
   5852         if (pAn->num_lane_adv == 0) {
   5853             pAn->num_lane_adv = _pm4x10_nof_lanes_get(unit, port, pm_info);
   5854         }
   5855         
   5856         if (pAn->an_mode == phymod_AN_MODE_NONE) {
   5857             rv = PM4x10_AN_MODE_GET(unit, pm_info, &pAn->an_mode, port_index);
   5858             _SOC_IF_ERR_EXIT(rv);
   5859         }
   5860 
   5861         if (pAn->an_mode == phymod_AN_MODE_NONE) {
   5862             pAn->an_mode = phymod_AN_MODE_SGMII; 
   5863         }
   5864 
   5865         rv = PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info,
   5866                                       &port_dynamic_state, port_index);
   5867         _SOC_IF_ERR_EXIT(rv);
   5868         if (PORTMOD_PORT_IS_AUTONEG_MODE_UPDATED(port_dynamic_state))  {
   5869             rv = PM4x10_AN_MODE_GET(unit, pm_info, &pAn->an_mode, port_index);
   5870             _SOC_IF_ERR_EXIT(rv);
   5871             PORTMOD_PORT_AUTONEG_MODE_UPDATED_CLR(port_dynamic_state);
   5872             rv = PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info,
   5873                                      port_dynamic_state, port_index);
   5874             _SOC_IF_ERR_EXIT(rv);
   5875         }
   5876 
   5877         _SOC_IF_ERR_EXIT
   5878             (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5879                                               phy_access ,(1+MAX_PHYN),
   5880                                               &nof_phys));
   5881 
   5882         rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, nof_phys, &phy_op_mode);
   5883 
   5884         /* Setting SerDes SGMII AN mode*/
   5885         if ((nof_phys <= 1) || 
   5886             ((phy_op_mode == phymodOperationModePassthru) && (rv == PHYMOD_E_NONE))) {
   5887             SOC_IF_ERROR_RETURN
   5888                 (portmod_port_phychain_firmware_lane_config_get(unit, phy_access, nof_phys, &fw_config));
   5889             if (pAn->an_mode == phymod_AN_MODE_CL37) {
   5890                 if (!(fw_config.MediaType & phymodFirmwareMediaTypeOptics)) {
   5891                     pAn->an_mode = phymod_AN_MODE_SGMII;
   5892                 }
   5893             }
   5894         }
   5895 
   5896         /* In case of warm boot, get autoneg informaton from hardware */  
   5897         if(SOC_WARM_BOOT(unit)) {
   5898             if (pAn->an_mode >= phymod_AN_MODE_Count) {
   5899                 _SOC_IF_ERR_EXIT
   5900                     (portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, phy_flags, pAn, &an_done));
   5901             }
   5902         }
   5903 
   5904         rv = PM4x10_AN_CL37_GET(unit, pm_info, &an_cl37, port_index);
   5905         _SOC_IF_ERR_EXIT(rv);
   5906         if(an_cl37 == PORTMOD_CL37_SGMII_COMBO){
   5907            if(pAn->enable){
   5908               cl37_sgmii_cnt = 0; 
   5909               _SOC_IF_ERR_EXIT(PM4x10_CL37_SGMII_CNT_SET(unit, pm_info,
   5910                                                          cl37_sgmii_cnt,
   5911                                                          port_index));
   5912            }
   5913         }
   5914 
   5915         _SOC_IF_ERR_EXIT
   5916             (portmod_port_phychain_autoneg_set(unit, port, phy_access, nof_phys, phy_flags, an));
   5917     }
   5918      
   5919 exit:
   5920     SOC_FUNC_RETURN;
   5921  
   5922 }
   5923 
   5924 int pm4x10_port_autoneg_get (int unit, int port, pm_info_t pm_info, uint32 phy_flags, 
   5925                              phymod_autoneg_control_t* an)
   5926 {      
   5927     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5928     int         nof_phys;
   5929     uint32      an_done;
   5930     int port_index, rv;
   5931     uint32_t bitmap;
   5932 
   5933     SOC_INIT_FUNC_DEFS;
   5934     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5935                                              &bitmap));
   5936     
   5937     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   5938         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("AN isn't supported")));
   5939     } else {
   5940         
   5941         if (an->num_lane_adv == 0) {
   5942             an->num_lane_adv = _pm4x10_nof_lanes_get(unit, port, pm_info);
   5943         }
   5944         rv = PM4x10_AN_MODE_GET(unit, pm_info, &an->an_mode, port_index);
   5945         _SOC_IF_ERR_EXIT(rv);
   5946 
   5947         if (an->an_mode == phymod_AN_MODE_NONE) {
   5948             an->an_mode = phymod_AN_MODE_SGMII; 
   5949         }
   5950 
   5951         _SOC_IF_ERR_EXIT
   5952             (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5953                                               phy_access ,(1+MAX_PHYN),
   5954                                                &nof_phys));
   5955         _SOC_IF_ERR_EXIT
   5956             (portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, phy_flags, an, &an_done));
   5957     }
   5958 
   5959 exit:
   5960     SOC_FUNC_RETURN;
   5961  
   5962 }
   5963 
   5964 int pm4x10_port_autoneg_status_get (int unit, int port, pm_info_t pm_info,
   5965                                     phymod_autoneg_status_t* an_status)
   5966 {   
   5967     phymod_phy_access_t phy_access[1+MAX_PHYN];
   5968     int nof_phys;
   5969     int port_index;
   5970     uint32 bitmap;
   5971     portmod_port_interface_config_t port_intf_config;
   5972     phymod_interface_t phy_intf;
   5973     
   5974     SOC_INIT_FUNC_DEFS; 
   5975 
   5976     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   5977                                              &bitmap));
   5978 
   5979     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   5980         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   5981                           (_SOC_MSG("Invalid number of Phys")));
   5982     } 
   5983 
   5984 
   5985     _SOC_IF_ERR_EXIT
   5986         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   5987                                          phy_access ,(1+MAX_PHYN),
   5988                                          &nof_phys));
   5989     _SOC_IF_ERR_EXIT
   5990         (portmod_port_phychain_autoneg_status_get(unit, port, phy_access, nof_phys, an_status));
   5991 
   5992     /* Even if AN is enabled the data rate and interface should be retrieved through 
   5993      * interface_config_get function
   5994      */
   5995     _SOC_IF_ERR_EXIT
   5996         (pm4x10_port_interface_config_get(unit, port, pm_info, &port_intf_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   5997     _SOC_IF_ERR_EXIT
   5998         (portmod_intf_to_phymod_intf(unit, port_intf_config.speed, port_intf_config.interface, &phy_intf));
   5999 
   6000     if (an_status->enabled && an_status->locked) {
   6001         an_status->data_rate = port_intf_config.speed;
   6002         an_status->interface = phy_intf;
   6003     } else {
   6004         /* upper layer should not rely on the 
   6005          *  data rate and interface if the AN is not locked
   6006          */
   6007         an_status->data_rate = 0;
   6008         an_status->interface = SOC_PORT_IF_NULL;        
   6009     }
   6010 
   6011 exit:
   6012     SOC_FUNC_RETURN;
   6013     
   6014 }
   6015 
   6016 int pm4x10_port_link_get(int unit, int port, pm_info_t pm_info, int flags, int* link)
   6017 {
   6018     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6019     int nof_phys;
   6020     int sys_start_lane=-1;
   6021     int sys_end_lane=-1;
   6022     int line_start_lane=-1;
   6023     int line_end_lane=-1;
   6024     uint32 int_lane_mask=0xf;
   6025     uint32 bitmap, an_done;
   6026     int    port_index, an_cl37, cl37_sgmii_war = 0;
   6027     int    cl37_sgmii_cnt, cl37_sgmii_restart_cnt;
   6028     phymod_autoneg_control_t an;
   6029     SOC_INIT_FUNC_DEFS;
   6030 
   6031     _SOC_IF_ERR_EXIT
   6032         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6033                                            phy_access ,(1+MAX_PHYN),
   6034                                            &nof_phys));
   6035 
   6036     _SOC_IF_ERR_EXIT(_pm4x10_port_tricore_lane_info_get(unit, port, pm_info,
   6037                                                         &sys_start_lane, &sys_end_lane,
   6038                                                         &line_start_lane, &line_end_lane,
   6039                                                         &int_lane_mask, NULL));
   6040     /* only look at the lanes that are used. */
   6041     phy_access[0].access.lane_mask &= int_lane_mask;
   6042 
   6043     _SOC_IF_ERR_EXIT
   6044             (portmod_port_phychain_link_status_get(unit, port, phy_access, nof_phys, flags, (uint32_t*) link));
   6045 
   6046     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6047                                              &bitmap));
   6048 
   6049     _SOC_IF_ERR_EXIT(PM4x10_AN_CL37_GET(unit, pm_info, &an_cl37, port_index));
   6050      if(an_cl37 == PORTMOD_CL37_SGMII_COMBO) {
   6051         _SOC_IF_ERR_EXIT(portmod_port_phychain_autoneg_get(unit, port, phy_access,
   6052                                                            nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, 
   6053                                                            &an, &an_done));
   6054         if (an.enable) {
   6055             cl37_sgmii_war = 1;
   6056         }
   6057      }
   6058 
   6059     if(*link == 0){
   6060        if(cl37_sgmii_war){
   6061           _SOC_IF_ERR_EXIT(PM4x10_CL37_SGMII_CNT_GET(unit, pm_info,
   6062                                                      &cl37_sgmii_cnt,
   6063                                                      port_index));
   6064           _SOC_IF_ERR_EXIT(PM4x10_CL37_SGMII_RESTART_CNT_GET(unit, pm_info,
   6065                                                      &cl37_sgmii_restart_cnt,
   6066                                                      port_index));
   6067           if(++cl37_sgmii_cnt >= cl37_sgmii_restart_cnt){
   6068              cl37_sgmii_cnt = 0;
   6069              _SOC_IF_ERR_EXIT(PM4x10_CL37_SGMII_CNT_SET(unit, pm_info,
   6070                                                         cl37_sgmii_cnt,
   6071                                                         port_index));
   6072              _SOC_IF_ERR_EXIT
   6073                 (portmod_port_phychain_autoneg_restart_set(unit, phy_access,nof_phys));
   6074             }
   6075         }
   6076     }
   6077 
   6078     if ((nof_phys == 1) && (PM_4x10_INFO(pm_info)->link_recovery.enabled)) {
   6079         /* link recovery for internal serdes only for optical application MLD based */
   6080         uint32_t signal_detect;
   6081         phymod_firmware_lane_config_t firmware_lane_config;
   6082 
   6083         /* first get the medium type from internal serdes */
   6084         _SOC_IF_ERR_EXIT(phymod_phy_firmware_lane_config_get(&phy_access[0], &firmware_lane_config));
   6085 
   6086         if ((firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) &&
   6087             (phy_access[0].access.lane_mask == 0xf)) {
   6088             switch (PM_4x10_INFO(pm_info)->link_recovery.state) {
   6089 
   6090             case PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK:
   6091                 /* link is good */
   6092                 if (*link) {
   6093                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt = 0;
   6094                     PM_4x10_INFO(pm_info)->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD;
   6095                 } else if ((PM_4x10_INFO(pm_info)->link_recovery.tick_cnt) > PORTMOD_LINK_RECOVERY_LINK_WAIT_CNT_LIMIT) {
   6096                     /* no link after all the try, reset the rx patha again */
   6097                     PM_4x10_INFO(pm_info)->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_RESET_RX;
   6098                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt = 0;
   6099                 } else {
   6100                     /* no link yet, keep wait for link */
   6101                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt += 1;
   6102                 }
   6103                 break;
   6104             case PORTMOD_LINK_RECOVERY_STATE_RESET_RX:
   6105                 /*first check link status */
   6106                 if (*link) {
   6107                     PM_4x10_INFO(pm_info)->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD;
   6108                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt = 0;
   6109                 } else {
   6110                     /* first reset the rx path */
   6111                     signal_detect = 0;
   6112 
   6113                     /* check if there is signal detect */
   6114                     _SOC_IF_ERR_EXIT(phymod_phy_rx_signal_detect_get(&phy_access[0], &signal_detect));
   6115 
   6116                     /* only toggle rx reset path only if there is signal on the line */
   6117                     if (signal_detect) {
   6118                          /* first put the rx into reset */
   6119                          _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxDisable));
   6120 
   6121                         /* add some delay */
   6122                         sal_usleep(5000);
   6123 
   6124                          /* toggle CDR lock */
   6125                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxSquelchOn));
   6126                         /* add some delay */
   6127                         sal_usleep(5000);
   6128                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxSquelchOff));
   6129 
   6130                         sal_usleep(10000);
   6131                         /* release the rx reset */
   6132                         _SOC_IF_ERR_EXIT(phymod_phy_rx_lane_control_set(&phy_access[0], phymodRxReset));
   6133 
   6134                         sal_usleep(10000);
   6135                     }
   6136                     PM_4x10_INFO(pm_info)->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_WAIT_FOR_LINK;
   6137                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt = 0;
   6138                 }
   6139                 break;
   6140 
   6141             case PORTMOD_LINK_RECOVERY_STATE_LINK_GOOD:
   6142                 /* no link, need to reset the rx path */
   6143                 if (*link == 0) {
   6144                     PM_4x10_INFO(pm_info)->link_recovery.state = PORTMOD_LINK_RECOVERY_STATE_RESET_RX;
   6145                     PM_4x10_INFO(pm_info)->link_recovery.tick_cnt = 0;
   6146                 }
   6147                 break;
   6148             }
   6149         } /* end of fiber_pref link recovery */
   6150     }
   6151 
   6152 exit:
   6153     SOC_FUNC_RETURN;
   6154 }
   6155 
   6156 int pm4x10_port_link_latch_down_get(int unit, int port, pm_info_t pm_info, uint32 flags, int* link)
   6157 {
   6158     int first_index, rv;
   6159     uint32 reg32_val, bitmap;
   6160     soc_field_t status_field, clear_field;
   6161     SOC_INIT_FUNC_DEFS;
   6162     
   6163     *link = 0;
   6164     
   6165     rv = _pm4x10_port_index_get(unit, port, pm_info, &first_index, &bitmap);
   6166     _SOC_IF_ERR_EXIT(rv);
   6167 
   6168      switch(first_index) {
   6169         case 0:
   6170             status_field = PORT0_LINKSTATUSf;
   6171             clear_field = PORT0_LINKDOWN_CLEARf;
   6172             break;
   6173 
   6174         case 1:
   6175             status_field = PORT1_LINKSTATUSf;
   6176             clear_field = PORT1_LINKDOWN_CLEARf;
   6177             break;
   6178 
   6179         case 2:
   6180             status_field = PORT2_LINKSTATUSf;
   6181             clear_field = PORT2_LINKDOWN_CLEARf;
   6182             break;
   6183 
   6184         case 3:
   6185             status_field = PORT3_LINKSTATUSf;
   6186             clear_field = PORT3_LINKDOWN_CLEARf;
   6187             break;
   6188 
   6189         default:
   6190             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
   6191                      (_SOC_MSG("Port %d, failed to get port index"), port));
   6192     }
   6193 
   6194     rv = READ_XLPORT_LINKSTATUS_DOWNr(unit, port, &reg32_val);
   6195     _SOC_IF_ERR_EXIT(rv);
   6196 
   6197     (*link) = soc_reg_field_get(unit, XLPORT_LINKSTATUS_DOWNr, 
   6198                                         reg32_val, status_field);
   6199 
   6200     if (PORTMOD_PORT_LINK_LATCH_DOWN_F_CLEAR & flags) {
   6201 
   6202         rv = READ_XLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, &reg32_val);
   6203         _SOC_IF_ERR_EXIT(rv);
   6204 
   6205         soc_reg_field_set(unit, XLPORT_LINKSTATUS_DOWN_CLEARr, 
   6206                                         &reg32_val, clear_field, 1);
   6207 
   6208         rv = WRITE_XLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, reg32_val);
   6209         _SOC_IF_ERR_EXIT(rv);
   6210 
   6211         sal_usleep(10);
   6212 
   6213         soc_reg_field_set(unit, XLPORT_LINKSTATUS_DOWN_CLEARr, 
   6214                                         &reg32_val, clear_field, 0);
   6215 
   6216         /* reset default register value */
   6217         rv = WRITE_XLPORT_LINKSTATUS_DOWN_CLEARr(unit, port, reg32_val);
   6218         _SOC_IF_ERR_EXIT(rv);
   6219 
   6220     }
   6221 
   6222         
   6223 exit:
   6224     SOC_FUNC_RETURN;
   6225 }
   6226 
   6227 /*
   6228     The field STRICT_PREAMBLE is used to check preamble+SFD strictly.
   6229     The preamble will be shrinked when some external PHY works at 1G,
   6230     so there are packet errors if STRICT_PREAMBLE is enabled.
   6231 */
   6232 int _pm4x10_port_strict_preamble_set(int unit, int port, pm_info_t pm_info)
   6233 {
   6234     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6235     int nof_phys;
   6236     int port_index=0;
   6237     uint32 bitmap;
   6238     phymod_phy_inf_config_t phy_config;
   6239     int is_higig = 0;
   6240     uint32 interface_modes;
   6241     int strict_preamble_enable=0;
   6242     SOC_INIT_FUNC_DEFS;
   6243 
   6244     _SOC_IF_ERR_EXIT
   6245         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   6246                                            phy_access ,(1+MAX_PHYN),
   6247                                            &nof_phys));
   6248 
   6249     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6250                                          &bitmap));
   6251     _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_config));
   6252 
   6253     _SOC_IF_ERR_EXIT
   6254         (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   6255                                                     0, PM_4x10_INFO(pm_info)->ref_clk,
   6256                                                     &phy_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   6257     _rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes, port_index);
   6258     _SOC_IF_ERR_EXIT(_rv);
   6259     is_higig =  interface_modes & PHYMOD_INTF_MODES_HIGIG ? 1 : 0;
   6260     if (!is_higig && (phy_config.data_rate>= 10000)) {
   6261         strict_preamble_enable = 1;
   6262     }
   6263     _rv = xlmac_strict_preamble_set(unit, port, strict_preamble_enable);
   6264     _SOC_IF_ERR_EXIT(_rv);
   6265 exit:
   6266     SOC_FUNC_RETURN;
   6267 }
   6268 
   6269 int pm4x10_port_phy_link_up_event(int unit, int port, pm_info_t pm_info)
   6270 {
   6271     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6272     int nof_phys;
   6273 
   6274     SOC_INIT_FUNC_DEFS;
   6275 
   6276     _SOC_IF_ERR_EXIT
   6277         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   6278                                            phy_access ,(1+MAX_PHYN),
   6279                                            &nof_phys));
   6280     _rv = portmod_port_phychain_phy_link_up_event(unit, port, phy_access, nof_phys);
   6281     _SOC_IF_ERR_EXIT(_rv);
   6282 
   6283     _SOC_IF_ERR_EXIT(_pm4x10_port_strict_preamble_set(unit, port, pm_info));
   6284 exit:
   6285     SOC_FUNC_RETURN;
   6286 }
   6287 
   6288 int pm4x10_port_phy_link_down_event(int unit, int port, pm_info_t pm_info)
   6289 {
   6290     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6291     int nof_phys;
   6292 
   6293     SOC_INIT_FUNC_DEFS;
   6294 
   6295     _SOC_IF_ERR_EXIT
   6296         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   6297                                            phy_access ,(1+MAX_PHYN),
   6298                                            &nof_phys));
   6299     
   6300     _rv = portmod_port_phychain_phy_link_down_event(unit, port, phy_access, nof_phys);
   6301 
   6302 exit:
   6303     SOC_FUNC_RETURN;
   6304 
   6305 }
   6306 
   6307 int pm4x10_port_mac_link_get(int unit, int port, pm_info_t pm_info, int* link)
   6308 {
   6309     uint32 reg_val, bitmap;
   6310     int port_index, phy_acc;
   6311     SOC_INIT_FUNC_DEFS;
   6312     SOC_NULL_CHECK(pm_info);
   6313 
   6314     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   6315 
   6316     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, 
   6317                                              &bitmap));
   6318 
   6319     switch(port_index) {
   6320         case 0:
   6321             _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_LN0_STATUS0_REGr(unit, phy_acc, 
   6322                                         &reg_val));
   6323             (*link) = soc_reg_field_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, 
   6324                                         reg_val, LINK_STATUSf);
   6325             break;
   6326 
   6327         case 1:
   6328             _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_LN1_STATUS0_REGr(unit, phy_acc, 
   6329                                          &reg_val));
   6330             (*link) = soc_reg_field_get(unit, XLPORT_XGXS0_LN1_STATUS0_REGr, 
   6331                                           reg_val, LINK_STATUSf);
   6332             break;
   6333 
   6334         case 2:
   6335             _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_LN2_STATUS0_REGr(unit, phy_acc, 
   6336                                           &reg_val));
   6337             (*link) = soc_reg_field_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, 
   6338                                           reg_val, LINK_STATUSf);
   6339             break;
   6340 
   6341         case 3:
   6342             _SOC_IF_ERR_EXIT(READ_XLPORT_XGXS0_LN3_STATUS0_REGr(unit, phy_acc, 
   6343                                            &reg_val));
   6344             (*link) = soc_reg_field_get(unit, XLPORT_XGXS0_LN3_STATUS0_REGr, 
   6345                                            reg_val, LINK_STATUSf);
   6346             break;
   6347 
   6348         default:
   6349             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL,
   6350                      (_SOC_MSG("Port %d, failed to get port index"), port));
   6351     }
   6352 
   6353 exit:
   6354     SOC_FUNC_RETURN;
   6355 }
   6356 
   6357 
   6358 int pm4x10_port_prbs_config_set(int unit, int port, pm_info_t pm_info, 
   6359                      portmod_prbs_mode_t mode, int flags, const phymod_prbs_t* config)
   6360 {
   6361     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6362     int nof_phys;
   6363     int port_index;
   6364     uint32 bitmap;
   6365     
   6366     SOC_INIT_FUNC_DEFS;
   6367 
   6368     if(mode == 1 /*MAC*/) {
   6369         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   6370                  (_SOC_MSG("MAC PRBS is not supported for PM4x10")));
   6371     }
   6372 
   6373     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6374                                              &bitmap));
   6375 
   6376     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   6377         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   6378                             (_SOC_MSG("phy PRBS isn't supported")));
   6379     }
   6380 
   6381     _SOC_IF_ERR_EXIT
   6382         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6383                                            phy_access ,(1+MAX_PHYN),
   6384                                            &nof_phys));
   6385     _SOC_IF_ERR_EXIT
   6386         (portmod_port_phychain_prbs_config_set(unit, phy_access, nof_phys, flags, config));
   6387 
   6388 exit:
   6389     SOC_FUNC_RETURN;
   6390 }
   6391 
   6392 int pm4x10_port_prbs_config_get (int unit, int port, pm_info_t pm_info, 
   6393                                  portmod_prbs_mode_t mode, int flags, phymod_prbs_t* config)
   6394 {
   6395     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6396     int nof_phys;
   6397     int port_index;
   6398     uint32 bitmap;
   6399 
   6400     SOC_INIT_FUNC_DEFS;
   6401 
   6402     if(mode == 1 /*MAC*/) {
   6403         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   6404                       (_SOC_MSG("MAC PRBS is not supported for PM4x10")));
   6405     }
   6406 
   6407     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6408                                              &bitmap));
   6409 
   6410     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   6411         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   6412                        (_SOC_MSG("phy PRBS isn't supported")));
   6413     }
   6414 
   6415     _SOC_IF_ERR_EXIT
   6416         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6417                                            phy_access ,(1+MAX_PHYN),
   6418                                            &nof_phys));
   6419     _SOC_IF_ERR_EXIT
   6420         (portmod_port_phychain_prbs_config_get(unit, phy_access, nof_phys, flags, config));
   6421 
   6422 exit:
   6423     SOC_FUNC_RETURN;
   6424 }
   6425 
   6426 
   6427 int pm4x10_port_prbs_enable_set (int unit, int port, pm_info_t pm_info, 
   6428                                  portmod_prbs_mode_t mode, int flags, int enable)
   6429 {
   6430     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6431     int nof_phys;
   6432     int port_index;
   6433     uint32 bitmap;
   6434 
   6435     SOC_INIT_FUNC_DEFS;
   6436     
   6437     if(mode == 1 /*MAC*/) {
   6438         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (
   6439               _SOC_MSG("MAC PRBS is not supported for PM4x10")));
   6440     }
   6441     
   6442     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6443                                              &bitmap));
   6444 
   6445     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   6446         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (
   6447               _SOC_MSG("phy PRBS isn't supported")));
   6448     }
   6449 
   6450     _SOC_IF_ERR_EXIT
   6451         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6452                                            phy_access ,(1+MAX_PHYN),
   6453                                            &nof_phys));
   6454     _SOC_IF_ERR_EXIT
   6455         (portmod_port_phychain_prbs_enable_set(unit, phy_access, nof_phys, flags, enable));
   6456 
   6457 exit:
   6458     SOC_FUNC_RETURN;
   6459 }
   6460 
   6461 int pm4x10_port_prbs_enable_get (int unit, int port, pm_info_t pm_info, 
   6462                                  portmod_prbs_mode_t mode, int flags, int* enable)
   6463 {
   6464     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6465     uint32 is_enabled;
   6466     int nof_phys;
   6467     int port_index;
   6468     uint32 bitmap;
   6469 
   6470     SOC_INIT_FUNC_DEFS;
   6471 
   6472     if(mode == 1 /*MAC*/) {
   6473         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   6474                  (_SOC_MSG("MAC PRBS is not supported for PM4x10")));
   6475     }
   6476 
   6477     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6478                                              &bitmap));
   6479 
   6480     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   6481         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   6482                     (_SOC_MSG("phy PRBS isn't supported")));
   6483     }
   6484 
   6485     _SOC_IF_ERR_EXIT
   6486         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6487                                            phy_access ,(1+MAX_PHYN),
   6488                                            &nof_phys));
   6489 
   6490     _SOC_IF_ERR_EXIT
   6491         (portmod_port_phychain_prbs_enable_get(unit, phy_access, nof_phys, flags, &is_enabled));
   6492 
   6493     (*enable) = (is_enabled ? 1 : 0);
   6494 
   6495 exit:
   6496     SOC_FUNC_RETURN;
   6497 }
   6498 
   6499 
   6500 int pm4x10_port_prbs_status_get(int unit, int port, pm_info_t pm_info, 
   6501                     portmod_prbs_mode_t mode, int flags, phymod_prbs_status_t* status)
   6502 {
   6503     phymod_phy_access_t phy_access[1+MAX_PHYN];
   6504     int nof_phys;
   6505     int port_index;
   6506     uint32 bitmap;
   6507 
   6508     SOC_INIT_FUNC_DEFS;
   6509 
   6510     if(mode == 1 /*MAC*/) {
   6511         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 
   6512                 (_SOC_MSG("MAC PRBS is not supported for PM4x10")));
   6513     }
   6514 
   6515     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6516                                              &bitmap));
   6517 
   6518     if(PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   6519         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, 
   6520                     (_SOC_MSG("phy PRBS isn't supported")));
   6521     }
   6522 
   6523     _SOC_IF_ERR_EXIT
   6524         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   6525                                            phy_access ,(1+MAX_PHYN),
   6526                                            &nof_phys));
   6527     _SOC_IF_ERR_EXIT
   6528         (portmod_port_phychain_prbs_status_get(unit, phy_access, nof_phys, flags, status));
   6529 
   6530 exit:
   6531     SOC_FUNC_RETURN;
   6532 
   6533 }
   6534 
   6535 int pm4x10_port_nof_lanes_get(int unit, int port, pm_info_t pm_info, int *nof_lanes)
   6536 {
   6537     int temp_nof_lanes = 0;
   6538     SOC_INIT_FUNC_DEFS;
   6539 
   6540     temp_nof_lanes = _pm4x10_nof_lanes_get(unit, port, pm_info);
   6541     if(0 == temp_nof_lanes){
   6542         SOC_EXIT;
   6543     }
   6544     else{
   6545         *nof_lanes = temp_nof_lanes;
   6546     }
   6547 
   6548 exit:
   6549     SOC_FUNC_RETURN;
   6550 }
   6551 
   6552 
   6553 int pm4x10_port_firmware_mode_set (int unit, int port, pm_info_t pm_info,
   6554                                    phymod_firmware_mode_t fw_mode)
   6555 {
   6556         
   6557     SOC_INIT_FUNC_DEFS;
   6558     SOC_NULL_CHECK(pm_info);
   6559     
   6560     /* Place your code here */
   6561 
   6562         
   6563 exit:
   6564     SOC_FUNC_RETURN; 
   6565     
   6566 }
   6567 
   6568 int pm4x10_port_firmware_mode_get (int unit, int port, pm_info_t pm_info, 
   6569                                    phymod_firmware_mode_t* fw_mode)
   6570 {
   6571         
   6572     SOC_INIT_FUNC_DEFS;
   6573     SOC_NULL_CHECK(pm_info);
   6574     
   6575     /* Place your code here */
   6576 
   6577         
   6578 exit:
   6579     SOC_FUNC_RETURN; 
   6580     
   6581 }
   6582 
   6583 
   6584 int pm4x10_port_runt_threshold_set (int unit, int port, 
   6585                                     pm_info_t pm_info, int value)
   6586 {
   6587         
   6588     SOC_INIT_FUNC_DEFS;
   6589     SOC_NULL_CHECK(pm_info);
   6590     
   6591     /* Place your code here */
   6592         
   6593 exit:
   6594     SOC_FUNC_RETURN; 
   6595     
   6596 }
   6597 
   6598 int pm4x10_port_runt_threshold_get(int unit, int port, pm_info_t pm_info, int* value)
   6599 {
   6600         
   6601     SOC_INIT_FUNC_DEFS;
   6602     SOC_NULL_CHECK(pm_info);
   6603     
   6604     /* Place your code here */
   6605 
   6606         
   6607 exit:
   6608     SOC_FUNC_RETURN; 
   6609     
   6610 }
   6611 
   6612 
   6613 int pm4x10_port_max_packet_size_set (int unit, int port, 
   6614                                      pm_info_t pm_info, int value)
   6615 {
   6616     SOC_INIT_FUNC_DEFS;
   6617 
   6618     _SOC_IF_ERR_EXIT(xlmac_rx_max_size_set(unit, port, value));
   6619 
   6620 exit:
   6621     SOC_FUNC_RETURN;
   6622 }
   6623 
   6624 int pm4x10_port_max_packet_size_get (int unit, int port, 
   6625                                      pm_info_t pm_info, int* value)
   6626 {
   6627     SOC_INIT_FUNC_DEFS;
   6628     _SOC_IF_ERR_EXIT(xlmac_rx_max_size_get(unit, port, value));
   6629 
   6630 exit:
   6631     SOC_FUNC_RETURN;
   6632 }
   6633 
   6634 
   6635 int pm4x10_port_pad_size_set(int unit, int port, pm_info_t pm_info, int value)
   6636 {        
   6637     SOC_INIT_FUNC_DEFS;
   6638     SOC_NULL_CHECK(pm_info);
   6639     
   6640     _SOC_IF_ERR_EXIT(xlmac_pad_size_set(unit, port , value));
   6641         
   6642 exit:
   6643     SOC_FUNC_RETURN; 
   6644     
   6645 }
   6646 
   6647 int pm4x10_port_pad_size_get(int unit, int port, pm_info_t pm_info, int* value)
   6648 {        
   6649     SOC_INIT_FUNC_DEFS;
   6650     SOC_NULL_CHECK(pm_info);
   6651     
   6652     _SOC_IF_ERR_EXIT(xlmac_pad_size_get(unit, port , value));
   6653         
   6654 exit:
   6655     SOC_FUNC_RETURN;     
   6656 }
   6657 
   6658 
   6659 int pm4x10_port_tx_drop_on_local_fault_set (int unit, int port, 
   6660                                             pm_info_t pm_info, int enable)
   6661 {
   6662     portmod_local_fault_control_t control;
   6663     SOC_INIT_FUNC_DEFS;
   6664 
   6665     portmod_local_fault_control_t_init(unit, &control);
   6666     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_get(unit, port, pm_info, &control));
   6667 
   6668     control.drop_tx_on_fault  = enable;
   6669     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_set(unit, port, pm_info, &control));
   6670 
   6671 exit:
   6672     SOC_FUNC_RETURN;
   6673 }
   6674 
   6675 int pm4x10_port_tx_drop_on_local_fault_get (int unit, int port, 
   6676                                             pm_info_t pm_info, int* enable)
   6677 {
   6678     portmod_local_fault_control_t control;
   6679     SOC_INIT_FUNC_DEFS;
   6680 
   6681     portmod_local_fault_control_t_init(unit, &control);
   6682     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_get(unit, port, pm_info, &control));
   6683     *enable = control.drop_tx_on_fault;
   6684 
   6685 exit:
   6686     SOC_FUNC_RETURN;
   6687 }
   6688 
   6689 
   6690 int pm4x10_port_tx_drop_on_remote_fault_set(int unit, int port,
   6691                                             pm_info_t pm_info, int enable)
   6692 {
   6693     portmod_remote_fault_control_t control;
   6694     SOC_INIT_FUNC_DEFS;
   6695 
   6696     portmod_remote_fault_control_t_init(unit, &control);
   6697 
   6698     _SOC_IF_ERR_EXIT(pm4x10_port_remote_fault_control_get(unit, port, pm_info, &control));
   6699     control.drop_tx_on_fault = enable;
   6700     _SOC_IF_ERR_EXIT(pm4x10_port_remote_fault_control_set(unit, port, pm_info,  &control));
   6701 
   6702 exit:
   6703     SOC_FUNC_RETURN;
   6704 }
   6705 
   6706 int pm4x10_port_tx_drop_on_remote_fault_get (int unit, int port, 
   6707                                              pm_info_t pm_info, int* enable)
   6708 {
   6709     portmod_remote_fault_control_t control;
   6710     SOC_INIT_FUNC_DEFS;
   6711 
   6712     portmod_remote_fault_control_t_init(unit, &control);
   6713     _SOC_IF_ERR_EXIT(pm4x10_port_remote_fault_control_get(unit, port, pm_info, &control));
   6714     *enable = control.drop_tx_on_fault;
   6715 
   6716 exit:
   6717     SOC_FUNC_RETURN;
   6718 }
   6719 
   6720 int pm4x10_port_local_fault_enable_set (int unit, int port, 
   6721                                         pm_info_t pm_info, int enable)
   6722 {
   6723     portmod_local_fault_control_t control;
   6724     SOC_INIT_FUNC_DEFS;
   6725 
   6726     portmod_local_fault_control_t_init(unit, &control);
   6727 
   6728     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_get(unit, port, pm_info, &control));
   6729     control.enable = enable;
   6730     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_set(unit, port, pm_info, &control));
   6731 
   6732 exit:
   6733     SOC_FUNC_RETURN;
   6734 }
   6735 
   6736 int pm4x10_port_local_fault_enable_get (int unit, int port, 
   6737                                         pm_info_t pm_info, int* enable)
   6738 {
   6739     portmod_local_fault_control_t control;
   6740     SOC_INIT_FUNC_DEFS;
   6741 
   6742     portmod_local_fault_control_t_init(unit, &control);
   6743 
   6744     _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_control_get(unit, port, pm_info, &control));
   6745     *enable = control.enable;
   6746 
   6747 exit:
   6748     SOC_FUNC_RETURN;
   6749 }
   6750 
   6751 int pm4x10_port_local_fault_status_get(int unit, int port,
   6752                                        pm_info_t pm_info, int* value)
   6753 {
   6754     int rv;
   6755     SOC_INIT_FUNC_DEFS;
   6756 
   6757     rv = xlmac_local_fault_status_get(unit, port, value);
   6758     _SOC_IF_ERR_EXIT(rv);
   6759 exit:
   6760     SOC_FUNC_RETURN;
   6761 }
   6762 
   6763 int pm4x10_port_local_fault_control_set(int unit, int port, pm_info_t pm_info,
   6764                     const portmod_local_fault_control_t* control)
   6765 {
   6766     int rv;
   6767     SOC_INIT_FUNC_DEFS;
   6768 
   6769     rv = xlmac_local_fault_control_set(unit, port, control);
   6770     _SOC_IF_ERR_EXIT(rv);
   6771 exit:
   6772     SOC_FUNC_RETURN;
   6773 }
   6774 
   6775 int pm4x10_port_local_fault_control_get(int unit, int port, pm_info_t pm_info,
   6776                     portmod_local_fault_control_t* control)
   6777 {
   6778     int rv;
   6779     SOC_INIT_FUNC_DEFS;
   6780 
   6781     rv = xlmac_local_fault_control_get(unit, port, control);
   6782     _SOC_IF_ERR_EXIT(rv);
   6783 exit:
   6784     SOC_FUNC_RETURN;
   6785 }
   6786 
   6787 int pm4x10_port_remote_fault_status_get(int unit, int port,
   6788                                         pm_info_t pm_info, int* value)
   6789 {
   6790     int rv;
   6791     SOC_INIT_FUNC_DEFS;
   6792 
   6793     rv = xlmac_remote_fault_status_get(unit, port, value);
   6794     _SOC_IF_ERR_EXIT(rv);
   6795 exit:
   6796     SOC_FUNC_RETURN;
   6797 }
   6798 
   6799 int pm4x10_port_remote_fault_control_set(int unit, int port, pm_info_t pm_info,
   6800                     const portmod_remote_fault_control_t* control)
   6801 {
   6802     int rv;
   6803     SOC_INIT_FUNC_DEFS;
   6804 
   6805     rv = xlmac_remote_fault_control_set(unit, port, control);
   6806     _SOC_IF_ERR_EXIT(rv);
   6807 exit:
   6808     SOC_FUNC_RETURN;
   6809 }
   6810 
   6811 int pm4x10_port_remote_fault_control_get(int unit, int port, pm_info_t pm_info,
   6812                     portmod_remote_fault_control_t* control)
   6813 {
   6814     int rv;
   6815     SOC_INIT_FUNC_DEFS;
   6816 
   6817     rv = xlmac_remote_fault_control_get(unit, port, control);
   6818     _SOC_IF_ERR_EXIT(rv);
   6819 exit:
   6820     SOC_FUNC_RETURN;
   6821 }
   6822 
   6823 
   6824 int pm4x10_port_pause_control_set(int unit, int port, pm_info_t pm_info, 
   6825                                   const portmod_pause_control_t* control)
   6826 {
   6827     SOC_INIT_FUNC_DEFS;
   6828     _SOC_IF_ERR_EXIT(xlmac_pause_control_set(unit, port, control));
   6829 exit:
   6830     SOC_FUNC_RETURN;
   6831 }
   6832 
   6833 int pm4x10_port_pause_control_get(int unit, int port, pm_info_t pm_info,
   6834                                   portmod_pause_control_t* control)
   6835 {
   6836     SOC_INIT_FUNC_DEFS;
   6837     _SOC_IF_ERR_EXIT(xlmac_pause_control_get(unit, port, control));
   6838 exit:
   6839     SOC_FUNC_RETURN;
   6840 }
   6841 
   6842 int pm4x10_port_llfc_control_set(int unit, int port, 
   6843            pm_info_t pm_info, const portmod_llfc_control_t* control)
   6844 {
   6845     SOC_INIT_FUNC_DEFS;
   6846     _SOC_IF_ERR_EXIT(xlmac_llfc_control_set(unit, port, control));
   6847 exit:
   6848     SOC_FUNC_RETURN;
   6849 }
   6850 
   6851 int pm4x10_port_llfc_control_get(int unit, int port,
   6852             pm_info_t pm_info, portmod_llfc_control_t* control)
   6853 {
   6854     SOC_INIT_FUNC_DEFS;
   6855     _SOC_IF_ERR_EXIT(xlmac_llfc_control_get(unit, port, control));
   6856 
   6857 exit:
   6858     SOC_FUNC_RETURN;
   6859 }
   6860 
   6861 int pm4x10_port_core_access_get (int unit, int port, 
   6862                                  pm_info_t pm_info, int phyn, int max_cores, 
   6863                                  phymod_core_access_t* core_access_arr, 
   6864                                  int* nof_cores,
   6865                                  int* is_most_ext)
   6866 {
   6867     int port_index;
   6868     uint32 bitmap;
   6869     int index;
   6870     int done=0;
   6871     int i,j, is_legacy_phy;
   6872     uint32 xphy_id;
   6873     phymod_core_access_t core_access;   
   6874  
   6875     SOC_INIT_FUNC_DEFS;
   6876 
   6877     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   6878                                              &bitmap));
   6879 
   6880     if(phyn > PM_4x10_INFO(pm_info)->nof_phys[port_index]){
   6881         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 
   6882                (_SOC_MSG("phyn exceeded. max allowed %d. got %d"), 
   6883                        PM_4x10_INFO(pm_info)->nof_phys[port_index] - 1, phyn));
   6884     }
   6885 
   6886     if(phyn < 0)
   6887     {
   6888         phyn = PM_4x10_INFO(pm_info)->nof_phys[port_index] - 1;
   6889     }
   6890 
   6891     _SOC_IF_ERR_EXIT(phymod_core_access_t_init(&core_access_arr[0]));
   6892 
   6893     if( phyn == 0 ){
   6894         sal_memcpy(&core_access_arr[0], &(PM_4x10_INFO(pm_info)->int_core_access),
   6895                      sizeof(phymod_core_access_t));
   6896         *nof_cores = 1;
   6897     } else {
   6898         index = 0;
   6899         done = 0;
   6900         for(i=0 ; (i< MAX_PORTS_PER_PM4X10); i++) {
   6901             if(bitmap & (0x1U << i)) {
   6902                 xphy_id = PM_4x10_INFO(pm_info)->lane_conn[phyn-1][i].xphy_id;
   6903                 if(xphy_id != PORTMOD_XPHY_ID_INVALID){
   6904                     if(index == 0){
   6905                         _SOC_IF_ERR_EXIT(portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_phy));
   6906                         sal_memcpy(&core_access_arr[index], &core_access,
   6907                                    sizeof(phymod_core_access_t));
   6908                         index++;
   6909                     } else {
   6910                         for( j = 0 ; (j < index) &&(!done) ; j++) {
   6911                              if((!sal_memcmp (&core_access_arr[j], &core_access,
   6912                                                sizeof(phymod_core_access_t)))) { /* found a match */
   6913                                 done = 1;
   6914                             }
   6915                         }
   6916                         if((!done) && (index < max_cores)){                        
   6917                             sal_memcpy(&core_access_arr[index], &core_access,
   6918                                        sizeof(phymod_core_access_t));
   6919                             index++;
   6920                         }
   6921                     }
   6922                 }
   6923             }
   6924         }
   6925         *nof_cores = index;
   6926     }
   6927     if (is_most_ext) {
   6928         if (phyn == PM_4x10_INFO(pm_info)->nof_phys[port_index]-1) {
   6929             *is_most_ext = 1;
   6930         } else {
   6931             *is_most_ext = 0;
   6932         }
   6933     }
   6934 
   6935 exit:
   6936     SOC_FUNC_RETURN;
   6937 }
   6938 
   6939 /*!
   6940  * pm4x10_port_frame_spacing_stretch_set
   6941  *
   6942  * @brief Port Mac Control Spacing Stretch 
   6943  *
   6944  * @param [in]  unit            - unit id
   6945  * @param [in]  port            - logical port
   6946  * @param [in]  spacing         - 
   6947  */
   6948 int pm4x10_port_frame_spacing_stretch_set (int unit, int port, 
   6949                                            pm_info_t pm_info,int spacing)
   6950 {
   6951     return(xlmac_frame_spacing_stretch_set(unit, port, spacing));
   6952 }
   6953 
   6954 /*! 
   6955  * pm4x10_port_frame_spacing_stretch_get
   6956  *
   6957  * @brief Port Mac Control Spacing Stretch 
   6958  *
   6959  * @param [in]  unit            - unit id
   6960  * @param [in]  port            - logical port
   6961  * @param [in]  spacing         - 
   6962  */
   6963 int pm4x10_port_frame_spacing_stretch_get (int unit, int port,
   6964                                             pm_info_t pm_info, 
   6965                                             const int *spacing)
   6966 {
   6967     return (xlmac_frame_spacing_stretch_get(unit, port, (int*)spacing));
   6968 }
   6969 
   6970 /*! 
   6971  * pm4x10_port_diag_fifo_status_get
   6972  *
   6973  * @brief get port timestamps in fifo 
   6974  *
   6975  * @param [in]  unit            - unit id
   6976  * @param [in]  port            - logical port
   6977  * @param [in]  diag_info       - 
   6978  */
   6979 int pm4x10_port_diag_fifo_status_get (int unit, int port,pm_info_t pm_info, 
   6980                                  const portmod_fifo_status_t* diag_info)
   6981 {
   6982     return(xlmac_diag_fifo_status_get(unit, port, diag_info));
   6983 }
   6984 
   6985 int _xlport_pfc_config_set(int unit, int port, uint32 value)
   6986 {
   6987     int rv = SOC_E_UNAVAIL;
   6988     uint32 rval32 = 0;
   6989 
   6990     if (SOC_REG_IS_VALID(unit,XLPORT_MAC_RSV_MASKr)) {
   6991         rv = READ_XLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   6992         if (SOC_SUCCESS(rv)) {
   6993             /* XLPORT_MAC_RSV_MASK: Bit 18 PFC frame detected
   6994              * Enable  PFC Frame : Set 0. Go through
   6995              * Disable PFC Frame : Set 1. Purged.
   6996              */
   6997             if(value) {
   6998                 rval32 &= ~(1 << 18);
   6999             } else {
   7000                 rval32 |= (1 << 18);
   7001             }
   7002             rv = WRITE_XLPORT_MAC_RSV_MASKr(unit, port, rval32);
   7003         }
   7004     }
   7005 
   7006     return rv;
   7007 }
   7008 
   7009 int _xlport_pfc_config_get(int unit, int port, uint32* value)
   7010 {
   7011     int rv = SOC_E_NONE;
   7012     uint32 rval32 = 0;
   7013 
   7014     if (SOC_REG_IS_VALID(unit,XLPORT_MAC_RSV_MASKr)) {
   7015         rv = READ_XLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   7016         if (SOC_SUCCESS(rv)) {
   7017             /* XLPORT_MAC_RSV_MASK: Bit 18 PFC frame detected
   7018              * Enable  PFC Frame : Set 0. Go through
   7019              * Disable PFC Frame : Set 1. Purged.
   7020              */
   7021             *value = ((rval32 & 0x40000) >> 18) ? 0 : 1;
   7022         }
   7023     }
   7024 
   7025     return rv;
   7026 }
   7027 
   7028 /*! 
   7029  * pm4x10_port_pfc_config_set
   7030  *
   7031  * @brief set pass control frames. 
   7032  *
   7033  * @param [in]  unit            - unit id
   7034  * @param [in]  port            - logical port
   7035  * @param [in]  pfc_cfg         - 
   7036  */
   7037 int pm4x10_port_pfc_config_set (int unit, int port,pm_info_t pm_info,
   7038                            const portmod_pfc_config_t* pfc_cfg)
   7039 {
   7040     SOC_INIT_FUNC_DEFS;
   7041 
   7042     if (pfc_cfg->classes != 8) {
   7043         return SOC_E_PARAM;
   7044     }
   7045     _SOC_IF_ERR_EXIT(xlmac_pfc_config_set(unit, port, pfc_cfg));
   7046     _SOC_IF_ERR_EXIT(_xlport_pfc_config_set(unit, port, pfc_cfg->rxpass));
   7047 exit:
   7048     SOC_FUNC_RETURN; 
   7049 }
   7050 
   7051 
   7052 /*! 
   7053  * pm4x10_port_pfc_config_get
   7054  *
   7055  * @brief set pass control frames. 
   7056  *
   7057  * @param [in]  unit            - unit id
   7058  * @param [in]  port            - logical port
   7059  * @param [in]  pfc_cfg         - 
   7060  */
   7061 int pm4x10_port_pfc_config_get (int unit, int port,pm_info_t pm_info, 
   7062                                 portmod_pfc_config_t* pfc_cfg)
   7063 {
   7064     SOC_INIT_FUNC_DEFS;
   7065 
   7066     pfc_cfg->classes = 8;
   7067     _SOC_IF_ERR_EXIT(xlmac_pfc_config_get(unit, port, pfc_cfg));
   7068 
   7069     _SOC_IF_ERR_EXIT(_xlport_pfc_config_get(unit, port, &pfc_cfg->rxpass));
   7070 exit:
   7071     SOC_FUNC_RETURN; 
   7072 }
   7073 
   7074 int pm4x10_port_pfc_control_set(int unit, int port, pm_info_t pm_info, const portmod_pfc_control_t* control)
   7075 {
   7076         
   7077     SOC_INIT_FUNC_DEFS;
   7078     _SOC_IF_ERR_EXIT(xlmac_pfc_control_set(unit, port, control));        
   7079 exit:
   7080     SOC_FUNC_RETURN; 
   7081     
   7082 }
   7083 
   7084 int pm4x10_port_pfc_control_get(int unit, int port, pm_info_t pm_info, portmod_pfc_control_t* control)
   7085 {
   7086         
   7087     SOC_INIT_FUNC_DEFS;
   7088     _SOC_IF_ERR_EXIT(xlmac_pfc_control_get(unit, port, control));     
   7089 exit:
   7090     SOC_FUNC_RETURN; 
   7091     
   7092 }
   7093 
   7094 /*!
   7095  * pm4x10_port_eee_set
   7096  *
   7097  * @brief set EEE control and timers
   7098  *
   7099  * @param [in]  unit            - unit id
   7100  * @param [in]  port            - logical port
   7101  * @param [in]  eee             -
   7102  */
   7103 int pm4x10_port_eee_set(int unit, int port, pm_info_t pm_info,const portmod_eee_t* eee)
   7104 {
   7105     return (xlmac_eee_set(unit, port, eee));
   7106 }
   7107 
   7108 /*!
   7109  * pm4x10_port_eee_get
   7110  *
   7111  * @brief get EEE control and timers
   7112  *
   7113  * @param [in]  unit            - unit id
   7114  * @param [in]  port            - logical port
   7115  * @param [in]  eee             -
   7116  */
   7117 int pm4x10_port_eee_get(int unit, int port, pm_info_t pm_info, portmod_eee_t* eee)
   7118 {
   7119     return (xlmac_eee_get(unit, port, eee));
   7120 }
   7121 
   7122 /*! 
   7123  * pm4x10_port_vlan_tag_set
   7124  *
   7125  * @brief vlan tag set. 
   7126  *
   7127  * @param [in]  unit            - unit id
   7128  * @param [in]  port            - logical port
   7129  * @param [in]  vlan_tag        - 
   7130  */
   7131 int pm4x10_port_vlan_tag_set(int unit, int port, pm_info_t pm_info,const portmod_vlan_tag_t* vlan_tag)
   7132 {
   7133     return (xlmac_rx_vlan_tag_set (unit, port, vlan_tag->outer_vlan_tag,
   7134                                    vlan_tag->inner_vlan_tag));
   7135 }
   7136 
   7137 
   7138 /*! 
   7139  * pm4x10_port_vlan_tag_get
   7140  *
   7141  * @brief vlan tag get. 
   7142  *
   7143  * @param [in]  unit            - unit id
   7144  * @param [in]  port            - logical port
   7145  * @param [in]  vlan_tag        - 
   7146  */
   7147 int pm4x10_port_vlan_tag_get(int unit, int port, pm_info_t pm_info, portmod_vlan_tag_t* vlan_tag)
   7148 {
   7149     return (xlmac_rx_vlan_tag_get (unit, port, (int*)&vlan_tag->outer_vlan_tag,
   7150                                    (int*)&vlan_tag->inner_vlan_tag));
   7151 }
   7152 
   7153 /*! 
   7154  * pm4x10_port_duplex_set
   7155  *
   7156  * @brief duplex set. 
   7157  *
   7158  * @param [in]  unit            - unit id
   7159  * @param [in]  port            - logical port
   7160  * @param [in]  enable        - 
   7161  */
   7162 int pm4x10_port_duplex_set(int unit, int port, pm_info_t pm_info,int enable)
   7163 {
   7164     return (xlmac_duplex_set (unit, port, enable)); 
   7165 }
   7166 
   7167 
   7168 /*! 
   7169  * pm4x10_port_duplex_get
   7170  *
   7171  * @brief duplex get. 
   7172  *
   7173  * @param [in]  unit            - unit id
   7174  * @param [in]  port            - logical port
   7175  * @param [in]  vlan_tag        - 
   7176  */
   7177 int pm4x10_port_duplex_get(int unit, int port, pm_info_t pm_info, int* enable)
   7178 {
   7179     return (xlmac_duplex_get (unit, port, enable)); 
   7180 }
   7181 
   7182 /*!
   7183  * pm4x10_port_speed_get
   7184  *
   7185  * @brief duplex get.
   7186  *
   7187  * @param [in]  unit            - unit id
   7188  * @param [in]  port            - logical port
   7189  * @param [in]  speed         -
   7190  */
   7191 int pm4x10_port_speed_get(int unit, int port, pm_info_t pm_info, int* speed)
   7192 {
   7193     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7194     phymod_phy_inf_config_t config;
   7195     int nof_phys, rv;
   7196 
   7197     rv = portmod_port_chain_phy_access_get(unit, port, pm_info,
   7198                                            phy_access ,(1+MAX_PHYN),
   7199                                            &nof_phys);
   7200     if (rv) return(rv);
   7201 
   7202     rv = phymod_phy_interface_config_get(&phy_access[0], 0,0,  &config);
   7203     if (rv) return (rv);
   7204 
   7205     *speed = config.data_rate;
   7206     return (rv);
   7207 }
   7208 
   7209 int pm4x10_port_phy_reg_read(int unit, int port, pm_info_t pm_info, int lane, int flags, int reg_addr, uint32* value)
   7210 {
   7211     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7212     int nof_phys;
   7213     SOC_INIT_FUNC_DEFS;
   7214 
   7215     _SOC_IF_ERR_EXIT
   7216         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7217                                            phy_access ,(1+MAX_PHYN),
   7218                                            &nof_phys));
   7219     _SOC_IF_ERR_EXIT
   7220         (portmod_port_phychain_reg_read(unit, port, phy_access, nof_phys, lane, flags, reg_addr,value));
   7221 
   7222 exit:
   7223     SOC_FUNC_RETURN;
   7224 }
   7225 
   7226 int pm4x10_port_phy_reg_write(int unit, int port, pm_info_t pm_info, int lane, int flags, int reg_addr, uint32 value)
   7227 {
   7228     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7229     int nof_phys;
   7230     SOC_INIT_FUNC_DEFS;
   7231 
   7232     _SOC_IF_ERR_EXIT
   7233         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7234                                            phy_access ,(1+MAX_PHYN),
   7235                                            &nof_phys));
   7236     _SOC_IF_ERR_EXIT
   7237         (portmod_port_phychain_reg_write(unit, port, phy_access, nof_phys, lane, flags, reg_addr,value));
   7238 
   7239 exit:
   7240     SOC_FUNC_RETURN;
   7241 }
   7242 
   7243 int pm4x10_port_check_legacy_phy (int unit, int port, pm_info_t pm_info, int *legacy_phy)
   7244 {
   7245     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7246     int nof_phys, xphy_id, is_legacy_phy;
   7247     int port_index;
   7248     uint32 bitmap;
   7249 
   7250     SOC_INIT_FUNC_DEFS;
   7251 
   7252     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   7253                                              &bitmap));
   7254 
   7255     *legacy_phy = 0;
   7256 
   7257     if (PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   7258         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7259                            (_SOC_MSG("phy reset is not supported")));
   7260     }
   7261 
   7262     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7263                                                        phy_access ,(1+MAX_PHYN),
   7264                                                        &nof_phys));
   7265      while (nof_phys > 1) {
   7266          nof_phys--;
   7267          xphy_id = phy_access[nof_phys].access.addr;
   7268          _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   7269          if (is_legacy_phy) {
   7270              *legacy_phy = 1;
   7271              break;
   7272          }          
   7273      }
   7274 
   7275 exit:
   7276     SOC_FUNC_RETURN;
   7277 }
   7278 
   7279 int pm4x10_port_reset_set (int unit, int port, pm_info_t pm_info, 
   7280                            int reset_mode, int opcode, int direction)
   7281 {
   7282     phymod_core_access_t core_access[1+MAX_PHYN];
   7283     int nof_phys;
   7284     int port_index;
   7285     uint32 bitmap;
   7286 
   7287     SOC_INIT_FUNC_DEFS;
   7288 
   7289     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   7290                                              &bitmap));
   7291 
   7292     if (PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   7293         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7294                            (_SOC_MSG("phy reset is not supported")));
   7295     }
   7296 
   7297     _SOC_IF_ERR_EXIT
   7298         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   7299                                            (phymod_phy_access_t*)core_access,
   7300                                            (1+MAX_PHYN), &nof_phys));
   7301 
   7302     _SOC_IF_ERR_EXIT
   7303         (portmod_port_phychain_core_reset_set(unit, core_access, nof_phys,
   7304                                             (phymod_reset_mode_t)reset_mode, 
   7305                                             (phymod_reset_direction_t)direction));
   7306 
   7307 exit:
   7308     SOC_FUNC_RETURN;
   7309 }
   7310 
   7311 int pm4x10_port_reset_get (int unit, int port, pm_info_t pm_info, 
   7312                            int reset_mode, int opcode, int* direction)
   7313 {
   7314     phymod_core_access_t core_access[1+MAX_PHYN];
   7315     int nof_phys;
   7316     int port_index;
   7317     uint32 bitmap;
   7318 
   7319     SOC_INIT_FUNC_DEFS;
   7320 
   7321     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   7322                                              &bitmap));
   7323 
   7324     if (PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   7325         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   7326                            (_SOC_MSG("phy reset is not supported")));
   7327     }
   7328 
   7329     _SOC_IF_ERR_EXIT
   7330         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   7331                                            (phymod_phy_access_t*)core_access,
   7332                                            (1+MAX_PHYN), &nof_phys));
   7333 
   7334     _SOC_IF_ERR_EXIT
   7335         (portmod_port_phychain_core_reset_get(unit, core_access, nof_phys,
   7336                        (phymod_reset_mode_t)reset_mode, 
   7337                        (phymod_reset_direction_t*)direction));
   7338 
   7339 exit:
   7340     SOC_FUNC_RETURN;
   7341 }
   7342 
   7343 /*Port remote Adv get*/
   7344 int pm4x10_port_adv_remote_get (int unit, int port, pm_info_t pm_info, 
   7345                                 int* ability_mask)
   7346 {
   7347     return (0);
   7348 }
   7349 
   7350 /*get port fec enable*/
   7351 int pm4x10_port_fec_enable_get(int unit, int port, pm_info_t pm_info, 
   7352                                uint32 phy_flags,  uint32_t* enable)
   7353 {
   7354     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7355     int   nof_phys = 0;
   7356 
   7357     SOC_INIT_FUNC_DEFS;
   7358 
   7359     _SOC_IF_ERR_EXIT
   7360         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7361                                            phy_access ,(1+MAX_PHYN),
   7362                                            &nof_phys));
   7363 
   7364     _SOC_IF_ERR_EXIT
   7365         (portmod_port_phychain_fec_enable_get(unit, port, phy_access, nof_phys, phy_flags, enable));
   7366 
   7367 exit:
   7368     SOC_FUNC_RETURN;
   7369 }
   7370 
   7371 /*set port fec enable*/
   7372 int pm4x10_port_fec_enable_set(int unit, int port, pm_info_t pm_info, 
   7373                                uint32 phy_flags,  uint32_t enable)
   7374 {
   7375     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7376     int   nof_phys = 0;
   7377 
   7378     SOC_INIT_FUNC_DEFS;
   7379 
   7380     _SOC_IF_ERR_EXIT
   7381         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7382                                            phy_access ,(1+MAX_PHYN),
   7383                                            &nof_phys));
   7384 
   7385     _SOC_IF_ERR_EXIT
   7386         (portmod_port_phychain_fec_enable_set(unit, port, phy_access, nof_phys, phy_flags, enable));
   7387 
   7388 exit:
   7389     SOC_FUNC_RETURN;
   7390 }
   7391 
   7392 /*get port auto negotiation local ability*/
   7393 int pm4x10_port_ability_advert_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags,
   7394                                  portmod_port_ability_t* ability)
   7395 {
   7396     phymod_phy_access_t              phy_access[1+MAX_PHYN];
   7397     phymod_autoneg_ability_t         an_ability;
   7398     portmod_port_ability_t port_ability;
   7399 
   7400     int     nof_phys = 0, port_index, flags;
   7401     uint32  bitmap;
   7402     int     rv;
   7403     int phy_index, xphy_id, is_legacy_phy;
   7404 
   7405     SOC_INIT_FUNC_DEFS;
   7406 
   7407     sal_memset(&port_ability, 0, sizeof(portmod_port_ability_t));
   7408     phymod_autoneg_ability_t_init(&an_ability);
   7409 
   7410     _SOC_IF_ERR_EXIT
   7411         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7412                                            phy_access ,(1+MAX_PHYN),
   7413                                            &nof_phys));
   7414     _SOC_IF_ERR_EXIT
   7415         (portmod_port_phychain_autoneg_ability_get(unit, port, phy_access, nof_phys, phy_flags,
   7416                                                    &an_ability, &port_ability));
   7417     phy_index = nof_phys -1;
   7418     if (phy_index) {
   7419         xphy_id = phy_access[phy_index].access.addr;
   7420         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   7421 
   7422         if (is_legacy_phy) {
   7423             sal_memcpy(ability, &port_ability, sizeof(portmod_port_ability_t));
   7424         }
   7425 
   7426     } else {
   7427         /*
   7428          * SGMII speed should be initialized to count but is initialized to 0
   7429          * which is treated as 10M. so for sesto mask this out.
   7430          */
   7431         if (nof_phys > 1) {
   7432 #ifdef PHYMOD_SESTO_SUPPORT
   7433             if (phy_access[nof_phys-1].type == phymodDispatchTypeSesto) {
   7434                 an_ability.sgmii_speed =  phymod_CL37_SGMII_Count;
   7435             }
   7436 #endif /* PHYMOD_SESTO_SUPPORT */
   7437         }
   7438         portmod_common_phy_to_port_ability(&an_ability, ability);
   7439     }
   7440     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   7441                                              &bitmap));
   7442 
   7443     rv = PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &ability->interface,
   7444                                    port_index);
   7445     _SOC_IF_ERR_EXIT(rv);
   7446 
   7447     _SOC_IF_ERR_EXIT(xlmac_encap_get (unit, port, &flags, &ability->encap)); 
   7448 
   7449 exit:
   7450     SOC_FUNC_RETURN;
   7451 }
   7452 
   7453 /*
   7454  * Function:
   7455  *     _pm4x10_port_to_phy_ability 
   7456  * Purpose:
   7457  *      This function will translate the portAbility request, which passed 
   7458  *      from BCM api to anAbility format required by phymod api.
   7459  *      
   7460  * Parameters:
   7461  *      portAbility         -(IN)  port an ability request from BCM Api 
   7462  *      anAbility           -(OUT) phymod an ability to phymod api.
   7463  *      port_num_lanes      -(IN)  number of lane
   7464  *      line_interface      -(IN)  line interface
   7465  *      cx4_10g             -(IN)  cx4 port
   7466  *      an_cl72             -(IN)  an cl72 configuration
   7467  *      an_fec              -(IN)  fec configuration 
   7468  *      an_hg_mode          -(IN)  hg_mode
   7469  * Returns:
   7470  *      None
   7471  */
   7472 
   7473 void _pm4x10_port_to_phy_ability (portmod_port_ability_t *portAbility, 
   7474                                   phymod_autoneg_ability_t *anAbility,
   7475                                   int port_num_lanes, 
   7476                                   int line_interface, 
   7477                                   int cx4_10g,
   7478                                   int an_cl72,
   7479                                   int an_fec,
   7480                                   int hg_mode)
   7481 {
   7482     uint32_t                  an_tech_ability   = 0;
   7483     uint32_t                  an_bam37_ability  = 0;
   7484     uint32_t                  an_bam73_ability  = 0;
   7485     _shr_port_mode_t          speed_full_duplex = portAbility->speed_full_duplex;
   7486     phymod_autoneg_ability_t_init(anAbility);
   7487 
   7488     /* 
   7489      * an_tech_ability 
   7490      */
   7491     if (port_num_lanes == 10 ||
   7492         port_num_lanes == 12 ) {
   7493         if (speed_full_duplex & SOC_PA_SPEED_100GB) { 
   7494             PHYMOD_AN_CAP_100G_CR10_SET(an_tech_ability);
   7495         }
   7496     } else if (port_num_lanes == 4) {
   7497         if (speed_full_duplex & SOC_PA_SPEED_100GB) { 
   7498         /*
   7499          * This is only possible for port with external
   7500          * phy in gearbox mode.
   7501          */
   7502             if (portAbility->medium) {
   7503                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   7504                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   7505                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   7506                     PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   7507                 } else {
   7508                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   7509                 }
   7510             } else {
   7511                 if (line_interface == SOC_PORT_IF_CR4){
   7512                     PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   7513                 } else {
   7514                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   7515                 }
   7516             }
   7517         }
   7518         if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   7519 
   7520             if (portAbility->medium) {
   7521             /*
   7522              * If the medium is defined, medium configuration will be
   7523              * used to determine which interface to advertise.  
   7524              */
   7525                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   7526                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   7527                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   7528                     PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   7529                 } else {
   7530                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   7531                 }
   7532             } else {
   7533             /* 
   7534              * If the medium is not defined, it will look at line 
   7535              * interface.  This case is for backward compatiblility
   7536              * during transition time, will remove this support later.
   7537              */
   7538                 if (line_interface ==SOC_PORT_IF_CR4) {
   7539                     PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   7540                 } else {
   7541                     PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   7542                 }
   7543             }
   7544         }
   7545 
   7546         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   7547             PHYMOD_AN_CAP_10G_KX4_SET(an_tech_ability);
   7548         }
   7549     } else if (port_num_lanes == 1) {
   7550         /* port_num_lanes == 1 */
   7551         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   7552             PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
   7553         }
   7554         if (speed_full_duplex & SOC_PA_SPEED_2500MB) {
   7555             PHYMOD_AN_CAP_2P5G_X_SET(an_tech_ability);
   7556         }
   7557         if (speed_full_duplex & SOC_PA_SPEED_5000MB) {
   7558             PHYMOD_AN_CAP_5G_KR1_SET(an_tech_ability);
   7559         }
   7560         if (speed_full_duplex & SOC_PA_SPEED_1000MB) {
   7561             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
   7562         }
   7563     }
   7564 
   7565     /* 
   7566      * an_bam73_ability 
   7567      */
   7568     if (port_num_lanes == 2) {     /* 2 lanes */
   7569         if (speed_full_duplex & SOC_PA_SPEED_20GB) {
   7570             if (portAbility->medium) {
   7571                 if (portAbility->medium & SOC_PA_MEDIUM_BACKPLANE) {
   7572                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   7573                 } else if (portAbility->medium & SOC_PA_MEDIUM_COPPER) {
   7574                     PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
   7575                 } else {
   7576                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   7577                 }
   7578             } else {
   7579                 if (line_interface ==SOC_PORT_IF_CR2) {
   7580                     PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
   7581                 } else {
   7582                     PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
   7583                 }
   7584             }
   7585         }
   7586     } 
   7587 
   7588     /* 
   7589      * an_bam37_ability 
   7590      */
   7591     if (port_num_lanes == 4) {
   7592         if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   7593             PHYMOD_BAM_CL37_CAP_40G_SET(an_bam37_ability);
   7594         }
   7595 
   7596         if (speed_full_duplex & SOC_PA_SPEED_30GB) {
   7597             PHYMOD_BAM_CL37_CAP_31P5G_SET(an_bam37_ability);
   7598         }
   7599 
   7600         if (speed_full_duplex & SOC_PA_SPEED_25GB) {
   7601             PHYMOD_BAM_CL37_CAP_25P455G_SET(an_bam37_ability);
   7602         }
   7603 
   7604         if (speed_full_duplex & SOC_PA_SPEED_21GB) {
   7605             PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_bam37_ability);
   7606         }
   7607 
   7608         if (speed_full_duplex & SOC_PA_SPEED_20GB) {
   7609             PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_bam37_ability);
   7610             PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_bam37_ability);
   7611         }
   7612 
   7613         if (speed_full_duplex & SOC_PA_SPEED_16GB) {
   7614             PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_bam37_ability);
   7615         }
   7616 
   7617         if (speed_full_duplex & SOC_PA_SPEED_15GB) {
   7618             PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_bam37_ability);
   7619         }
   7620 
   7621         if (speed_full_duplex & SOC_PA_SPEED_13GB) {
   7622             PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_bam37_ability);
   7623         }
   7624 
   7625         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   7626             if (cx4_10g) {
   7627                 PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_bam37_ability);
   7628             } else {
   7629                 PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_bam37_ability);
   7630             }
   7631         }
   7632 
   7633     } else if (port_num_lanes == 2) {     /* 2 lanes */
   7634 
   7635         if (speed_full_duplex & SOC_PA_SPEED_20GB){
   7636             if (hg_mode) {
   7637                 PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_bam37_ability);
   7638             } else {
   7639                 PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_bam37_ability);
   7640             }
   7641         }
   7642 
   7643         if (speed_full_duplex & SOC_PA_SPEED_16GB) {
   7644             PHYMOD_BAM_CL37_CAP_15P75G_R2_SET(an_bam37_ability);
   7645         }
   7646 
   7647         if (speed_full_duplex & SOC_PA_SPEED_13GB) {
   7648             PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_bam37_ability);
   7649         }
   7650 
   7651         if (speed_full_duplex & SOC_PA_SPEED_11GB) {
   7652             PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_bam37_ability);
   7653         }
   7654 
   7655         if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   7656             PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_bam37_ability);
   7657             PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_bam37_ability);
   7658         }
   7659     } else if (port_num_lanes == 1) {
   7660 
   7661         if (speed_full_duplex & SOC_PA_SPEED_2500MB) {
   7662             PHYMOD_BAM_CL37_CAP_2P5G_SET(an_bam37_ability);
   7663         }
   7664     }
   7665 
   7666     anAbility->an_cap = an_tech_ability;
   7667     anAbility->cl73bam_cap = an_bam73_ability;
   7668     anAbility->cl37bam_cap = an_bam37_ability;
   7669 
   7670     switch (portAbility->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
   7671     case SOC_PA_PAUSE_TX:
   7672         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
   7673         break;
   7674     case SOC_PA_PAUSE_RX:
   7675         /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
   7676         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
   7677         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
   7678         break;
   7679     case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
   7680         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
   7681         break;
   7682     }
   7683 
   7684     if ((speed_full_duplex & SOC_PA_SPEED_10MB) ||
   7685         (speed_full_duplex & SOC_PA_SPEED_100MB) ||
   7686         (speed_full_duplex & SOC_PA_SPEED_1000MB)) {
   7687         if (portAbility->medium) {
   7688             if (!(portAbility->medium & SOC_PA_MEDIUM_FIBER)) {
   7689 
   7690                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
   7691 
   7692                 /* also set the sgmii speed */
   7693                 if (portAbility->speed_full_duplex & SOC_PA_SPEED_1000MB) {
   7694                     anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
   7695                 } else if (portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
   7696                     anAbility->sgmii_speed = phymod_CL37_SGMII_100M;
   7697                 } else if (portAbility->speed_full_duplex & SOC_PA_SPEED_10MB) {
   7698                     anAbility->sgmii_speed = phymod_CL37_SGMII_10M;
   7699                 } else {
   7700                     anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
   7701                 }
   7702             }
   7703         } else {
   7704             if (SOC_PORT_IF_SGMII == line_interface) {
   7705 
   7706                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
   7707 
   7708                 /* also set the sgmii speed */
   7709                 if (portAbility->speed_full_duplex & SOC_PA_SPEED_1000MB) {
   7710                     anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
   7711                 } else if (portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
   7712                     anAbility->sgmii_speed = phymod_CL37_SGMII_100M;
   7713                 } else if (portAbility->speed_full_duplex & SOC_PA_SPEED_10MB) {
   7714                     anAbility->sgmii_speed = phymod_CL37_SGMII_10M;
   7715                 } else {
   7716                     anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
   7717                 }
   7718             } else {
   7719                 if (portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
   7720                     PHYMOD_AN_CAP_100M_SET(anAbility->an_cap);
   7721                 }
   7722             }
   7723         }
   7724     }
   7725 
   7726     /* next check if we need to set cl37 attribute */
   7727     if (an_cl72) {
   7728         anAbility->an_cl72 = 1;
   7729     }
   7730     if (hg_mode) {
   7731         anAbility->an_hg2 = 1;
   7732     }
   7733 
   7734     /*
   7735      * check if Cl74 fec is requested from AN BCM api.
   7736      */
   7737     if (portAbility->fec & SOC_PA_FEC_NONE) {
   7738         PHYMOD_AN_FEC_OFF_SET(anAbility->an_fec);
   7739     } else if ((an_fec == 1) || portAbility->fec & SOC_PA_FEC_CL74) {
   7740         /* The 'phy_an_fec=1' and FEC CL74 ability are all the phymod FEC CL74. */
   7741         PHYMOD_AN_FEC_CL74_SET(anAbility->an_fec);
   7742     }
   7743 
   7744 }
   7745 
   7746 int pm4x10_port_ability_advert_set(int unit, int port, pm_info_t pm_info, uint32 phy_flags,
   7747                                  portmod_port_ability_t* ability)
   7748 {
   7749     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7750     int   nof_phys = 0, port_index, rv;
   7751     uint32_t bitmap, interface_modes;
   7752     portmod_port_ability_t      port_ability;
   7753     phymod_autoneg_ability_t    an_ability;
   7754     portmod_access_get_params_t params;
   7755 
   7756     int port_num_lanes, line_interface, cx4_10g;
   7757     soc_port_if_t temp_line_intf;
   7758     int an_cl72, an_fec, hg_mode;
   7759     int total_num_lanes = 0;
   7760     int line_side;
   7761     SOC_INIT_FUNC_DEFS;
   7762 
   7763     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, 
   7764                                              &bitmap));
   7765 
   7766     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   7767     params.lane = -1;
   7768     params.phyn = 0;
   7769     params.sys_side = PORTMOD_SIDE_LINE;
   7770 
   7771     _SOC_IF_ERR_EXIT
   7772         (pm4x10_port_ability_local_get(unit, port, pm_info, phy_flags, &port_ability));
   7773 
   7774     /* Make sure to advertise only abilities supported by the port */
   7775     port_ability.pause             &= ability->pause;
   7776     port_ability.interface         &= ability->interface;
   7777     port_ability.medium            &= ability->medium;
   7778     port_ability.eee               &= ability->eee;
   7779     port_ability.loopback          &= ability->loopback;
   7780     port_ability.flags             &= ability->flags;
   7781     port_ability.speed_half_duplex &= ability->speed_half_duplex;
   7782     port_ability.speed_full_duplex &= ability->speed_full_duplex;
   7783     port_ability.fec               &= ability->fec;
   7784     port_ability.channel           &= ability->channel;
   7785 
   7786     /* coverity[Out-of-bounds access:FALSE] */
   7787     SHR_BITCOUNT_RANGE(&bitmap, port_num_lanes, 0, PM4X10_LANES_PER_CORE);
   7788     rv = PM4x10_INTERFACE_TYPE_GET(unit, pm_info, &line_interface, port_index);
   7789     _SOC_IF_ERR_EXIT(rv);
   7790     rv = PM4x10_CX4_10G_GET(unit, pm_info, &cx4_10g, port_index);
   7791     _SOC_IF_ERR_EXIT(rv);
   7792     rv = PM4x10_AN_CL72_GET(unit, pm_info, &an_cl72, port_index);
   7793     _SOC_IF_ERR_EXIT(rv);
   7794     rv = PM4x10_AN_FEC_GET(unit, pm_info, &an_fec, port_index);
   7795     _SOC_IF_ERR_EXIT(rv);
   7796     rv = PM4x10_INTERFACE_MODES_GET(unit, pm_info, &interface_modes,
   7797                                     port_index);
   7798     _SOC_IF_ERR_EXIT(rv);
   7799     hg_mode = (interface_modes & PHYMOD_INTF_MODES_HIGIG)? 1: 0;
   7800 
   7801 
   7802     _SOC_IF_ERR_EXIT
   7803         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7804                                            phy_access ,(1+MAX_PHYN),
   7805                                            &nof_phys));
   7806 
   7807     /* 
   7808      * if line interface is CAUI -- check it is 4x25 or 10x10
   7809      * change the line interface for this purpose.
   7810      *
   7811      * Default interface for 100G is CR10. However if line interface is Falcon
   7812      * the interface should be CR4 (not CR10). Fix the line interface here..,
   7813      */ 
   7814     if (nof_phys > 1) {
   7815       portmod_port_line_interface_map_for_xphy(unit, &(phy_access[nof_phys-1]), port, line_interface, &temp_line_intf);
   7816       line_interface = temp_line_intf;
   7817     }
   7818 
   7819     /*
   7820      * Get the total number of line side lanes, if it is triple core mode (PM12x10).
   7821      * and update the port_num_lanes with the new count.
   7822      */
   7823 
   7824     if (interface_modes & PHYMOD_INTF_MODES_TRIPLE_CORE) {
   7825         line_side = TRUE ;
   7826         _SOC_IF_ERR_EXIT
   7827             (portmod_port_lane_count_get(unit, port, line_side,
   7828                                         &total_num_lanes));
   7829         port_num_lanes = total_num_lanes;
   7830     }
   7831 
   7832     _pm4x10_port_to_phy_ability(&port_ability, &an_ability,
   7833                                        port_num_lanes, line_interface, cx4_10g,
   7834                                        an_cl72, an_fec, hg_mode);
   7835 
   7836     rv = PM4x10_AN_MASTER_LANE_GET(unit, pm_info, &an_ability.an_master_lane,
   7837                                    port_index);
   7838     _SOC_IF_ERR_EXIT(rv);
   7839 
   7840     _SOC_IF_ERR_EXIT
   7841         (portmod_port_phychain_autoneg_ability_set(unit, port, phy_access, nof_phys, phy_flags, &an_ability, &port_ability));
   7842 
   7843     LOG_VERBOSE(BSL_LS_BCM_PORT,
   7844                 (BSL_META_U(unit,
   7845                      "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x orig(HD=0x%08x, FD=0x%08x) \n"
   7846                      "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
   7847                      port_ability.speed_half_duplex,
   7848                      port_ability.speed_full_duplex,
   7849                      port_ability.pause,
   7850                      ability->speed_half_duplex,
   7851                      ability->speed_full_duplex,
   7852                      port_ability.interface,
   7853                      port_ability.medium, port_ability.loopback,
   7854                      port_ability.flags));
   7855 exit:
   7856     SOC_FUNC_RETURN;
   7857 }
   7858 
   7859 /*Port ability remote Adv get*/
   7860 int pm4x10_port_ability_remote_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags,
   7861                                        portmod_port_ability_t* ability)
   7862 {
   7863     phymod_phy_access_t phy_access[1+MAX_PHYN];
   7864     int                         nof_phys;
   7865     phymod_autoneg_ability_t    an_ability;
   7866     int phy_index, xphy_id, is_legacy_phy = 0;
   7867 
   7868     SOC_INIT_FUNC_DEFS;
   7869 
   7870     phymod_autoneg_ability_t_init(&an_ability);
   7871 
   7872     _SOC_IF_ERR_EXIT
   7873         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   7874                                            phy_access ,(1+MAX_PHYN),
   7875                                            &nof_phys));
   7876 
   7877     phy_index = nof_phys -1;
   7878     if (phy_index) {
   7879         xphy_id = phy_access[phy_index].access.addr;
   7880         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy));
   7881     }
   7882     _SOC_IF_ERR_EXIT
   7883         (portmod_port_phychain_autoneg_remote_ability_get(unit, port, phy_access, nof_phys, phy_flags, &an_ability, ability));
   7884     if (!is_legacy_phy) {
   7885     portmod_common_phy_to_port_ability(&an_ability, ability);
   7886     }
   7887 
   7888 exit:
   7889     SOC_FUNC_RETURN;
   7890 }
   7891 
   7892 int _xlport_rx_control_set(int unit, int port, int value)
   7893 {
   7894     int rv = SOC_E_UNAVAIL;
   7895     uint32 rval32 = 0;
   7896 
   7897     if (SOC_REG_IS_VALID(unit,XLPORT_MAC_RSV_MASKr)) {
   7898         rv = READ_XLPORT_MAC_RSV_MASKr(unit, port, &rval32);
   7899         if (SOC_SUCCESS(rv)) {
   7900             /* XLPORT_MAC_RSV_MASK: Bit 11 Control Frame recieved
   7901              * Enable  Control Frame : Set 0. Packet go through
   7902              * Disable Control Frame : Set 1. Packet is purged.
   7903              */
   7904             if(value) {
   7905                 rval32 &= ~(1 << 11);
   7906             } else {
   7907                 rval32 |= (1 << 11);
   7908             }
   7909             rv = WRITE_XLPORT_MAC_RSV_MASKr(unit, port, rval32);
   7910         }
   7911     }
   7912 
   7913     return rv;
   7914 }
   7915 
   7916 int pm4x10_port_rx_control_set (int unit, int port, pm_info_t pm_info,
   7917                                  const portmod_rx_control_t* rx_ctrl)
   7918 {
   7919     int phy_acc;
   7920     uint32 reg_val;
   7921 
   7922     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7923     SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_RSV_MASKr(unit, phy_acc, &reg_val));
   7924 
   7925     if (rx_ctrl->flags & PORTMOD_MAC_PASS_CONTROL_FRAME) {
   7926         if (rx_ctrl->pass_control_frames) {
   7927             reg_val &= ~(1 << 11);
   7928         } else{
   7929             reg_val |= (1 << 11);
   7930         }
   7931     }
   7932 
   7933     if (rx_ctrl->flags & PORTMOD_MAC_PASS_PFC_FRAME) {
   7934         if (rx_ctrl->pass_pfc_frames) {
   7935             reg_val &= ~(1 << 18);
   7936         } else{
   7937             reg_val |= (1 << 18);
   7938         }
   7939     }
   7940 
   7941     if (rx_ctrl->flags & PORTMOD_MAC_PASS_PAUSE_FRAME) {
   7942         if (rx_ctrl->pass_pause_frames) {
   7943             reg_val &= ~(1 << 12);
   7944         } else{
   7945             reg_val |= (1 << 12);
   7946         }
   7947     }
   7948 
   7949     SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_RSV_MASKr(unit, phy_acc, reg_val));
   7950 
   7951     return (SOC_E_NONE);
   7952 }
   7953 
   7954 int pm4x10_port_rx_control_get (int unit, int port, pm_info_t pm_info,
   7955                                          portmod_rx_control_t* rx_ctrl)
   7956 {
   7957     int phy_acc;
   7958     uint32 reg_val;
   7959 
   7960     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   7961     SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_RSV_MASKr(unit, phy_acc, &reg_val));
   7962     rx_ctrl->pass_control_frames = ((reg_val & 0x800) >> 11) ? 0 : 1;
   7963     rx_ctrl->pass_pfc_frames = ((reg_val & 0x40000) >> 18) ? 0 : 1;
   7964     rx_ctrl->pass_pause_frames = ((reg_val & 0x1000) >> 12) ? 0 : 1;
   7965 
   7966     return (SOC_E_NONE);
   7967 }
   7968 
   7969 int pm4x10_port_tx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   7970 {
   7971     return (xlmac_tx_mac_sa_set(unit, port, mac_addr));
   7972 }
   7973 
   7974 
   7975 int pm4x10_port_tx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   7976 {
   7977     return (xlmac_tx_mac_sa_get(unit, port, mac_addr));
   7978 }
   7979 
   7980 int pm4x10_port_rx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   7981 {
   7982     return (xlmac_rx_mac_sa_set(unit, port, mac_addr));
   7983 }
   7984 
   7985 
   7986 int pm4x10_port_rx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr)
   7987 {
   7988     return (xlmac_rx_mac_sa_get(unit, port, mac_addr));
   7989 }
   7990 
   7991 int pm4x10_port_tx_average_ipg_set (int unit, int port, 
   7992                                     pm_info_t pm_info, int value)
   7993 {
   7994     return (xlmac_tx_average_ipg_set(unit, port, value));
   7995 }
   7996 
   7997 
   7998 int pm4x10_port_tx_average_ipg_get (int unit, int port, 
   7999                                     pm_info_t pm_info, int* value)
   8000 {
   8001     return (xlmac_tx_average_ipg_get(unit, port, value));
   8002 }
   8003 
   8004 int pm4x10_port_update (int unit, int port, pm_info_t pm_info,
   8005                         const portmod_port_update_control_t* update_control)
   8006 {
   8007     int link, flags = 0;
   8008     int duplex = 0, tx_pause = 0, rx_pause = 0;
   8009     phymod_autoneg_status_t autoneg;
   8010     portmod_pause_control_t pause_control;
   8011     portmod_port_ability_t local_advert, remote_advert;
   8012     portmod_port_interface_config_t interface_config;
   8013     int port_index, ref_clock, max_speed;
   8014     uint32_t                    bitmap;
   8015     phymod_phy_inf_config_t     phy_interface_config;
   8016     soc_port_if_t   interface = SOC_PORT_IF_NULL;
   8017     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8018     int nof_phys;
   8019     int is_xlmac_en = 0;
   8020     portmod_port_ts_adjust_t ts_adjust;
   8021 
   8022     int sys_start_lane = -1;
   8023     int sys_end_lane = -1;
   8024     int line_start_lane = -1;
   8025     int line_end_lane=-1;
   8026     uint32 int_lane_mask=0xf;
   8027     uint32_t serdes_link_status=0;
   8028     phymod_phy_rx_lane_control_t rx_control;
   8029     uint32 port_dynamic_state = 0;
   8030     int mac_ts_enable;
   8031     SOC_INIT_FUNC_DEFS;
   8032 
   8033     _SOC_IF_ERR_EXIT(phymod_autoneg_status_t_init(&autoneg));
   8034     _SOC_IF_ERR_EXIT(portmod_pause_control_t_init(unit, &pause_control));
   8035     sal_memset(&local_advert, 0, sizeof(portmod_port_ability_t));
   8036     sal_memset(&remote_advert, 0, sizeof(portmod_port_ability_t));
   8037     sal_memset(&ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   8038 
   8039     _SOC_IF_ERR_EXIT
   8040         (portmod_port_chain_phy_access_get(unit, port, pm_info,
   8041                                            phy_access ,(1+MAX_PHYN),
   8042                                            &nof_phys));
   8043 
   8044     if(update_control->link_status == -1) {
   8045         _SOC_IF_ERR_EXIT(pm4x10_port_link_get(unit, port, pm_info,PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &link)); 
   8046     } else {
   8047         link = update_control->link_status;
   8048     }
   8049 
   8050     _SOC_IF_ERR_EXIT(pm4x10_port_autoneg_status_get(unit, port, pm_info, &autoneg));
   8051 
   8052     /*
   8053      * Update the interface type stored in the SW database when the port is in the AN mode
   8054      * and link is up. The update has to be done before any possible early return in this
   8055      * function or portmod_port_interface_config_get() will get outdated interface type
   8056      * causing "BCM.0> ps" to show outdated interface types in the AN mode.
   8057      */
   8058     if (link && autoneg.enabled && autoneg.locked) {
   8059         /* update interface*/
   8060         _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init(&phy_interface_config));
   8061         _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   8062         _SOC_IF_ERR_EXIT(PM4x10_MAX_SPEED_GET(unit, pm_info, &max_speed, port_index));
   8063 
   8064         ref_clock = PM_4x10_INFO(pm_info)->ref_clk;
   8065         phy_interface_config.data_rate =  max_speed;
   8066         phy_interface_config.ref_clock =  ref_clock;
   8067         _SOC_IF_ERR_EXIT
   8068             (portmod_port_phychain_interface_config_get(unit, port, phy_access, nof_phys,
   8069                                                         0, ref_clock, &phy_interface_config,
   8070                                                         PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   8071         _SOC_IF_ERR_EXIT
   8072             (portmod_intf_from_phymod_intf(unit, phy_interface_config.interface_type, &interface));
   8073         _SOC_IF_ERR_EXIT
   8074             (PM4x10_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   8075         _SOC_IF_ERR_EXIT
   8076             (PM4x10_OUTMOST_PHY_INTERFACE_TYPE_SET(unit, pm_info, interface, port_index));
   8077     }
   8078 
   8079 /* Following code applies to the phy 54290 */
   8080     if (PORTMOD_PORT_UPDATE_F_UPDATE_SERDES_LINK_GET(update_control)){
   8081         _SOC_IF_ERR_EXIT(_pm4x10_port_tricore_lane_info_get(unit, port, pm_info,
   8082                                               &sys_start_lane, &sys_end_lane,
   8083                                               &line_start_lane, &line_end_lane,
   8084                                               &int_lane_mask, NULL));
   8085         /* only look at the lanes that are used. */
   8086         phy_access[0].access.lane_mask &= int_lane_mask;
   8087 
   8088         if (nof_phys > 1){
   8089             _SOC_IF_ERR_EXIT
   8090                 (phymod_phy_link_status_get(&phy_access[0],&serdes_link_status));
   8091 
   8092             if(link) {
   8093                 _SOC_IF_ERR_EXIT
   8094                     (phymod_phy_rx_lane_control_get(&phy_access[0],&rx_control));
   8095                 if(rx_control == phymodRxSquelchOn){
   8096                     phymod_phy_rx_lane_control_set(&phy_access[0],
   8097                                                    phymodRxSquelchOff);
   8098                 }
   8099             } else {
   8100                 /* if external phy and link is down, internal serdes link is up,
   8101                    force internal SerDes link to be down. */
   8102                 if(serdes_link_status){
   8103                     phymod_phy_rx_lane_control_set(&phy_access[0],
   8104                                                    phymodRxSquelchOn);
   8105                     phymod_phy_rx_lane_control_set(&phy_access[0],
   8106                                                    phymodRxSquelchOff);
   8107                 }
   8108             }
   8109         }
   8110 
   8111         /*
   8112          * PORTMOD_PORT_UPDATE_F_UPDATE_SERDES_LINK is set for XGS devices. Since XGS devices
   8113          * already update their MAC registers elsewhere, there is an early return below to
   8114          * avoid redundant works.
   8115          */
   8116         return (SOC_E_NONE);
   8117     }
   8118 
   8119     if(!link) {
   8120         /* PHY is down.  Disable the MAC. */
   8121         if (PORTMOD_PORT_UPDATE_F_DISABLE_MAC_GET(update_control)) {
   8122             _SOC_IF_ERR_EXIT(xlmac_enable_set(unit, port, 0, 0));
   8123         }
   8124 
   8125         /* TBD - do we need phymod_link_down_event ? */
   8126     } else {
   8127         _SOC_IF_ERR_EXIT(xlmac_enable_get(unit, port, 0, &is_xlmac_en));
   8128         if (is_xlmac_en == 0) {
   8129             _SOC_IF_ERR_EXIT(xlmac_enable_set(unit, port, 0, 1));
   8130             if(PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   8131                 _SOC_IF_ERR_EXIT(pm4x10_port_soft_reset(unit, port, pm_info, 0));
   8132             }
   8133         }
   8134 
   8135         /* TBD - do we need phymod_link_up_event ? */
   8136 
   8137         if(autoneg.enabled && autoneg.locked) {
   8138             /* update MAC */
   8139             _SOC_IF_ERR_EXIT(pm4x10_port_interface_config_get(unit, port, pm_info, &interface_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   8140             flags = XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS;
   8141             _SOC_IF_ERR_EXIT(xlmac_speed_set(unit, port, flags, interface_config.speed));
   8142 
   8143             if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
   8144                 _SOC_IF_ERR_EXIT(pm4x10_port_mac_timestamp_enable_get(unit, port, pm_info,
   8145                                                                   &mac_ts_enable));
   8146             } else {
   8147                 mac_ts_enable = 1;
   8148             }
   8149             if (mac_ts_enable) {
   8150                 /*Set MAC Timestamp Delay*/
   8151                 _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   8152                 _SOC_IF_ERR_EXIT(PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info, &port_dynamic_state, port_index));
   8153 
   8154                 if (!PORTMOD_PORT_IS_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED(port_dynamic_state)) {
   8155                     _SOC_IF_ERR_EXIT
   8156                         (_pm4x10_port_timestamp_adjust_wb_get(unit,
   8157                                                               port,
   8158                                                               pm_info,
   8159                                                               interface_config.speed,
   8160                                                               &ts_adjust));
   8161                     _SOC_IF_ERR_EXIT
   8162                         (xlmac_timestamp_delay_set(unit,
   8163                                                    port,
   8164                                                    ts_adjust,
   8165                                                    interface_config.speed));
   8166                 }
   8167                 _SOC_IF_ERR_EXIT(xlmac_timestamp_byte_adjust_set(unit, port, 0, interface_config.speed));
   8168             }
   8169 
   8170             if(PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   8171                 _SOC_IF_ERR_EXIT(pm4x10_port_soft_reset(unit, port, pm_info, 0));
   8172             }
   8173             /* update pause in MAC on the base of local and remote pause ability*/
   8174             _SOC_IF_ERR_EXIT(pm4x10_port_duplex_get(unit, port, pm_info, &duplex));
   8175             _SOC_IF_ERR_EXIT(pm4x10_port_ability_advert_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &local_advert));
   8176             _SOC_IF_ERR_EXIT(pm4x10_port_ability_remote_get(unit, port, pm_info, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &remote_advert));
   8177             /* IEEE 802.3 Flow Control Resolution.
   8178                    * Please see $SDK/doc/pause-resolution.txt for more information. */
   8179             if (duplex) {
   8180                 tx_pause = \
   8181                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   8182                     (local_advert.pause & SOC_PA_PAUSE_RX)) || \
   8183                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   8184                     !(remote_advert.pause & SOC_PA_PAUSE_TX) && \
   8185                     (local_advert.pause & SOC_PA_PAUSE_TX)); 
   8186                 rx_pause = \
   8187                     ((remote_advert.pause & SOC_PA_PAUSE_RX) && \
   8188                     (local_advert.pause & SOC_PA_PAUSE_RX)) || \
   8189                     ((local_advert.pause & SOC_PA_PAUSE_RX) && \
   8190                     (remote_advert.pause & SOC_PA_PAUSE_TX) && \
   8191                     !(local_advert.pause & SOC_PA_PAUSE_TX));
   8192             }
   8193             else {
   8194                 rx_pause = tx_pause = 0;
   8195             }
   8196             _SOC_IF_ERR_EXIT(pm4x10_port_pause_control_get(unit, port, pm_info, &pause_control));
   8197             if ((pause_control.rx_enable != rx_pause) || (pause_control.tx_enable != tx_pause)) {
   8198                 pause_control.rx_enable = rx_pause;
   8199                 pause_control.tx_enable = tx_pause;
   8200                 _SOC_IF_ERR_EXIT(pm4x10_port_pause_control_set(unit, port, pm_info, &pause_control));
   8201             }
   8202         }
   8203 
   8204         _SOC_IF_ERR_EXIT(PM_DRIVER(pm_info)->f_portmod_port_lag_failover_status_toggle(unit, port, pm_info));
   8205     }
   8206 
   8207 exit:
   8208     SOC_FUNC_RETURN;
   8209 }
   8210 
   8211 int pm4x10_port_drv_name_get (int unit, int port, pm_info_t pm_info, 
   8212                               char* buf, int len)
   8213 {
   8214     strncpy(buf, "PM4X10 Driver", len);
   8215     return (SOC_E_NONE);
   8216 }
   8217 
   8218 int pm4x10_port_local_fault_status_clear(int unit, int port, pm_info_t pm_info)
   8219 {
   8220     int lcl_fault, rmt_fault;
   8221 
   8222     SOC_IF_ERROR_RETURN (pm4x10_port_clear_rx_lss_status_get (unit, port, pm_info, &lcl_fault, &rmt_fault));
   8223     if (lcl_fault) {
   8224         SOC_IF_ERROR_RETURN (pm4x10_port_clear_rx_lss_status_set(unit, port, pm_info, 0, rmt_fault)); 
   8225     }
   8226     return (pm4x10_port_clear_rx_lss_status_set (unit, port, pm_info, 1, rmt_fault));
   8227 }
   8228 
   8229 int pm4x10_port_remote_fault_status_clear(int unit, int port, pm_info_t pm_info)
   8230 {
   8231     int lcl_fault, rmt_fault;
   8232 
   8233     SOC_IF_ERROR_RETURN (pm4x10_port_clear_rx_lss_status_get (unit, port, pm_info, &lcl_fault, &rmt_fault));
   8234     if (rmt_fault) {
   8235         SOC_IF_ERROR_RETURN (pm4x10_port_clear_rx_lss_status_set(unit, port, pm_info, lcl_fault, 0)); 
   8236     }
   8237     return (pm4x10_port_clear_rx_lss_status_set (unit, port, pm_info, lcl_fault, 1));
   8238 }
   8239 
   8240 
   8241 int pm4x10_port_clear_rx_lss_status_set (int unit, soc_port_t port, 
   8242                            pm_info_t pm_info, int lcl_fault, int rmt_fault)
   8243 {
   8244     return (xlmac_clear_rx_lss_status_set (unit, port, lcl_fault, rmt_fault));
   8245 }
   8246 
   8247 int pm4x10_port_clear_rx_lss_status_get (int unit, soc_port_t port, 
   8248                            pm_info_t pm_info, int *lcl_fault, int *rmt_fault)
   8249 {
   8250     return (xlmac_clear_rx_lss_status_get (unit, port, lcl_fault, rmt_fault));
   8251 }
   8252 
   8253 int pm4x10_port_lag_failover_status_toggle (int unit, soc_port_t port, pm_info_t pm_info)
   8254 {
   8255     int phy_acc;
   8256     uint32_t rval;
   8257     int link = 0;
   8258     soc_timeout_t to;
   8259 
   8260     SOC_INIT_FUNC_DEFS;
   8261 
   8262     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8263 
   8264     /* Link status to IPIPE is updated by H/W and driven based on both the
   8265      * rising edge of XLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and
   8266      * actual link up status from Serdes.
   8267      * In some loopback scenarios it may take longer time to see Serdes link up status.
   8268      */
   8269     soc_timeout_init(&to, 10000, 0);
   8270 
   8271     do {
   8272         _SOC_IF_ERR_EXIT(pm4x10_port_mac_link_get(unit, port, pm_info, &link));
   8273         if (link) {
   8274             break;
   8275         }
   8276     } while(!soc_timeout_check(&to));
   8277 
   8278     /* Toggle link_status_up bit to notify IPIPE on link up */
   8279     _SOC_IF_ERR_EXIT(READ_XLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, &rval));
   8280     soc_reg_field_set(unit, XLPORT_LAG_FAILOVER_CONFIGr, &rval, LINK_STATUS_UPf, 1);
   8281     _SOC_IF_ERR_EXIT(WRITE_XLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, rval));
   8282     soc_reg_field_set(unit, XLPORT_LAG_FAILOVER_CONFIGr, &rval, LINK_STATUS_UPf, 0);
   8283     _SOC_IF_ERR_EXIT(WRITE_XLPORT_LAG_FAILOVER_CONFIGr(unit, phy_acc, rval));
   8284 
   8285 exit:
   8286     SOC_FUNC_RETURN;
   8287 }
   8288 
   8289 int pm4x10_port_lag_failover_loopback_set (int unit, soc_port_t port, 
   8290                                         pm_info_t pm_info, int value)
   8291 {
   8292     return (xlmac_lag_failover_loopback_set(unit, port, value));
   8293 }
   8294 
   8295 int pm4x10_port_lag_failover_loopback_get (int unit, soc_port_t port, 
   8296                                         pm_info_t pm_info, int *value)
   8297 {
   8298     return(xlmac_lag_failover_loopback_get(unit, port, value));
   8299 }
   8300 
   8301 int pm4x10_port_mode_set(int unit, soc_port_t port,
   8302                      pm_info_t pm_info, const portmod_port_mode_info_t *mode)
   8303 {
   8304     int phy_acc;
   8305     SOC_INIT_FUNC_DEFS;
   8306 
   8307     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8308 
   8309     _SOC_IF_ERR_EXIT(_xlport_mode_set(unit, phy_acc, mode->cur_mode));
   8310 
   8311 exit:
   8312     SOC_FUNC_RETURN;
   8313 }
   8314 
   8315 int pm4x10_port_mode_get(int unit, soc_port_t port,
   8316                      pm_info_t pm_info, portmod_port_mode_info_t *mode)
   8317 {
   8318     int port_index, rv, phy_acc;
   8319     uint32 bitmap;
   8320 
   8321     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8322 
   8323     rv = _pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   8324     if (rv) return (rv);
   8325 
   8326     return(_xlport_mode_get(unit, phy_acc, port_index, &mode->cur_mode, &mode->lanes));
   8327 }
   8328 
   8329 int
   8330 pm4x10_port_trunk_hwfailover_config_set(int unit, soc_port_t port, pm_info_t pm_info, int hw_count)
   8331 {
   8332     int    old_failover_en=0, new_failover_en = 0;
   8333     int    old_link_status_sel=0, new_link_status_sel=0;
   8334     int    old_reset_flow_control=0, new_reset_flow_control = 0;
   8335     int    lag_failover_lpbk;
   8336 
   8337     if (hw_count) {
   8338         new_failover_en        = 1;
   8339         new_link_status_sel    = 1;
   8340         new_reset_flow_control = 1;
   8341     }
   8342 
   8343     SOC_IF_ERROR_RETURN (xlmac_lag_failover_loopback_get(unit, port, &lag_failover_lpbk));
   8344     if (lag_failover_lpbk) return (SOC_E_NONE);
   8345 
   8346 
   8347     SOC_IF_ERROR_RETURN (xlmac_lag_failover_en_get(unit, port, &old_failover_en));
   8348     SOC_IF_ERROR_RETURN (xlmac_sw_link_status_select_get (unit, port, &old_link_status_sel));
   8349 
   8350     if (old_failover_en     != new_failover_en ||
   8351         old_link_status_sel != new_link_status_sel) {
   8352 
   8353         SOC_IF_ERROR_RETURN (xlmac_sw_link_status_select_set (unit, port, new_link_status_sel));
   8354         SOC_IF_ERROR_RETURN (xlmac_lag_failover_en_set(unit, port, new_failover_en));
   8355     }
   8356 
   8357     SOC_IF_ERROR_RETURN (xlmac_reset_fc_timers_on_link_dn_get(unit,
   8358                                        port, &old_reset_flow_control));
   8359     if (old_reset_flow_control != new_reset_flow_control) {
   8360         SOC_IF_ERROR_RETURN (xlmac_reset_fc_timers_on_link_dn_set(unit, 
   8361                                         port, new_reset_flow_control));
   8362     }
   8363 
   8364     return 0;
   8365 }
   8366 
   8367 int
   8368 pm4x10_port_trunk_hwfailover_config_get(int unit, soc_port_t port, pm_info_t pm_info, 
   8369                                         int *enable)
   8370 {
   8371     return (xlmac_lag_failover_en_get(unit, port, enable));
   8372 }
   8373 
   8374 
   8375 int
   8376 pm4x10_port_trunk_hwfailover_status_get(int unit, soc_port_t port, pm_info_t pm_info, 
   8377                                         int *loopback)
   8378 {
   8379     return (xlmac_lag_failover_loopback_get(unit, port, loopback));
   8380 }
   8381 
   8382 int pm4x10_port_diag_ctrl(int unit, soc_port_t port, pm_info_t pm_info,
   8383                       uint32 inst, int op_type, int op_cmd, const void *arg) 
   8384 {
   8385     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8386     phymod_tx_t          ln_txparam[PM4X10_LANES_PER_CORE];
   8387     int nof_phys, i;
   8388     uint32 lane_map;
   8389     portmod_access_get_params_t params;
   8390 
   8391     SOC_IF_ERROR_RETURN(portmod_access_get_params_t_init(unit, &params));
   8392     for (i = 0; i < PM4X10_LANES_PER_CORE; i++) {
   8393         SOC_IF_ERROR_RETURN(phymod_tx_t_init(&ln_txparam[i]));
   8394     }
   8395 
   8396     if( PHY_DIAG_INST_DEV(inst) == PHY_DIAG_DEV_INT ) {
   8397         params.phyn = 0 ;
   8398     } else { 
   8399         /* most external  PHY_DIAG_DEV_DFLT and PHY_DIAG_DEV_EXT */  
   8400         params.phyn = -1 ;  
   8401     }
   8402 
   8403     if(PHY_DIAG_INST_INTF(inst) == PHY_DIAG_INTF_SYS ){
   8404         params.sys_side = PORTMOD_SIDE_SYSTEM;
   8405     } else { /* line side is default */
   8406         params.sys_side = PORTMOD_SIDE_LINE;
   8407     }
   8408 
   8409     params.apply_lane_mask = 1;
   8410 
   8411     SOC_IF_ERROR_RETURN(pm4x10_port_phy_lane_access_get(unit, port, pm_info,
   8412                                     &params, 1, phy_access, &nof_phys, NULL));
   8413 
   8414     lane_map = phy_access[0].access.lane_mask;
   8415 
   8416     switch(op_cmd) {
   8417         case PHY_DIAG_CTRL_DSC:
   8418             LOG_INFO(BSL_LS_SOC_PHY,
   8419                      (BSL_META_U(unit,
   8420                                  "pm4x10_port_diag_ctrl: "
   8421                                  "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"),
   8422                       unit, port, PHY_DIAG_CTRL_DSC));
   8423 
   8424             SOC_IF_ERROR_RETURN
   8425                 (portmod_port_phychain_pmd_info_dump(unit, phy_access, nof_phys,
   8426                                                  (void*)arg));
   8427 
   8428             break;
   8429 
   8430         case PHY_DIAG_CTRL_PCS:
   8431             LOG_INFO(BSL_LS_SOC_PHY,
   8432                      (BSL_META_U(unit,
   8433                                  "pm4x10_port_diag_ctrl: "
   8434                                  "u=%d p=%d PHY_DIAG_CTRL_PCS 0x%x\n"),
   8435                       unit, port, PHY_DIAG_CTRL_PCS));
   8436 
   8437             SOC_IF_ERROR_RETURN
   8438                 (portmod_port_phychain_pcs_info_dump(unit, phy_access, nof_phys,
   8439                                                     (void*)arg));
   8440             break;
   8441 
   8442         case PHY_DIAG_CTRL_LINKMON_MODE:
   8443             LOG_INFO(BSL_LS_SOC_PHY,
   8444                      (BSL_META_U(unit,
   8445                                  "pm4x10_port_diag_ctrl: "
   8446                                  "u=%d p=%d PHY_DIAG_CTRL_LINKMON_MODE  0x%x\n"),
   8447                       unit, port, PHY_DIAG_CTRL_LINKMON_MODE));
   8448 
   8449             if(phy_access[0].access.lane_mask){
   8450                 SOC_IF_ERROR_RETURN
   8451                     (portmod_pm_phy_link_mon_enable_set(phy_access, nof_phys, PTR_TO_INT(arg)));
   8452             }
   8453             break;
   8454 
   8455         case PHY_DIAG_CTRL_LINKMON_STATUS:
   8456             LOG_INFO(BSL_LS_SOC_PHY,
   8457                      (BSL_META_U(unit,
   8458                                  "pm4x10_port_diag_ctrl: "
   8459                                  "u=%d p=%d PHY_DIAG_CTRL_LINKMON_STATUS 0x%x\n"),
   8460                       unit, port, PHY_DIAG_CTRL_LINKMON_STATUS));
   8461 
   8462             if(phy_access[0].access.lane_mask){
   8463                 SOC_IF_ERROR_RETURN
   8464                     (portmod_pm_phy_link_mon_status_get(phy_access, nof_phys));
   8465             }
   8466             break;
   8467 
   8468 
   8469         default:
   8470             if(op_type == PHY_DIAG_CTRL_SET) {
   8471                 LOG_INFO(BSL_LS_SOC_PHY,
   8472                          (BSL_META_U(unit,
   8473                                      "pm4x10_port_diag_ctrl: "
   8474                                      "u=%d p=%d PHY_DIAG_CTRL_SET 0x%x\n"),
   8475                           unit, port, PHY_DIAG_CTRL_SET));
   8476                 if (!SAL_BOOT_SIMULATION) {
   8477                     if( !(phy_access->access.lane_mask == 0)){
   8478                         SOC_IF_ERROR_RETURN(portmod_pm_phy_control_set(phy_access, nof_phys, op_cmd, ln_txparam, lane_map, PTR_TO_INT(arg)));
   8479                     }
   8480                 }
   8481             } else if(op_type == PHY_DIAG_CTRL_GET) {
   8482                 LOG_INFO(BSL_LS_SOC_PHY,
   8483                          (BSL_META_U(unit,
   8484                                      "pm4x10_port_diag_ctrl: "
   8485                                      "u=%d p=%d PHY_DIAG_CTRL_GET 0x%x\n"),
   8486                           unit, port, PHY_DIAG_CTRL_GET));
   8487                 if (!SAL_BOOT_SIMULATION) {
   8488                     if( !(phy_access->access.lane_mask == 0)){
   8489                         SOC_IF_ERROR_RETURN(portmod_pm_phy_control_get(phy_access,nof_phys,op_cmd, ln_txparam, lane_map, (uint32 *)arg));
   8490                     } else {
   8491                         *(uint32 *)arg = 0;
   8492                     }
   8493                 }
   8494             } else {
   8495                 return (SOC_E_UNAVAIL);
   8496             }
   8497             break ;
   8498     }
   8499     return (SOC_E_NONE);
   8500 }
   8501 
   8502 int
   8503 pm4x10_port_ref_clk_get(int unit, soc_port_t port, pm_info_t pm_info, int *ref_clk)
   8504 {
   8505     *ref_clk = pm_info->pm_data.pm4x10_db->ref_clk;
   8506 
   8507     return (SOC_E_NONE);
   8508 }
   8509 
   8510 int pm4x10_port_lag_remove_failover_lpbk_get(int unit, int port, pm_info_t pm_info, int *val)
   8511 {
   8512     return (xlmac_lag_remove_failover_lpbk_get(unit, port, val));
   8513 }
   8514 
   8515 int pm4x10_port_lag_remove_failover_lpbk_set(int unit, int port, pm_info_t pm_info, int val)
   8516 {
   8517     return (xlmac_lag_remove_failover_lpbk_set(unit, port, val));
   8518 }
   8519 
   8520 int pm4x10_port_lag_failover_disable(int unit, int port, pm_info_t pm_info)
   8521 {
   8522     return (xlmac_lag_failover_disable(unit, port));
   8523 }
   8524 
   8525 int pm4x10_port_mac_ctrl_set(int unit, int port, 
   8526                    pm_info_t pm_info, uint64 ctrl)
   8527 {
   8528     return(xlmac_mac_ctrl_set(unit, port, ctrl));
   8529 }
   8530 
   8531 int pm4x10_port_drain_cell_get(int unit, int port, 
   8532            pm_info_t pm_info, portmod_drain_cells_t *drain_cells)
   8533 {
   8534     return (xlmac_drain_cell_get(unit, port, drain_cells));
   8535 }
   8536 
   8537 int pm4x10_port_drain_cell_stop (int unit, int port, 
   8538            pm_info_t pm_info, const portmod_drain_cells_t *drain_cells)
   8539 {
   8540     return(xlmac_drain_cell_stop (unit, port, drain_cells));
   8541 }
   8542 
   8543 int pm4x10_port_drain_cell_start(int unit, int port, pm_info_t pm_info)
   8544 {
   8545     return (xlmac_drain_cell_start(unit, port));
   8546 }
   8547 
   8548 int pm4x10_port_txfifo_cell_cnt_get(int unit, int port,
   8549                        pm_info_t pm_info, uint32* fval)
   8550 {
   8551     return(xlmac_txfifo_cell_cnt_get(unit, port, fval));
   8552 }
   8553 
   8554 int pm4x10_port_egress_queue_drain_get(int unit, int port,
   8555                    pm_info_t pm_info, uint64 *ctrl, int *rx)
   8556 {
   8557     return (xlmac_egress_queue_drain_get(unit, port, ctrl, rx));
   8558 }
   8559 
   8560 int pm4x10_port_drain_cells_rx_enable (int unit, int port,
   8561                    pm_info_t pm_info, int rx_en)
   8562 {
   8563     return (xlmac_drain_cells_rx_enable(unit, port, rx_en));
   8564 }
   8565 
   8566 int pm4x10_port_egress_queue_drain_rx_en(int unit, int port,
   8567                    pm_info_t pm_info, int rx_en)
   8568 {
   8569     return (xlmac_egress_queue_drain_rx_en(unit, port, rx_en));
   8570 }
   8571 
   8572 int pm4x10_port_mac_reset_set(int unit, int port,
   8573                    pm_info_t pm_info, int val)
   8574 {
   8575     int rv;
   8576     SOC_INIT_FUNC_DEFS;
   8577 
   8578     /* if callback defined, go to local soft reset function */
   8579     rv = (PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) ? pm4x10_port_soft_reset(unit, port, pm_info, val) : xlmac_soft_reset_set(unit, port, val);
   8580     _SOC_IF_ERR_EXIT(rv);
   8581 
   8582 exit:
   8583     SOC_FUNC_RETURN;
   8584 }
   8585 
   8586 int pm4x10_port_mac_reset_get (int unit, int port, pm_info_t pm_info, int* val)
   8587 {
   8588     return (xlmac_soft_reset_get(unit, port, val));
   8589 }
   8590 
   8591 int pm4x10_port_mac_reset_check(int unit, int port, pm_info_t pm_info,
   8592                                 int enable, int* reset)
   8593 {
   8594     return (xlmac_reset_check(unit, port, enable, reset));
   8595 }
   8596 
   8597 int pm4x10_port_core_num_get(int unit, int port, pm_info_t pm_info,
   8598                                 int* core_num)
   8599 {
   8600     *core_num = PM_4x10_INFO(pm_info)->core_num;
   8601     return (SOC_E_NONE);
   8602 }
   8603 
   8604 int pm4x10_port_e2ecc_hdr_set (int unit, int port, pm_info_t pm_info, 
   8605                                const portmod_port_higig_e2ecc_hdr_t* e2ecc_hdr)
   8606 {
   8607     return (xlmac_e2ecc_hdr_set (unit, port, (uint32_t *)e2ecc_hdr->words));
   8608 }
   8609 
   8610 
   8611 int pm4x10_port_e2ecc_hdr_get (int unit, int port, pm_info_t pm_info, 
   8612                                portmod_port_higig_e2ecc_hdr_t* e2ecc_hdr)
   8613 {
   8614     return (xlmac_e2ecc_hdr_get (unit, port, e2ecc_hdr->words));
   8615 }
   8616 
   8617 int pm4x10_port_e2e_enable_set (int unit, int port, pm_info_t pm_info, int enable) 
   8618 {
   8619     return (xlmac_e2e_enable_set(unit, port, enable));
   8620 }
   8621 
   8622 
   8623 int pm4x10_port_e2e_enable_get (int unit, int port, pm_info_t pm_info, int *enable)
   8624 {
   8625     return (xlmac_e2e_enable_get(unit, port, enable));
   8626 }
   8627 
   8628 int pm4x10_port_fallback_lane_get(int unit, int port, pm_info_t pm_info, int* fallback_lane)
   8629 {
   8630     int                         port_index;
   8631     uint32_t                    bitmap;
   8632 
   8633     SOC_INIT_FUNC_DEFS;
   8634     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   8635                                              &bitmap));
   8636     _SOC_IF_ERR_EXIT(PM4x10_PORT_FALLBACK_LANE_GET(unit, pm_info, fallback_lane,
   8637                                                    port_index));
   8638 
   8639 exit:
   8640     SOC_FUNC_RETURN;
   8641 
   8642 }
   8643 
   8644 /* in_out: 1= in reset, 0= in and out of reset */
   8645 STATIC
   8646 int pm4x10_port_soft_reset(int unit, int port, pm_info_t pm_info, int in_out)
   8647 {
   8648     int rv, rx_enable = 0;
   8649     int phy_port, block, bindex, i;
   8650     portmod_drain_cells_t drain_cells;
   8651     uint32 cell_count;
   8652     uint64 mac_ctrl;
   8653     soc_timeout_t to;
   8654     SOC_INIT_FUNC_DEFS;
   8655 
   8656     /* Callback soft reset function */
   8657     if (PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   8658         rv = PM_4x10_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypePre);
   8659         _SOC_IF_ERR_EXIT(rv);
   8660     }
   8661 
   8662     if(in_out == 0) {
   8663     
   8664         rv = xlmac_egress_queue_drain_get(unit, port, &mac_ctrl, &rx_enable); 
   8665         _SOC_IF_ERR_EXIT(rv);
   8666 
   8667         /* Drain cells */
   8668         rv = xlmac_drain_cell_get(unit, port, &drain_cells);
   8669         _SOC_IF_ERR_EXIT(rv);
   8670 
   8671         /* Start TX FIFO draining */
   8672         rv = xlmac_drain_cell_start(unit, port);
   8673         _SOC_IF_ERR_EXIT(rv);
   8674 
   8675         /* De-assert SOFT_RESET to let the drain start */
   8676         rv = xlmac_soft_reset_set(unit, port, 0);           
   8677         _SOC_IF_ERR_EXIT(rv);
   8678 
   8679         /* Wait until TX fifo cell count is 0 */
   8680         soc_timeout_init(&to, 250000, 0);
   8681         for (;;) {
   8682             rv = xlmac_txfifo_cell_cnt_get(unit, port, &cell_count);
   8683                _SOC_IF_ERR_EXIT(rv);
   8684                if (cell_count == 0) {
   8685                     break;
   8686             }
   8687             if (soc_timeout_check(&to)) {
   8688                     LOG_ERROR(BSL_LS_BCM_PORT,
   8689                               (BSL_META_UP(unit, port,
   8690                                    "ERROR: u=%d p=%d timeout draining "
   8691                                    "TX FIFO (%d cells remain)\n"),
   8692                                unit, port, cell_count));
   8693                     return SOC_E_INTERNAL;
   8694             }
   8695         }
   8696    
   8697         /* Stop TX FIFO draining */
   8698         rv = xlmac_drain_cell_stop (unit, port, &drain_cells);
   8699         _SOC_IF_ERR_EXIT(rv);
   8700 
   8701         /* Reset port FIFO */
   8702         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   8703        for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   8704             block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   8705                 if ((SOC_BLOCK_INFO(unit, block).type == SOC_BLK_XLPORT) ||
   8706                     (SOC_BLOCK_INFO(unit, block).type == SOC_BLK_XLPORTB0)) {
   8707                     bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   8708                     _SOC_IF_ERR_EXIT(portmod_port_soft_reset_toggle(unit, port, bindex));
   8709                     break;
   8710             }
   8711         }
   8712     }
   8713 
   8714     /* Put port into SOFT_RESET */
   8715     rv = xlmac_soft_reset_set(unit, port, 1);
   8716     _SOC_IF_ERR_EXIT(rv);
   8717     
   8718     if (in_out == 0) {
   8719 
   8720         /* Callback soft reset function */
   8721        if (PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   8722             rv = PM_4x10_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypeDuring);
   8723                _SOC_IF_ERR_EXIT(rv);
   8724                soc_reg64_field32_set (unit, XLMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 0); /*make sure restored data wont put mac back in reset*/
   8725         }
   8726 
   8727         /* Enable TX, set RX, de-assert SOFT_RESET */
   8728        rv = xlmac_egress_queue_drain_rx_en(unit, port, rx_enable);
   8729         _SOC_IF_ERR_EXIT(rv);
   8730 
   8731         /* Restore XLMAC_CTRL to original value */
   8732         rv = xlmac_mac_ctrl_set(unit, port, mac_ctrl);
   8733         _SOC_IF_ERR_EXIT(rv);
   8734     }
   8735 
   8736     /* Callback soft reset function */
   8737     if (PM_4x10_INFO(pm_info)->portmod_mac_soft_reset) {
   8738         rv = PM_4x10_INFO(pm_info)->portmod_mac_soft_reset(unit, port, portmodCallBackActionTypePost);
   8739         _SOC_IF_ERR_EXIT(rv);
   8740     }
   8741  
   8742 exit:
   8743     SOC_FUNC_RETURN;
   8744 }
   8745 
   8746 /*Port discard set*/
   8747 int pm4x10_port_discard_set(int unit, int port, pm_info_t pm_info, int discard)
   8748 {
   8749     return(xlmac_discard_set(unit, port, discard));
   8750 }
   8751 
   8752 /*Port soft reset set set*/
   8753 int pm4x10_port_soft_reset_set(int unit, int port, pm_info_t pm_info, int idx,
   8754                                int val, int flags)
   8755 {
   8756     SOC_INIT_FUNC_DEFS;
   8757 
   8758     if (PORTMOD_PORT_REG_ACCESS_DIRECT == flags) {
   8759         _SOC_IF_ERR_EXIT(_pm4x10_port_soft_reset_set_by_phyport(unit, port,
   8760                                                         pm_info, idx, val));
   8761     } else {
   8762         _SOC_IF_ERR_EXIT(_pm4x10_port_soft_reset_set(unit, port, pm_info, idx, val));
   8763     }
   8764 
   8765 exit:
   8766     SOC_FUNC_RETURN;
   8767 }
   8768 
   8769 /*Port tx_en=0 and softreset mac*/
   8770 int pm4x10_port_tx_down(int unit, int port, pm_info_t pm_info)
   8771 {
   8772     SOC_INIT_FUNC_DEFS;
   8773 
   8774     _SOC_IF_ERR_EXIT(xlmac_tx_enable_set(unit, port, 0));
   8775     _SOC_IF_ERR_EXIT(xlmac_discard_set(unit, port, 0));
   8776     _SOC_IF_ERR_EXIT(xlmac_soft_reset_set(unit, port, 1));
   8777 
   8778 exit:
   8779     SOC_FUNC_RETURN;
   8780 }
   8781 
   8782 int pm4x10_port_pgw_reconfig (int unit, int port, pm_info_t pm_info, 
   8783                               const portmod_port_mode_info_t *pmode, int phy_port, int flags)
   8784 {
   8785     int rv, idx;
   8786     int phy_acc;
   8787     uint32 reg_val;
   8788     soc_field_t port_fields[] = {PORT0f, PORT1f, PORT2f, PORT3f};
   8789 
   8790     SOC_INIT_FUNC_DEFS; 
   8791 
   8792     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   8793 
   8794     if (PORTMOD_PORT_PGW_MAC_RESET == flags) {
   8795         rv = xlmac_discard_set(unit, port, 1);
   8796         _SOC_IF_ERR_EXIT(rv);
   8797         rv = xlmac_rx_enable_set(unit, port, 0);
   8798         _SOC_IF_ERR_EXIT(rv);
   8799         rv = xlmac_tx_enable_set(unit, port, 0);
   8800         _SOC_IF_ERR_EXIT(rv);
   8801         rv = xlmac_soft_reset_set(unit, port, 1);
   8802         _SOC_IF_ERR_EXIT(rv);
   8803 
   8804         _SOC_IF_ERR_EXIT(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   8805         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 1);
   8806         _SOC_IF_ERR_EXIT(WRITE_XLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   8807 
   8808     } else if (PORTMOD_PORT_PGW_POWER_SAVE == flags) {
   8809          _SOC_IF_ERR_EXIT(READ_XLPORT_POWER_SAVEr(unit, phy_acc, &reg_val));
   8810          soc_reg_field_set(unit, XLPORT_POWER_SAVEr, &reg_val, XPORT_CORE0f, 1);
   8811          _SOC_IF_ERR_EXIT(WRITE_XLPORT_POWER_SAVEr(unit, phy_acc, reg_val));
   8812 
   8813     } else if (PORTMOD_PORT_PGW_MAC_UNRESET == flags) {
   8814         _SOC_IF_ERR_EXIT(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
   8815         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val, XMAC0_RESETf, 0);
   8816         _SOC_IF_ERR_EXIT(WRITE_XLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
   8817     } else if (PORTMOD_PORT_PGW_CONFIGURE == flags) {
   8818         /* 10/20/40G RECONFIGURE SEQUENCE */
   8819         idx = pmode->port_index;
   8820 
   8821         /* 1.a st SOFT_RESET field in XLMAC_CTRL for new ports that use XLMAC */
   8822         rv = xlmac_soft_reset_set(unit, port, 1);
   8823         _SOC_IF_ERR_EXIT(rv);
   8824 
   8825         /* 1.a set PORT[subport] field in XLPORT_SOFT_RESET for all new ports */
   8826         _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   8827         soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, port_fields[idx], 1);
   8828         _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   8829 
   8830         /* Port enable */
   8831         _SOC_IF_ERR_EXIT(READ_XLPORT_ENABLE_REGr(unit, phy_acc, &reg_val));
   8832         soc_reg_field_set (unit, XLPORT_ENABLE_REGr, &reg_val,
   8833                                port_fields[idx], 1);
   8834         _SOC_IF_ERR_EXIT(WRITE_XLPORT_ENABLE_REGr(unit, phy_acc, reg_val));
   8835 
   8836         /* set port mode */
   8837         _SOC_IF_ERR_EXIT(pm4x10_port_mode_set(unit, port, pm_info, pmode));
   8838 
   8839         /* Release XLPORT SOFT RESET */
   8840         _SOC_IF_ERR_EXIT(READ_XLPORT_SOFT_RESETr(unit, phy_acc, &reg_val));
   8841         soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &reg_val, port_fields[idx], 0);
   8842         _SOC_IF_ERR_EXIT(WRITE_XLPORT_SOFT_RESETr(unit, phy_acc, reg_val));
   8843 
   8844         /*Release Mac Soft Reset */
   8845         rv = xlmac_soft_reset_set(unit, port, 0);
   8846         _SOC_IF_ERR_EXIT(rv);
   8847     }
   8848 exit:
   8849     SOC_FUNC_RETURN;
   8850 }
   8851 
   8852 int pm4x10_port_notify(int unit, int port, pm_info_t pm_info, int link) {
   8853     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8854     int nof_phys;
   8855     portmod_port_interface_config_t interface_config;
   8856     SOC_INIT_FUNC_DEFS;
   8857 
   8858     _SOC_IF_ERR_EXIT
   8859         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
   8860                                            phy_access ,(1+MAX_PHYN),
   8861                                            &nof_phys));
   8862     /* If nof phys > 1 change the internal phy speed based on the external 
   8863     link speed if the link is up*/
   8864     if (nof_phys > 1) {
   8865         if (link) {
   8866             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit,
   8867                                                                port,
   8868                                                                &interface_config,
   8869                                                                PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   8870             /* Set the interface config to internal phy */
   8871             _SOC_IF_ERR_EXIT(portmod_port_interface_config_set(unit,
   8872                                                                port,
   8873                                                                &interface_config, 
   8874                                                                PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   8875         } else {
   8876             /*TBD*/
   8877         }
   8878     } 
   8879     exit:
   8880     SOC_FUNC_RETURN;   
   8881 }
   8882 
   8883 int pm4x10_port_timesync_config_set(int unit, int port, pm_info_t pm_info, const portmod_phy_timesync_config_t* config)
   8884 {
   8885     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8886     int nof_phys;
   8887     SOC_INIT_FUNC_DEFS;
   8888 
   8889     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8890                                                        phy_access ,(1+MAX_PHYN),
   8891                                                        &nof_phys));
   8892     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_config_set(unit, port, phy_access,
   8893                                                                   nof_phys,config));
   8894     exit:
   8895     SOC_FUNC_RETURN;   
   8896 }
   8897 
   8898 int pm4x10_port_timesync_config_get(int unit, int port, pm_info_t pm_info, portmod_phy_timesync_config_t* config)
   8899 {
   8900     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8901     int nof_phys;
   8902     SOC_INIT_FUNC_DEFS;
   8903 
   8904     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8905                                                        phy_access ,(1+MAX_PHYN),
   8906                                                        &nof_phys));
   8907     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_config_get(unit, port, phy_access,
   8908                                                                   nof_phys,config));
   8909     exit:
   8910     SOC_FUNC_RETURN;  
   8911 }
   8912 
   8913 int pm4x10_port_timesync_enable_set(int unit, int port, pm_info_t pm_info, uint32 enable)
   8914 {
   8915     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8916     int nof_phys;
   8917     SOC_INIT_FUNC_DEFS;
   8918 
   8919     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8920                                                        phy_access ,(1+MAX_PHYN),
   8921                                                        &nof_phys));
   8922     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_enable_set(unit, phy_access,
   8923                                                                   nof_phys,enable));
   8924     exit:
   8925     SOC_FUNC_RETURN;   
   8926 }
   8927 
   8928 int pm4x10_port_timesync_enable_get(int unit, int port, pm_info_t pm_info, uint32* enable)
   8929 {
   8930     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8931     int nof_phys;
   8932     SOC_INIT_FUNC_DEFS;
   8933 
   8934     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8935                                                        phy_access ,(1+MAX_PHYN),
   8936                                                        &nof_phys));
   8937     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_enable_get(unit, phy_access,
   8938                                                                   nof_phys,enable));
   8939 
   8940     exit:
   8941     SOC_FUNC_RETURN;
   8942 }
   8943 
   8944 int pm4x10_port_timesync_nco_addend_set(int unit, int port, pm_info_t pm_info, uint32 freq_step)
   8945 {
   8946     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8947     int nof_phys;
   8948     SOC_INIT_FUNC_DEFS;
   8949 
   8950     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8951                                                        phy_access ,(1+MAX_PHYN),
   8952                                                        &nof_phys));
   8953     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_nco_addend_set(unit, phy_access,
   8954                                                                       nof_phys,freq_step));
   8955     exit:
   8956     SOC_FUNC_RETURN;
   8957 }
   8958 
   8959 int pm4x10_port_timesync_nco_addend_get(int unit, int port, pm_info_t pm_info, uint32* freq_step)
   8960 {
   8961     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8962     int nof_phys;
   8963     SOC_INIT_FUNC_DEFS;
   8964 
   8965     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8966                                                        phy_access ,(1+MAX_PHYN),
   8967                                                        &nof_phys));
   8968     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_nco_addend_get(unit, phy_access,
   8969                                                                       nof_phys,freq_step));
   8970     exit:
   8971     SOC_FUNC_RETURN;
   8972 }
   8973 
   8974 int pm4x10_port_timesync_framesync_mode_set(int unit, int port, pm_info_t pm_info, 
   8975                                             const portmod_timesync_framesync_t* framesync)
   8976 {
   8977     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8978     int nof_phys;
   8979     SOC_INIT_FUNC_DEFS;
   8980 
   8981     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8982                                                        phy_access ,(1+MAX_PHYN),
   8983                                                        &nof_phys));
   8984     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_framesync_mode_set(unit, phy_access,
   8985                                                                           nof_phys,framesync));
   8986     exit:
   8987     SOC_FUNC_RETURN;
   8988 }
   8989 
   8990 int pm4x10_port_timesync_framesync_mode_get(int unit, int port, pm_info_t pm_info, 
   8991                                             portmod_timesync_framesync_t* framesync)
   8992 {
   8993     phymod_phy_access_t phy_access[1+MAX_PHYN];
   8994     int nof_phys;
   8995     SOC_INIT_FUNC_DEFS;
   8996 
   8997     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   8998                                                        phy_access ,(1+MAX_PHYN),
   8999                                                        &nof_phys));
   9000     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_framesync_mode_get(unit, phy_access,
   9001                                                                       nof_phys,framesync));
   9002     exit:
   9003     SOC_FUNC_RETURN;
   9004 }
   9005 
   9006 int pm4x10_port_timesync_local_time_set(int unit, int port, pm_info_t pm_info, const uint64 local_time)
   9007 {
   9008     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9009     int nof_phys;
   9010     SOC_INIT_FUNC_DEFS;
   9011 
   9012     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9013                                                        phy_access ,(1+MAX_PHYN),
   9014                                                        &nof_phys));
   9015     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_local_time_set(unit, phy_access,
   9016                                                                       nof_phys,local_time));
   9017     exit:
   9018     SOC_FUNC_RETURN;
   9019 }
   9020 
   9021 
   9022 int pm4x10_port_timesync_local_time_get(int unit, int port, pm_info_t pm_info, uint64* local_time)
   9023 {
   9024     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9025     int nof_phys;
   9026     SOC_INIT_FUNC_DEFS;
   9027 
   9028     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9029                                                        phy_access ,(1+MAX_PHYN),
   9030                                                        &nof_phys));
   9031     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_local_time_get(unit, phy_access, nof_phys,
   9032                                                                       local_time));
   9033     exit:
   9034     SOC_FUNC_RETURN;
   9035 }
   9036 
   9037 int pm4x10_port_timesync_load_ctrl_set(int unit, int port, pm_info_t pm_info, 
   9038                                        uint32 load_once, uint32 load_always)
   9039 {
   9040     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9041     int nof_phys;
   9042     SOC_INIT_FUNC_DEFS;
   9043 
   9044     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9045                                                        phy_access ,(1+MAX_PHYN),
   9046                                                        &nof_phys));
   9047     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_load_ctrl_set(unit, phy_access, nof_phys,
   9048                                                                      load_once, load_always));
   9049     exit:
   9050     SOC_FUNC_RETURN;
   9051 }
   9052 
   9053 int pm4x10_port_timesync_load_ctrl_get(int unit, int port, pm_info_t pm_info, 
   9054                                        uint32* load_once, uint32* load_always)
   9055 {
   9056     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9057     int nof_phys;
   9058     SOC_INIT_FUNC_DEFS;
   9059 
   9060     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9061                                                        phy_access ,(1+MAX_PHYN),
   9062                                                        &nof_phys));
   9063     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_load_ctrl_get(unit, phy_access, nof_phys,
   9064                                                                      load_once, load_always));
   9065     exit:
   9066     SOC_FUNC_RETURN;
   9067 }
   9068 
   9069 int pm4x10_port_timesync_tx_timestamp_offset_set(int unit, int port, pm_info_t pm_info, uint32 ts_offset)
   9070 {
   9071     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9072     int nof_phys;
   9073     SOC_INIT_FUNC_DEFS;
   9074 
   9075     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9076                                                        phy_access ,(1+MAX_PHYN),
   9077                                                        &nof_phys));
   9078     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_tx_timestamp_offset_set(unit, phy_access, nof_phys,
   9079                                                                                ts_offset));
   9080     exit:
   9081     SOC_FUNC_RETURN;
   9082 }
   9083 
   9084 int pm4x10_port_timesync_tx_timestamp_offset_get(int unit, int port, pm_info_t pm_info, uint32* ts_offset)
   9085 {
   9086     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9087     int nof_phys;
   9088     SOC_INIT_FUNC_DEFS;
   9089 
   9090     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9091                                                        phy_access ,(1+MAX_PHYN),
   9092                                                        &nof_phys));
   9093     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_tx_timestamp_offset_get(unit, phy_access, nof_phys,
   9094                                                                                ts_offset));
   9095     exit:
   9096     SOC_FUNC_RETURN;
   9097 }
   9098 
   9099 int pm4x10_port_timesync_rx_timestamp_offset_set(int unit, int port, pm_info_t pm_info, uint32 ts_offset)
   9100 {
   9101     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9102     int nof_phys;
   9103     SOC_INIT_FUNC_DEFS;
   9104 
   9105     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9106                                                        phy_access ,(1+MAX_PHYN),
   9107                                                        &nof_phys));
   9108     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_rx_timestamp_offset_set(unit, phy_access, nof_phys,
   9109                                                                                ts_offset));
   9110     exit:
   9111     SOC_FUNC_RETURN;
   9112 }
   9113 
   9114 int pm4x10_port_timesync_rx_timestamp_offset_get(int unit, int port, pm_info_t pm_info, uint32* ts_offset)
   9115 {
   9116     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9117     int nof_phys;
   9118     SOC_INIT_FUNC_DEFS;
   9119 
   9120     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9121                                                        phy_access ,(1+MAX_PHYN),
   9122                                                        &nof_phys));
   9123     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_rx_timestamp_offset_get(unit, phy_access, nof_phys,
   9124                                                                                ts_offset));
   9125     exit:
   9126     SOC_FUNC_RETURN;
   9127 }
   9128 
   9129 /*
   9130  *Function:
   9131  *  pm4x10_port_timestamp_adjust_set
   9132  *
   9133  *Purpose:
   9134  *  It sets tsts,osts adjustment into MAC registers directly.
   9135 */
   9136 int
   9137 pm4x10_port_timestamp_adjust_set(int unit, int port, pm_info_t pm_info,
   9138                          const soc_port_timestamp_adjust_t *ts_adjust)
   9139 {
   9140     int port_index;
   9141     uint32_t bitmap, port_dynamic_state;
   9142     portmod_port_interface_config_t port_intf_config;
   9143     portmod_port_ts_adjust_t portmod_ts_adjust;
   9144     SOC_INIT_FUNC_DEFS;
   9145 
   9146     sal_memset(&port_intf_config, 0, sizeof(portmod_port_interface_config_t));
   9147     sal_memset(&portmod_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   9148 
   9149     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
   9150     _SOC_IF_ERR_EXIT
   9151         (pm4x10_port_interface_config_get(unit, port, pm_info, &port_intf_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   9152     portmod_ts_adjust.speed = port_intf_config.speed;
   9153     portmod_ts_adjust.osts_adjust = ts_adjust->osts_adjust;
   9154     portmod_ts_adjust.tsts_adjust = ts_adjust->tsts_adjust;
   9155     _SOC_IF_ERR_EXIT(xlmac_timestamp_delay_set(unit, port, portmod_ts_adjust, port_intf_config.speed));
   9156 
   9157     _SOC_IF_ERR_EXIT(PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info, &port_dynamic_state, port_index));
   9158     PORTMOD_PORT_DEFAULT_TIMESTAMP_ADJUSTMENT_UPDATED_SET(port_dynamic_state);
   9159     _SOC_IF_ERR_EXIT(PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info, port_dynamic_state, port_index));
   9160     exit:
   9161     SOC_FUNC_RETURN;
   9162 }
   9163 
   9164 /*
   9165  *Function:
   9166  *  pm4x10_port_timestamp_adjust_get
   9167  *
   9168  *Purpose:
   9169  *  Get the tsts,osts adjustment from MAC register.
   9170  */
   9171 int
   9172 pm4x10_port_timestamp_adjust_get(int unit, int port, pm_info_t pm_info,
   9173                           soc_port_timestamp_adjust_t *ts_adjust)
   9174 {
   9175     portmod_port_ts_adjust_t portmod_ts_adjust;
   9176     SOC_INIT_FUNC_DEFS;
   9177 
   9178     sal_memset(&portmod_ts_adjust, 0, sizeof(portmod_port_ts_adjust_t));
   9179 
   9180     _SOC_IF_ERR_EXIT(xlmac_timestamp_delay_get(unit, port, &portmod_ts_adjust));
   9181     ts_adjust->osts_adjust = portmod_ts_adjust.osts_adjust;
   9182     ts_adjust->tsts_adjust = portmod_ts_adjust.tsts_adjust;
   9183 
   9184     exit:
   9185     SOC_FUNC_RETURN;
   9186 }
   9187 
   9188 int pm4x10_port_phy_intr_enable_set(int unit, int port, pm_info_t pm_info, uint32 intr_enable)
   9189 {
   9190     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9191     int nof_phys;
   9192     SOC_INIT_FUNC_DEFS;
   9193 
   9194     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9195                                                        phy_access ,(1+MAX_PHYN),
   9196                                                        &nof_phys));
   9197     SOC_IF_ERROR_RETURN(portmod_port_phychain_phy_intr_enable_set(unit, phy_access, nof_phys,
   9198                                                                      intr_enable));
   9199     exit:
   9200     SOC_FUNC_RETURN;
   9201 }
   9202 
   9203 int pm4x10_port_phy_intr_enable_get(int unit, int port, pm_info_t pm_info, uint32* intr_enable)
   9204 {
   9205     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9206     int nof_phys;
   9207     SOC_INIT_FUNC_DEFS;
   9208 
   9209     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9210                                                        phy_access ,(1+MAX_PHYN),
   9211                                                        &nof_phys));
   9212     SOC_IF_ERROR_RETURN(portmod_port_phychain_phy_intr_enable_get(unit, phy_access, nof_phys,
   9213                                                                   intr_enable));
   9214     exit:
   9215     SOC_FUNC_RETURN;
   9216 }
   9217 
   9218 int pm4x10_port_phy_intr_status_get(int unit, int port, pm_info_t pm_info, uint32* intr_enable)
   9219 {
   9220     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9221     int nof_phys;
   9222     SOC_INIT_FUNC_DEFS;
   9223 
   9224     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9225                                                        phy_access ,(1+MAX_PHYN),
   9226                                                        &nof_phys));
   9227     SOC_IF_ERROR_RETURN(portmod_port_phychain_phy_intr_status_get(unit, phy_access, nof_phys,
   9228                                                                   intr_enable));
   9229     exit:
   9230     SOC_FUNC_RETURN;
   9231 }
   9232 
   9233 int pm4x10_port_phy_intr_status_clear(int unit, int port, pm_info_t pm_info)
   9234 {
   9235     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9236     int nof_phys;
   9237     SOC_INIT_FUNC_DEFS;
   9238 
   9239     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9240                                                        phy_access ,(1+MAX_PHYN),
   9241                                                        &nof_phys));
   9242     SOC_IF_ERROR_RETURN(portmod_port_phychain_phy_intr_status_clear(unit, phy_access, nof_phys));
   9243 
   9244     exit:
   9245     SOC_FUNC_RETURN;
   9246 }
   9247 
   9248 int pm4x10_port_phy_timesync_do_sync(int unit, int port, pm_info_t pm_info )
   9249 {
   9250     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9251     int nof_phys;
   9252     SOC_INIT_FUNC_DEFS;
   9253 
   9254     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9255                                                        phy_access ,(1+MAX_PHYN),
   9256                                                        &nof_phys));
   9257     SOC_IF_ERROR_RETURN(portmod_port_phychain_phy_timesync_do_sync(unit, phy_access, nof_phys ));
   9258     exit:
   9259     SOC_FUNC_RETURN;
   9260 }
   9261 
   9262 int pm4x10_port_timesync_capture_timestamp_get(int unit, int port, pm_info_t pm_info, uint64* cap_ts)
   9263 {
   9264     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9265     int nof_phys;
   9266     SOC_INIT_FUNC_DEFS;
   9267 
   9268     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9269                                                        phy_access ,(1+MAX_PHYN),
   9270                                                        &nof_phys));
   9271     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_capture_timestamp_get(unit, phy_access, nof_phys,
   9272                                                                              cap_ts));
   9273     exit:
   9274     SOC_FUNC_RETURN;
   9275 }
   9276 
   9277 
   9278 int pm4x10_port_timesync_heartbeat_timestamp_get(int unit, int port, pm_info_t pm_info, uint64* hb_ts)
   9279 {
   9280     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9281     int nof_phys;
   9282     SOC_INIT_FUNC_DEFS;
   9283 
   9284     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9285                                                        phy_access ,(1+MAX_PHYN),
   9286                                                        &nof_phys));
   9287     SOC_IF_ERROR_RETURN(portmod_port_phychain_timesync_heartbeat_timestamp_get(unit, phy_access, nof_phys,
   9288                                                                               hb_ts));
   9289     exit:
   9290     SOC_FUNC_RETURN;
   9291 }
   9292 
   9293 int pm4x10_port_edc_config_set(int unit, int port, pm_info_t pm_info, 
   9294                                const portmod_edc_config_t* config)
   9295 {
   9296     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9297     int nof_phys;
   9298     SOC_INIT_FUNC_DEFS;
   9299 
   9300     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9301                                                        phy_access ,(1+MAX_PHYN),
   9302                                                        &nof_phys));
   9303     SOC_IF_ERROR_RETURN(portmod_port_phychain_edc_config_set(unit, phy_access, nof_phys, config));
   9304     exit:
   9305     SOC_FUNC_RETURN;
   9306 }
   9307 
   9308 int pm4x10_port_edc_config_get(int unit, int port, pm_info_t pm_info, 
   9309                                portmod_edc_config_t* config)
   9310 {
   9311     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9312     int nof_phys;
   9313     SOC_INIT_FUNC_DEFS;
   9314 
   9315     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9316                                                        phy_access ,(1+MAX_PHYN),
   9317                                                        &nof_phys));
   9318     SOC_IF_ERROR_RETURN(portmod_port_phychain_edc_config_get(unit, phy_access, nof_phys, config));
   9319     exit:
   9320     SOC_FUNC_RETURN;
   9321 }
   9322 
   9323 /* get interrupt value. */
   9324 int pm4x10_port_interrupt_enable_get (int unit, int port, pm_info_t pm_info,
   9325                                     int intr_type, uint32 *val)
   9326 {
   9327     uint32 reg_val;
   9328     int phy_acc;
   9329     pm_version_t pm_version;
   9330     SOC_INIT_FUNC_DEFS;
   9331 
   9332     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9333     _SOC_IF_ERR_EXIT(READ_XLPORT_INTR_ENABLEr(unit, phy_acc, &reg_val));
   9334     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   9335 
   9336     switch(intr_type) {
   9337         case portmodIntrTypeMibTxMemErr:
   9338              *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, MIB_TX_MEM_ERRf);
   9339              break;
   9340         case portmodIntrTypeMibRxMemErr:
   9341              *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, MIB_RX_MEM_ERRf);
   9342              break;
   9343         case portmodIntrTypeMacTxCdcMemErr:
   9344              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9345                  *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, MAC_TX_CDC_MEM_ERRf);
   9346                  break;
   9347              }
   9348              else {
   9349                  return SOC_E_UNAVAIL;
   9350              }
   9351         case portmodIntrTypeMacRxCdcMemErr:
   9352              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9353                  *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, MAC_RX_CDC_MEM_ERRf);
   9354                  break;
   9355              }
   9356              else {
   9357                  return SOC_E_UNAVAIL;
   9358              }
   9359         case portmodIntrTypeTscErr:
   9360              *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, TSC_ERRf);
   9361              break;
   9362         case portmodIntrTypeRxFcReqFull:
   9363              *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, RX_FLOWCONTROL_REQ_FULLf);
   9364              break;
   9365         case portmodIntrTypeLinkdown:
   9366              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9367                  *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, LINK_DOWNf);
   9368                  break;
   9369              }
   9370              else {
   9371                  return SOC_E_UNAVAIL;
   9372              }
   9373         case portmodIntrTypeMacErr:
   9374              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9375                  *val = soc_reg_field_get(unit, XLPORT_INTR_ENABLEr, reg_val, MAC_ERRf);
   9376                  break;
   9377              }
   9378              else {
   9379                  return SOC_E_UNAVAIL;
   9380              }
   9381         case portmodIntrTypeTxPktUnderflow :
   9382         case portmodIntrTypeTxPktOverflow :
   9383         case portmodIntrTypeTxLlfcMsgOverflow :
   9384         case portmodIntrTypeTxTSFifoOverflow :
   9385         case portmodIntrTypeRxPktOverflow :
   9386         case portmodIntrTypeRxMsgOverflow :
   9387         case portmodIntrTypeTxCdcSingleBitErr :
   9388         case portmodIntrTypeTxCdcDoubleBitErr :
   9389         case portmodIntrTypeRxCdcSingleBitErr :
   9390         case portmodIntrTypeRxCdcDoubleBitErr :
   9391         case portmodIntrTypeLocalFaultStatus :
   9392         case portmodIntrTypeRemoteFaultStatus :
   9393         case portmodIntrTypeLinkInterruptionStatus :
   9394         case portmodIntrTypeTsEntryValid :
   9395              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9396                  _SOC_IF_ERR_EXIT(xlmac_interrupt_enable_get(unit, port, intr_type, val));
   9397                  break;
   9398              }
   9399              else {
   9400                  return SOC_E_UNAVAIL;
   9401              }
   9402         default:
   9403             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   9404             break;
   9405     }
   9406 
   9407 exit:
   9408     SOC_FUNC_RETURN;
   9409 }
   9410 
   9411 /* set interrupt value. */
   9412 int pm4x10_port_interrupt_enable_set (int unit, int port, pm_info_t pm_info,
   9413                                     int intr_type, uint32 val)
   9414 {
   9415     uint32 reg_val;
   9416     int phy_acc;
   9417     pm_version_t pm_version;
   9418     SOC_INIT_FUNC_DEFS;
   9419 
   9420     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9421     _SOC_IF_ERR_EXIT(READ_XLPORT_INTR_ENABLEr(unit, phy_acc, &reg_val));
   9422     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   9423 
   9424     switch(intr_type) {
   9425         case portmodIntrTypeMibTxMemErr:
   9426              soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, MIB_TX_MEM_ERRf, val);
   9427              break;
   9428         case portmodIntrTypeMibRxMemErr:
   9429              soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, MIB_RX_MEM_ERRf, val);
   9430              break;
   9431         case portmodIntrTypeMacTxCdcMemErr:
   9432              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9433                 soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, MAC_TX_CDC_MEM_ERRf, val);
   9434                 break;
   9435              }
   9436              else {
   9437                 return SOC_E_UNAVAIL;
   9438              }
   9439         case portmodIntrTypeMacRxCdcMemErr:
   9440              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9441                 soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, MAC_RX_CDC_MEM_ERRf, val);
   9442                 break;
   9443              }
   9444              else {
   9445                 return SOC_E_UNAVAIL;
   9446              }
   9447         case portmodIntrTypeTscErr:
   9448              soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, TSC_ERRf, val);
   9449              break;
   9450         case portmodIntrTypeRxFcReqFull:
   9451              soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, RX_FLOWCONTROL_REQ_FULLf, val);
   9452              break;
   9453         case portmodIntrTypeLinkdown:
   9454              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9455                  soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, LINK_DOWNf, val);
   9456                  break;
   9457              }
   9458              else {
   9459                  return SOC_E_UNAVAIL;
   9460              }
   9461         case portmodIntrTypeMacErr:
   9462              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9463                 soc_reg_field_set(unit, XLPORT_INTR_ENABLEr, &reg_val, MAC_ERRf, val);
   9464                 break;
   9465              }
   9466              else {
   9467                 return SOC_E_UNAVAIL;
   9468              }
   9469         case portmodIntrTypeTxPktUnderflow :
   9470         case portmodIntrTypeTxPktOverflow :
   9471         case portmodIntrTypeTxLlfcMsgOverflow :
   9472         case portmodIntrTypeTxTSFifoOverflow :
   9473         case portmodIntrTypeRxPktOverflow :
   9474         case portmodIntrTypeRxMsgOverflow :
   9475         case portmodIntrTypeTxCdcSingleBitErr :
   9476         case portmodIntrTypeTxCdcDoubleBitErr :
   9477         case portmodIntrTypeRxCdcSingleBitErr :
   9478         case portmodIntrTypeRxCdcDoubleBitErr :
   9479         case portmodIntrTypeLocalFaultStatus :
   9480         case portmodIntrTypeRemoteFaultStatus :
   9481         case portmodIntrTypeLinkInterruptionStatus :
   9482         case portmodIntrTypeTsEntryValid :
   9483              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9484                 _SOC_IF_ERR_EXIT(xlmac_interrupt_enable_set(unit, port, intr_type, val));
   9485                 break;
   9486              }
   9487              else {
   9488                 return SOC_E_UNAVAIL;
   9489              }
   9490         default:
   9491             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   9492             break;
   9493     }
   9494     _SOC_IF_ERR_EXIT(WRITE_XLPORT_INTR_ENABLEr(unit, phy_acc, reg_val));
   9495 
   9496 exit:
   9497     SOC_FUNC_RETURN;
   9498 }
   9499 
   9500 /* get interrupt value. */
   9501 int pm4x10_port_interrupt_get (int unit, int port, pm_info_t pm_info,
   9502                                int intr_type, uint32* val)
   9503 {
   9504     uint32 reg_val;
   9505     int phy_acc;
   9506     pm_version_t pm_version;
   9507     SOC_INIT_FUNC_DEFS;
   9508 
   9509     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9510     _SOC_IF_ERR_EXIT(READ_XLPORT_INTR_STATUSr(unit, phy_acc, &reg_val));
   9511     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   9512 
   9513     switch(intr_type) {
   9514         case portmodIntrTypeMibTxMemErr:
   9515              *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MIB_TX_MEM_ERRf);
   9516              break;
   9517         case portmodIntrTypeMibRxMemErr:
   9518              *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MIB_RX_MEM_ERRf);
   9519              break;
   9520         case portmodIntrTypeMacTxCdcMemErr:
   9521              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9522                 *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_TX_CDC_MEM_ERRf);
   9523                 break;
   9524              }
   9525              else {
   9526                 return SOC_E_UNAVAIL;
   9527              }
   9528         case portmodIntrTypeMacRxCdcMemErr:
   9529              if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9530                 *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_RX_CDC_MEM_ERRf);
   9531                 break;
   9532              }
   9533              else {
   9534                 return SOC_E_UNAVAIL;
   9535               }
   9536         case portmodIntrTypeTscErr:
   9537              *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, TSC_ERRf);
   9538              break;
   9539         case portmodIntrTypeRxFcReqFull:
   9540              *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, RX_FLOWCONTROL_REQ_FULLf);
   9541              break;
   9542         case portmodIntrTypeLinkdown:
   9543              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9544                 *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, LINK_DOWNf);
   9545                 break;
   9546              }
   9547              else {
   9548                 return SOC_E_UNAVAIL;
   9549              }
   9550         case portmodIntrTypeMacErr:
   9551              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9552                    *val = soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_ERRf);
   9553                     break;
   9554              }
   9555              else {
   9556                   return SOC_E_UNAVAIL;
   9557              }
   9558         case portmodIntrTypeTxPktUnderflow :
   9559         case portmodIntrTypeTxPktOverflow :
   9560         case portmodIntrTypeTxLlfcMsgOverflow :
   9561         case portmodIntrTypeTxTSFifoOverflow :
   9562         case portmodIntrTypeRxPktOverflow :
   9563         case portmodIntrTypeRxMsgOverflow :
   9564         case portmodIntrTypeTxCdcSingleBitErr :
   9565         case portmodIntrTypeTxCdcDoubleBitErr :
   9566         case portmodIntrTypeRxCdcSingleBitErr :
   9567         case portmodIntrTypeRxCdcDoubleBitErr :
   9568         case portmodIntrTypeLocalFaultStatus :
   9569         case portmodIntrTypeRemoteFaultStatus :
   9570         case portmodIntrTypeLinkInterruptionStatus :
   9571         case portmodIntrTypeTsEntryValid :
   9572              if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9573                 _SOC_IF_ERR_EXIT(xlmac_interrupt_status_get(unit, port, intr_type, val));
   9574                 break;
   9575              }
   9576              else {
   9577                 return SOC_E_UNAVAIL;
   9578              }
   9579         default:
   9580             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   9581             break;
   9582     }
   9583 exit:
   9584     SOC_FUNC_RETURN;
   9585 }
   9586 
   9587 int pm4x10_port_interrupts_get (int unit, int port, pm_info_t pm_info,
   9588                                 int arr_max_size, uint32* intr_arr, uint32* size)
   9589 {
   9590     uint32 reg_val, cnt=0;
   9591     int phy_acc;
   9592     uint32 mac_intr_cnt = 0;
   9593     pm_version_t pm_version;
   9594     SOC_INIT_FUNC_DEFS;
   9595 
   9596     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9597     _SOC_IF_ERR_EXIT(READ_XLPORT_INTR_STATUSr(unit, phy_acc, &reg_val));
   9598     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
   9599 
   9600     if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MIB_TX_MEM_ERRf)) {
   9601         if (cnt >= arr_max_size) {
   9602             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9603         }
   9604         intr_arr[cnt++] = portmodIntrTypeMibTxMemErr;
   9605     }
   9606 
   9607     if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MIB_RX_MEM_ERRf)) {
   9608         if (cnt >= arr_max_size) {
   9609             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9610         }
   9611         intr_arr[cnt++] = portmodIntrTypeMibRxMemErr;
   9612     }
   9613 
   9614     if(PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9615         if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_TX_CDC_MEM_ERRf)) {
   9616             if (cnt >= arr_max_size) {
   9617                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9618             }
   9619             intr_arr[cnt++] = portmodIntrTypeMacTxCdcMemErr;
   9620         }
   9621         if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_RX_CDC_MEM_ERRf)) {
   9622              if (cnt >= arr_max_size) {
   9623                  _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9624              }
   9625              intr_arr[cnt++] = portmodIntrTypeMacRxCdcMemErr;
   9626         }
   9627     }
   9628 
   9629     if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, TSC_ERRf)) {
   9630         if (cnt >= arr_max_size) {
   9631             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9632         }
   9633         intr_arr[cnt++] = portmodIntrTypeTscErr;
   9634     }
   9635     if (soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, RX_FLOWCONTROL_REQ_FULLf)) {
   9636         if (cnt >= arr_max_size) {
   9637             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9638         }
   9639         intr_arr[cnt++] = portmodIntrTypeRxFcReqFull;
   9640     }
   9641 
   9642     if(!PORTMOD_PM4x10_IS_GEN1(pm_version)) {
   9643         if(soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, LINK_DOWNf)) {
   9644              if (cnt >= arr_max_size) {
   9645                   _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9646              }
   9647              intr_arr[cnt++] = portmodIntrTypeLinkdown;
   9648         }
   9649 
   9650         if(soc_reg_field_get(unit, XLPORT_INTR_STATUSr, reg_val, MAC_ERRf)) {
   9651              if (cnt >= arr_max_size) {
   9652                   _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   9653              }
   9654              intr_arr[cnt++] = portmodIntrTypeMacErr;
   9655         }
   9656 
   9657         _SOC_IF_ERR_EXIT(xlmac_interrupts_status_get(unit, port, (arr_max_size- cnt), (intr_arr + cnt), &mac_intr_cnt));
   9658         cnt += mac_intr_cnt;
   9659      }
   9660 
   9661     *size = cnt;
   9662 
   9663 exit:
   9664     SOC_FUNC_RETURN;
   9665 }
   9666 
   9667 /*!
   9668  * pm4x10_port_eee_clock_set
   9669  *
   9670  * @brief set EEE Config.
   9671  *
   9672  * @param [in]  unit            - unit id
   9673  * @param [in]  port            - logical port
   9674  * @param [in]  eee             -
   9675  */
   9676 int pm4x10_port_eee_clock_set(int unit, int port, pm_info_t pm_info,
   9677                               const portmod_eee_clock_t* eee_clk)
   9678 {
   9679     int phy_acc;
   9680     SOC_INIT_FUNC_DEFS;
   9681 
   9682     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9683 
   9684     _SOC_IF_ERR_EXIT(WRITE_XLPORT_EEE_CLOCK_GATEr(unit, phy_acc, eee_clk->clock_gate));
   9685     _SOC_IF_ERR_EXIT(WRITE_XLPORT_EEE_CORE0_CLOCK_GATE_COUNTERr(unit, phy_acc, eee_clk->clock_count));
   9686     _SOC_IF_ERR_EXIT(WRITE_XLPORT_EEE_DURATION_TIMER_PULSEr(unit, phy_acc, eee_clk->timer_pulse));
   9687 
   9688 exit:
   9689     SOC_FUNC_RETURN;
   9690 }
   9691 
   9692 
   9693 /*!
   9694  * portmod_port_eee_clock_get
   9695  *
   9696  * @brief set EEE Config.
   9697  *
   9698  * @param [in]  unit            - unit id
   9699  * @param [in]  port            - logical port
   9700  * @param [out]  eee             -
   9701  */
   9702 int pm4x10_port_eee_clock_get (int unit, int port, pm_info_t pm_info,
   9703                                portmod_eee_clock_t* eee_clk)
   9704 {
   9705     int phy_acc;
   9706     SOC_INIT_FUNC_DEFS;
   9707 
   9708     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9709 
   9710     _SOC_IF_ERR_EXIT(READ_XLPORT_EEE_CLOCK_GATEr(unit, phy_acc, &eee_clk->clock_gate));
   9711     _SOC_IF_ERR_EXIT(READ_XLPORT_EEE_CORE0_CLOCK_GATE_COUNTERr(unit, phy_acc, &eee_clk->clock_count));
   9712     _SOC_IF_ERR_EXIT(READ_XLPORT_EEE_DURATION_TIMER_PULSEr(unit, phy_acc, &eee_clk->timer_pulse));
   9713 
   9714 exit:
   9715     SOC_FUNC_RETURN;
   9716 }
   9717 
   9718 int pm4x10_port_failover_mode_set(int unit, int port, pm_info_t pm_info, phymod_failover_mode_t failover)
   9719 {
   9720     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9721     int nof_phys;
   9722     int port_index;
   9723     uint32 bitmap;
   9724 
   9725     SOC_INIT_FUNC_DEFS;
   9726 
   9727     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   9728                                              &bitmap));
   9729 
   9730     if (PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   9731         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   9732                            (_SOC_MSG("phy failover is not supported")));
   9733     }
   9734 
   9735     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9736                                                        phy_access ,(1+MAX_PHYN),
   9737                                                        &nof_phys));
   9738 
   9739     SOC_IF_ERROR_RETURN(portmod_port_phychain_failover_mode_set(unit, phy_access, nof_phys, failover));
   9740 
   9741 exit:
   9742     SOC_FUNC_RETURN;
   9743 }
   9744 
   9745 int pm4x10_port_failover_mode_get(int unit, int port, pm_info_t pm_info, phymod_failover_mode_t* failover)
   9746 {
   9747     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9748     int nof_phys;
   9749     int port_index;
   9750     uint32 bitmap;
   9751 
   9752     SOC_INIT_FUNC_DEFS;
   9753 
   9754     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index,
   9755                                              &bitmap));
   9756 
   9757     if (PM_4x10_INFO(pm_info)->nof_phys[port_index] == 0) {
   9758         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
   9759                            (_SOC_MSG("phy failover is not supported")));
   9760     }
   9761 
   9762     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9763                                                        phy_access ,(1+MAX_PHYN),
   9764                                                        &nof_phys));
   9765 
   9766     SOC_IF_ERROR_RETURN(portmod_port_phychain_failover_mode_get(unit, phy_access, nof_phys, failover));
   9767 
   9768 exit:
   9769     SOC_FUNC_RETURN;
   9770 }
   9771 
   9772 int pm4x10_port_flow_control_set (int unit, int port, pm_info_t pm_info, 
   9773                                   int merge_mode_en, int parallel_fc_en)
   9774 {
   9775     int phy_acc, rv;
   9776     uint32 rval;
   9777 
   9778     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
   9779 
   9780     rv = READ_XLPORT_FLOW_CONTROL_CONFIGr(unit, phy_acc, &rval);
   9781     if (SOC_FAILURE(rv)) return (rv);
   9782 
   9783     soc_reg_field_set(unit, XLPORT_FLOW_CONTROL_CONFIGr, &rval, MERGE_MODE_ENf, merge_mode_en);
   9784     soc_reg_field_set(unit, XLPORT_FLOW_CONTROL_CONFIGr, &rval, PARALLEL_FC_ENf, parallel_fc_en);
   9785 
   9786     return(WRITE_XLPORT_FLOW_CONTROL_CONFIGr(unit, phy_acc, rval));
   9787 }
   9788 
   9789 int pm4x10_port_lane_map_set(int unit, int port, pm_info_t pm_info, uint32 flags, const phymod_lane_map_t* lane_map)
   9790 {
   9791     SOC_INIT_FUNC_DEFS;
   9792 
   9793     PM_4x10_INFO(pm_info)->lane_map = *lane_map;
   9794 
   9795 
   9796     SOC_FUNC_RETURN;
   9797 }
   9798 
   9799 int pm4x10_port_lane_map_get(int unit, int port, pm_info_t pm_info, uint32 flags, phymod_lane_map_t* lane_map)
   9800 {
   9801     SOC_INIT_FUNC_DEFS;
   9802 
   9803     *lane_map = PM_4x10_INFO(pm_info)->lane_map;
   9804 
   9805 
   9806     SOC_FUNC_RETURN;
   9807 }
   9808 
   9809 int pm4x10_xphy_lane_attach_to_pm (int unit, pm_info_t pm_info, int iphy, int phyn, const portmod_xphy_lane_connection_t* lane_conn)
   9810 {   
   9811     portmod_xphy_lane_connection_t *candidate_lane_conn = NULL;
   9812     int lane_index = 0, phy_index = 0;
   9813     int pm_is_active = 0, rv = 0;
   9814     int nof_phys = 0;
   9815     uint32 xphy_id;
   9816     int lane_mask;
   9817     uint32 active_lanes;
   9818     SOC_INIT_FUNC_DEFS;
   9819 
   9820     /* Validate parameters */
   9821     _SOC_IF_ERR_EXIT(portmod_xphy_lane_connection_t_validate(unit,lane_conn));
   9822 
   9823     if (MAX_PHYN <= phyn){
   9824         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid Ext PHY location.")));
   9825     }
   9826     /* Making sure the port macro is not active */
   9827     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active);
   9828     _SOC_IF_ERR_EXIT(rv);
   9829 
   9830     /* Attaching the external phy to the phy chain of the port macro */
   9831 
   9832     /* find lane index corresponding to internal physical port */
   9833     lane_index = 0;
   9834     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy_index) {
   9835         if (phy_index == iphy) {
   9836             break;
   9837         }
   9838         lane_index++;
   9839     }
   9840 
   9841     if (!SOC_WARM_BOOT(unit)) {
   9842         rv = PM4x10_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, lane_conn, phyn-1, lane_index); 
   9843         _SOC_IF_ERR_EXIT(rv);
   9844         candidate_lane_conn = &(PM_4x10_INFO(pm_info)->lane_conn[phyn-1][lane_index]); 
   9845         sal_memcpy(candidate_lane_conn, lane_conn, sizeof(portmod_xphy_lane_connection_t));
   9846 
   9847         xphy_id = candidate_lane_conn->xphy_id;
   9848         lane_mask = candidate_lane_conn->ss_lane_mask;
   9849 
   9850         /*
   9851          * Keeping track of the xphy lane usage.  If the xphy lane is connected
   9852          * it will set the corresponding bit to mark as lane is active.
   9853          */
   9854 
   9855         if ((lane_mask != -1) && (xphy_id != PORTMOD_XPHY_ID_INVALID)) {
   9856             _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_get(unit, xphy_id, &active_lanes));
   9857             active_lanes |= lane_mask;
   9858             _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_set(unit,xphy_id, active_lanes));
   9859         }
   9860 
   9861         PM4x10_PORT_NUM_PHYS_GET(unit, pm_info, &nof_phys, lane_index); 
   9862         if (nof_phys <= phyn) {
   9863             nof_phys = phyn + 1;
   9864             rv = PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, &nof_phys, lane_index);
   9865             _SOC_IF_ERR_EXIT(rv);
   9866             PM_4x10_INFO(pm_info)->nof_phys[lane_index] = phyn+1;
   9867         }
   9868     } 
   9869   
   9870 exit:
   9871    SOC_FUNC_RETURN;
   9872 }
   9873 
   9874 int pm4x10_xphy_lane_detach_from_pm (int unit, pm_info_t pm_info, int iphy, int phyn, portmod_xphy_lane_connection_t* lane_conn)
   9875 {
   9876     portmod_xphy_lane_connection_t *candidate_lane_conn = NULL;
   9877     int lane_index = 0, phy_index = 0;
   9878     int pm_is_active = 0, rv = 0;
   9879     int nof_phys = 0;
   9880     uint32 active_lanes;
   9881     uint32 xphy_id;
   9882     int lane_mask;
   9883     SOC_INIT_FUNC_DEFS;
   9884 
   9885     if (MAX_PHYN <= phyn){
   9886         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid Ext PHY location.")));
   9887     }
   9888     /* Making sure the port macro is not active */
   9889     rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active);
   9890     _SOC_IF_ERR_EXIT(rv);
   9891 
   9892     /* Attaching the external phy to the phy chain of the port macro */
   9893 
   9894     /* find lane index corresponding to internal physical port */
   9895     lane_index = 0;
   9896     PORTMOD_PBMP_ITER(PM_4x10_INFO(pm_info)->phys, phy_index) {
   9897         if (phy_index == iphy) {
   9898             break;
   9899         }
   9900         lane_index++;
   9901     }
   9902  
   9903     if (!SOC_WARM_BOOT(unit)) {
   9904         candidate_lane_conn = &(PM_4x10_INFO(pm_info)->lane_conn[phyn-1][lane_index]);
   9905 
   9906         xphy_id = candidate_lane_conn->xphy_id;
   9907         lane_mask = candidate_lane_conn->ss_lane_mask;
   9908 
   9909         if ((lane_mask != -1) && (xphy_id != PORTMOD_XPHY_ID_INVALID)) {
   9910 
   9911             /*
   9912             * Keeping track of the xphy lane usage.  If the xphy lane is disconnected
   9913             * it will clear the corresponding bit to mark as lane is not active.
   9914             * When none of the lane are active, it clear intialization status,
   9915             * phy_type and probe status.  When it probe again, it will re-initialize
   9916             * this xphy again.
   9917             */
   9918             _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_get(unit, xphy_id, &active_lanes));
   9919             active_lanes &= ~lane_mask;
   9920             _SOC_IF_ERR_EXIT(portmod_xphy_active_lane_set(unit, xphy_id, active_lanes));
   9921 
   9922             if (active_lanes == 0) { /* none of the lanes are active */
   9923                 _SOC_IF_ERR_EXIT(portmod_xphy_core_probed_set(unit, xphy_id, 0));
   9924                 _SOC_IF_ERR_EXIT(portmod_xphy_phy_type_set(unit,xphy_id,phymodDispatchTypeInvalid));
   9925                 _SOC_IF_ERR_EXIT(portmod_xphy_is_initialized_set(unit, xphy_id,0));
   9926             }
   9927         }
   9928 
   9929         portmod_xphy_lane_connection_t_init(unit, candidate_lane_conn);
   9930         rv = PM4x10_PORT_LANE_CONNECTION_DB_SET(unit, pm_info, candidate_lane_conn, phyn-1, lane_index);
   9931         _SOC_IF_ERR_EXIT(rv);
   9932 
   9933         if (phyn > 0) {
   9934             nof_phys = phyn;
   9935             rv = PM4x10_PORT_NUM_PHYS_SET(unit, pm_info, &nof_phys, lane_index);
   9936             _SOC_IF_ERR_EXIT(rv);
   9937             PM_4x10_INFO(pm_info)->nof_phys[lane_index] = nof_phys;
   9938         }
   9939     }
   9940  
   9941 exit:
   9942    SOC_FUNC_RETURN;
   9943 }
   9944 
   9945 int pm4x10_port_control_phy_timesync_set(int unit, int port, pm_info_t pm_info, const portmod_port_control_phy_timesync_t config, uint64 value)
   9946 {
   9947     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9948     int nof_phys;
   9949     SOC_INIT_FUNC_DEFS;
   9950 
   9951     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9952                                                        phy_access ,(1+MAX_PHYN),
   9953                                                        &nof_phys));
   9954 
   9955     SOC_IF_ERROR_RETURN(portmod_port_phychain_control_phy_timesync_set(unit, port, phy_access, nof_phys,
   9956                                                                        config, value));
   9957 
   9958     exit:
   9959     SOC_FUNC_RETURN;
   9960 }
   9961 
   9962 int pm4x10_port_control_phy_timesync_get(int unit, int port, pm_info_t pm_info, const portmod_port_control_phy_timesync_t config, uint64* value)
   9963 {
   9964     phymod_phy_access_t phy_access[1+MAX_PHYN];
   9965     int nof_phys;
   9966     SOC_INIT_FUNC_DEFS;
   9967 
   9968     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
   9969                                                        phy_access ,(1+MAX_PHYN),
   9970                                                        &nof_phys));
   9971 
   9972     SOC_IF_ERROR_RETURN(portmod_port_phychain_control_phy_timesync_get(unit, port, phy_access, nof_phys,
   9973                                                                        config, value));
   9974 
   9975     exit:
   9976     SOC_FUNC_RETURN;
   9977 }
   9978 
   9979 int pm4x10_port_update_dynamic_state(int unit, int port, pm_info_t pm_info, uint32_t port_dynamic_state) {
   9980     
   9981     int rv = 0;
   9982     int port_index;
   9983     uint32_t bitmap;
   9984     phymod_an_mode_type_t an_mode;
   9985     uint32_t an_updated = FALSE, tmp_state;
   9986     SOC_INIT_FUNC_DEFS;
   9987 
   9988 
   9989     rv = _pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap);
   9990     if (SOC_FAILURE(rv)) {
   9991         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Unable to retrieve the port index")));
   9992     }
   9993 
   9994     if (PORTMOD_PORT_IS_AUTONEG_MODE_UPDATED(port_dynamic_state)) {
   9995         rv = PM4x10_PORT_DYNAMIC_STATE_GET(unit, pm_info, &tmp_state,
   9996                                            port_index);
   9997         _SOC_IF_ERR_EXIT(rv);
   9998         /*we need to change the data base An_mode based on the new value */
   9999         switch (port_dynamic_state >> 16 & 0xffff) { 
  10000         case SOC_PHY_CONTROL_AUTONEG_MODE_CL37:
  10001             an_mode = phymod_AN_MODE_CL37;
  10002             an_updated = TRUE;
  10003             break;
  10004         case SOC_PHY_CONTROL_AUTONEG_MODE_CL37_BAM:
  10005             an_mode = phymod_AN_MODE_CL37BAM;
  10006             an_updated = TRUE;
  10007             break;
  10008         case SOC_PHY_CONTROL_AUTONEG_MODE_CL73:
  10009             an_mode = phymod_AN_MODE_CL73;
  10010             an_updated = TRUE;
  10011             break;
  10012         case SOC_PHY_CONTROL_AUTONEG_MODE_CL73_BAM:
  10013             an_mode = phymod_AN_MODE_CL73BAM;
  10014             an_updated = TRUE;
  10015             break;
  10016         default:
  10017             break;
  10018         }
  10019     } else if (PORTMOD_PORT_IS_DEFAULT_TX_PARAMS_UPDATED(port_dynamic_state)) {
  10020         rv = PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info,
  10021                                       port_dynamic_state, port_index);
  10022         _SOC_IF_ERR_EXIT(rv);
  10023     }
  10024     if (an_updated == TRUE) {
  10025         rv = PM4x10_AN_MODE_SET(unit, pm_info, an_mode, port_index);
  10026         _SOC_IF_ERR_EXIT(rv);
  10027         PORTMOD_PORT_AUTONEG_MODE_UPDATED_SET(tmp_state);
  10028         rv = PM4x10_PORT_DYNAMIC_STATE_SET(unit, pm_info, tmp_state,
  10029                                            port_index);
  10030         _SOC_IF_ERR_EXIT(rv);
  10031     }
  10032 
  10033 exit:
  10034     SOC_FUNC_RETURN;
  10035 
  10036 }
  10037 
  10038 int pm4x10_port_phy_op_mode_get(int unit, int port, pm_info_t pm_info, phymod_operation_mode_t* val)
  10039 {
  10040     uint32 bitmap;
  10041     int    port_index, rv = 0, nof_phys = 0;
  10042     phymod_phy_access_t phy_access[1+MAX_PHYN];
  10043     phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer;
  10044     SOC_INIT_FUNC_DEFS;
  10045 
  10046     rv = _pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap);
  10047     if SOC_FAILURE(rv) return (rv);
  10048 
  10049     _SOC_IF_ERR_EXIT
  10050         (portmod_port_chain_phy_access_get(unit, port, pm_info,
  10051                                             phy_access ,(1+MAX_PHYN),
  10052                                             &nof_phys));
  10053     rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, nof_phys, &phy_op_mode);
  10054     if (SOC_SUCCESS(rv)) {
  10055         *val = phy_op_mode;
  10056     } else if (rv == SOC_E_UNAVAIL) {
  10057     rv = PM4x10_PORT_OP_MODE_GET(unit, pm_info, val, port_index);
  10058     }
  10059     _SOC_IF_ERR_EXIT(rv);
  10060 
  10061 exit:
  10062     SOC_FUNC_RETURN;
  10063 
  10064 }
  10065 
  10066 int pm4x10_port_medium_config_set(int unit, int port, pm_info_t pm_info, soc_port_medium_t medium, soc_phy_config_t* config)
  10067 {
  10068     int rv;
  10069     SOC_INIT_FUNC_DEFS;
  10070 
  10071     rv = portmod_port_phychain_medium_config_set(unit, port, medium, config);
  10072     if (SOC_FAILURE(rv)) return (rv);
  10073 
  10074     SOC_FUNC_RETURN;
  10075 }
  10076 
  10077 int pm4x10_port_medium_config_get(int unit, int port, pm_info_t pm_info, soc_port_medium_t medium, soc_phy_config_t* config)
  10078 {
  10079     int rv;
  10080     SOC_INIT_FUNC_DEFS;
  10081 
  10082     rv = portmod_port_phychain_medium_config_get(unit, port, medium, config);
  10083 
  10084     if (SOC_FAILURE(rv)) return (rv);
  10085 
  10086     SOC_FUNC_RETURN;
  10087 }
  10088 
  10089 int pm4x10_port_medium_get(int unit, int port, pm_info_t pm_info, soc_port_medium_t* medium)
  10090 {
  10091     int rv;
  10092     SOC_INIT_FUNC_DEFS;
  10093 
  10094     rv = portmod_port_phychain_medium_get(unit, port, medium);
  10095     if (SOC_FAILURE(rv)) return (rv);
  10096 
  10097     SOC_FUNC_RETURN;
  10098 }
  10099 
  10100 int pm4x10_port_multi_get(int unit, int port, pm_info_t pm_info, portmod_multi_get_t* multi_get)
  10101 {
  10102     phymod_phy_access_t phy_access[1+MAX_PHYN];
  10103     int nof_phys;
  10104     SOC_INIT_FUNC_DEFS;
  10105 
  10106     _SOC_IF_ERR_EXIT
  10107         (portmod_port_chain_phy_access_get(unit, port, pm_info, 
  10108                                            phy_access ,(1+MAX_PHYN),
  10109                                            &nof_phys));
  10110     _SOC_IF_ERR_EXIT
  10111         (portmod_port_phychain_multi_get(unit, port, phy_access, nof_phys, multi_get));
  10112 
  10113 exit:
  10114     SOC_FUNC_RETURN;
  10115 
  10116 }
  10117 
  10118 int pm4x10_port_polarity_set(int unit, int port, pm_info_t pm_info, const phymod_polarity_t* polarity)
  10119 {
  10120     SOC_INIT_FUNC_DEFS;
  10121 
  10122     PM_4x10_INFO(pm_info)->polarity = *polarity;
  10123 
  10124 
  10125     SOC_FUNC_RETURN;
  10126 }
  10127 
  10128 int pm4x10_port_polarity_get(int unit, int port, pm_info_t pm_info, phymod_polarity_t* polarity)
  10129 {
  10130     SOC_INIT_FUNC_DEFS;
  10131 
  10132     *polarity = PM_4x10_INFO(pm_info)->polarity;
  10133 
  10134 
  10135     SOC_FUNC_RETURN;
  10136 }
  10137 
  10138 int pm4x10_pm_is_in_pm12x10(int unit, pm_info_t pm_info, int* in_pm12x10)
  10139 {
  10140     SOC_INIT_FUNC_DEFS;
  10141 
  10142     if (PM_4x10_INFO(pm_info)->in_pm12x10){
  10143         *in_pm12x10 = 1;
  10144     } else {
  10145         *in_pm12x10 = 0;
  10146     }
  10147 
  10148     SOC_FUNC_RETURN;
  10149 
  10150 }
  10151 
  10152 /*
  10153  * This function will be called during speed change or flexport.
  10154  * This function returns pll_div value by looking up the static table.
  10155  * In flexport scenario, this funciton might be called before port is attached. The port number may be invalid(-1).
  10156  * So this function can't access registers by logical port number, or access Warmboot DB.
  10157  */
  10158 int pm4x10_port_pll_div_get(int unit, int port, pm_info_t pm_info,
  10159                             const portmod_port_resources_t* port_resource,
  10160                             uint32_t* pll_div)
  10161 {
  10162     pm_version_t pm_version;
  10163     SOC_INIT_FUNC_DEFS;
  10164 
  10165     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
  10166 
  10167     switch (port_resource->speed){
  10168       case 10:
  10169       case 100:
  10170       case 1000:
  10171       case 2500:
  10172           if (PORTMOD_SERDES_1000X_AT_6250_GET(port_resource->flag)) {
  10173               *pll_div = phymod_TSCE_PLL_DIV40;
  10174           } else if (PORTMOD_SERDES_1000X_AT_12500_GET(port_resource->flag)) {
  10175               *pll_div = phymod_TSCE_PLL_DIV80;
  10176           } else {
  10177               *pll_div = phymod_TSCE_PLL_DIV66;
  10178           }
  10179           break;
  10180       case 5000:
  10181           if (PORTMOD_SERDES_1000X_AT_12500_GET(port_resource->flag)) {
  10182               *pll_div = phymod_TSCE_PLL_DIV80;
  10183           } else {
  10184               if (PORTMOD_PM4x10_IS_GEN2_16nm(pm_version)) {
  10185                   *pll_div = phymod_TSCE_PLL_DIV66;
  10186               } else {
  10187                   *pll_div = phymod_TSCE_PLL_DIV40;
  10188               }
  10189           }
  10190           break;
  10191       case 10000:
  10192           if (port_resource->num_lane == 1){
  10193               *pll_div = phymod_TSCE_PLL_DIV66;
  10194           } else {
  10195               if (PORTMOD_PM4x10_IS_GEN2_16nm(pm_version)) {
  10196                   *pll_div = phymod_TSCE_PLL_DIV80;
  10197               } else {
  10198                   *pll_div = phymod_TSCE_PLL_DIV40;
  10199               }
  10200           }
  10201           break;
  10202       case 105000:
  10203           *pll_div = phymod_TSCE_PLL_DIV42;
  10204           break;
  10205       case 11000:
  10206           if (port_resource->num_lane == 1){
  10207               *pll_div = phymod_TSCE_PLL_DIV70;
  10208           } else {
  10209               *pll_div = phymod_TSCE_PLL_DIV42;
  10210           }
  10211           break;
  10212       case 12000:
  10213           *pll_div = phymod_TSCE_PLL_DIV80;
  10214           break;
  10215       case 13000:
  10216           if (port_resource->num_lane == 2){
  10217               *pll_div = phymod_TSCE_PLL_DIV42;
  10218           } else {
  10219               *pll_div = phymod_TSCE_PLL_DIV52;
  10220           }
  10221           break;
  10222       case 15000:
  10223           *pll_div = phymod_TSCE_PLL_DIV66;
  10224           break;
  10225       case 15700:
  10226           *pll_div = phymod_TSCE_PLL_DIV52;
  10227           break;
  10228       case 16000:
  10229           *pll_div = phymod_TSCE_PLL_DIV64;
  10230           break;
  10231       case 20000:
  10232           if (port_resource->num_lane == 2){
  10233               *pll_div = phymod_TSCE_PLL_DIV66;
  10234           } else {
  10235               if (PORTMOD_PM4x10_IS_GEN2_16nm(pm_version)) {
  10236                   *pll_div = phymod_TSCE_PLL_DIV80;
  10237               } else {
  10238                   *pll_div = phymod_TSCE_PLL_DIV40;
  10239               }
  10240           }
  10241           break;
  10242       case 21000:
  10243           if (port_resource->num_lane == 2){
  10244               *pll_div = phymod_TSCE_PLL_DIV70;
  10245           } else {
  10246               *pll_div = phymod_TSCE_PLL_DIV42;
  10247           }
  10248           break;
  10249       case 25000:
  10250           if (port_resource->num_lane == 2){
  10251               *pll_div = phymod_TSCE_PLL_DIV80;
  10252           } else {
  10253               *pll_div = phymod_TSCE_PLL_DIV42;
  10254           }
  10255           break;
  10256       case 25450:
  10257           *pll_div = phymod_TSCE_PLL_DIV42;
  10258           break;
  10259       case 30000:
  10260       case 32000:
  10261           *pll_div = phymod_TSCE_PLL_DIV52;
  10262           break;
  10263       case 40000:
  10264           *pll_div = phymod_TSCE_PLL_DIV66;
  10265           break;
  10266       case 42000:
  10267           *pll_div = phymod_TSCE_PLL_DIV70;
  10268           break;
  10269       case 48000:
  10270           *pll_div = phymod_TSCE_PLL_DIV80;
  10271           break;
  10272       case 100000:
  10273           *pll_div = phymod_TSCE_PLL_DIV66;
  10274           break;
  10275       case 106000:
  10276       case 107000:
  10277           *pll_div = phymod_TSCE_PLL_DIV70;
  10278           break;
  10279       case 120000:
  10280           *pll_div = phymod_TSCE_PLL_DIV66;
  10281           break;
  10282       case 127000:
  10283           *pll_div = phymod_TSCE_PLL_DIV70;
  10284           break;
  10285       default:
  10286           *pll_div = phymod_TSCE_PLL_DIV66;
  10287           break;
  10288     }
  10289 
  10290 exit:
  10291     SOC_FUNC_RETURN;
  10292 }
  10293 
  10294 #define VCO_6P25G    0x1
  10295 #define VCO_10P3125G 0x2
  10296 #define VCO_10P9375G 0x4
  10297 #define VCO_12P5G    0x8
  10298 #define VCO_6P5625G  0x10
  10299 #define VCO_6P25G_10P3125G    (VCO_6P25G | VCO_10P3125G)
  10300 #define VCO_6P25G_10P9375G    (VCO_6P25G | VCO_10P9375G)
  10301 #define VCO_10P3125G_10P9375G (VCO_10P3125G | VCO_10P9375G)
  10302 #define VCO_6P25G_12P5G       (VCO_6P25G | VCO_12P5G)
  10303 #define VCO_6P25G_6P5625G     (VCO_6P25G | VCO_6P5625G)
  10304 
  10305 STATIC
  10306 int _pm4x10_port_vcobitmap_to_vcos(int unit, pm_info_t pm_info, int vco_bmp, portmod_dual_vcos_t* dual_vco)
  10307 {
  10308     pm_version_t pm_version;
  10309     SOC_INIT_FUNC_DEFS;
  10310 
  10311     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
  10312 
  10313    if (PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
  10314         /* PLL1 always is 6.25G in TSCE_DPLL Gen3 */
  10315         switch (vco_bmp) {
  10316             case VCO_6P25G:
  10317             case VCO_10P3125G:
  10318             case VCO_6P25G_10P3125G:
  10319                 dual_vco->vco_0 = portmodVCO10P3125G;
  10320                 dual_vco->vco_1 = portmodVCO6P25G;
  10321                 break;
  10322             case VCO_10P9375G:
  10323             case VCO_6P25G_10P9375G:
  10324                 dual_vco->vco_0 = portmodVCO10P9375G;
  10325                 dual_vco->vco_1 = portmodVCO6P25G;
  10326                 break;
  10327             case VCO_12P5G:
  10328             case VCO_6P25G_12P5G:
  10329                 dual_vco->vco_0 = portmodVCO12P5G;
  10330                 dual_vco->vco_1 = portmodVCO6P25G;
  10331                 break;
  10332             case VCO_6P5625G:
  10333             case VCO_6P25G_6P5625G:
  10334                 dual_vco->vco_0 = portmodVCO6P5625G;
  10335                 dual_vco->vco_1 = portmodVCO6P25G;
  10336                 break;
  10337             default:
  10338                 LOG_ERROR(BSL_LS_SOC_PORT,
  10339                      (BSL_META_U(unit, "fail to get vcos -- no vcos combination vco_bmp 0x%x\n"), vco_bmp));
  10340                 return SOC_E_PARAM;
  10341          }
  10342     } else {   /* Convert dual vcos for other PM version in future */
  10343         return SOC_E_INTERNAL;
  10344     }
  10345 
  10346 exit:
  10347     SOC_FUNC_RETURN;
  10348 }
  10349 
  10350 STATIC
  10351 int _pm4x10_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)
  10352 {
  10353     int index, port_index;
  10354     int vco_bitmap[4] = {0};
  10355     int vco_bmp = 0;
  10356     int pll_divider_req = 66;
  10357     uint32_t bitmap;
  10358     SOC_INIT_FUNC_DEFS;
  10359 
  10360     /* Get pll_divider_req only when port is valid.
  10361      * That port ID is -1 means that the port is new port in flexport, such as 40G --> 4x10G
  10362      */
  10363     if (port != -1) {
  10364         _SOC_IF_ERR_EXIT(_pm4x10_port_index_get (unit, port, pm_info, &port_index, &bitmap));
  10365         _SOC_IF_ERR_EXIT(PM4x10_PORT_PLL_DIVIDER_REQ_GET(unit, pm_info, &pll_divider_req, port_index));
  10366     }
  10367 
  10368     for (index = 0; index < size; index++) {
  10369         switch (speed_config_list[index].num_lanes) {
  10370             case 1:
  10371                 if (speed_config_list[index].speed == 10 ||
  10372                     speed_config_list[index].speed == 100 ||
  10373                     speed_config_list[index].speed == 1000 ||
  10374                     speed_config_list[index].speed == 5000) {
  10375                     if (pll_divider_req == 40) {
  10376                         vco_bitmap[index] = VCO_6P25G;
  10377                     } else {
  10378                         vco_bitmap[index] = VCO_10P3125G;
  10379                     }
  10380                 } else if (speed_config_list[index].speed ==2500) {
  10381                     vco_bitmap[index] = VCO_6P25G;
  10382                 } else if (speed_config_list[index].speed == 10000) {
  10383                     vco_bitmap[index] = VCO_10P3125G;
  10384                 } else if (speed_config_list[index].speed == 11000) {
  10385                     vco_bitmap[index] = VCO_10P9375G;
  10386                 } else if (speed_config_list[index].speed == 12000) {
  10387                     vco_bitmap[index] = VCO_12P5G;
  10388                 }
  10389                 break;
  10390             case 2:
  10391                 if (speed_config_list[index].speed == 20000) {
  10392                     vco_bitmap[index] = VCO_10P3125G;
  10393                 } else if (speed_config_list[index].speed == 21000) {
  10394                     vco_bitmap[index] = VCO_10P9375G;
  10395                 } else if (speed_config_list[index].speed == 24000) {
  10396                     vco_bitmap[index] = VCO_12P5G;
  10397                 }
  10398                 break;
  10399             case 4:
  10400                 if (speed_config_list[index].speed == 10000) {
  10401                     vco_bitmap[index] = VCO_6P25G;
  10402                 } else if (speed_config_list[index].speed == 20000) {
  10403                     vco_bitmap[index] = VCO_6P25G;
  10404                 } else if (speed_config_list[index].speed == 21000) {
  10405                     vco_bitmap[index] = VCO_6P5625G;
  10406                 } else if (speed_config_list[index].speed == 40000) {
  10407                     vco_bitmap[index] = VCO_10P3125G;
  10408                 } else if (speed_config_list[index].speed == 42000) {
  10409                     vco_bitmap[index] = VCO_10P9375G;
  10410                 } else if (speed_config_list[index].speed == 48000) {
  10411                     vco_bitmap[index] = VCO_12P5G;
  10412                 }
  10413                 break;
  10414             default:
  10415                 LOG_ERROR(BSL_LS_SOC_PORT,
  10416                      (BSL_META_U(unit, "fail to get vcos -- no vco matches lane %d speed %d\n"),
  10417                      speed_config_list[index].num_lanes, speed_config_list[index].speed));
  10418                 return SOC_E_PARAM;
  10419         }
  10420         vco_bmp |= vco_bitmap[index];
  10421     }
  10422 
  10423     _SOC_IF_ERR_EXIT(_pm4x10_port_vcobitmap_to_vcos(unit, pm_info,  vco_bmp, dual_vco));
  10424 
  10425 exit:
  10426     SOC_FUNC_RETURN;
  10427 }
  10428 
  10429 STATIC
  10430 int _pm4x10_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)
  10431 {
  10432     int pll_index;
  10433     portmod_dual_vcos_t dual_vcos;
  10434     uint32_t *vco = (uint32_t *)&dual_vcos;
  10435     uint32_t *div = (uint32_t *)dual_plls;
  10436     SOC_INIT_FUNC_DEFS;
  10437 
  10438     portmod_dual_vcos_t_init(unit, &dual_vcos);
  10439 
  10440     _SOC_IF_ERR_EXIT(_pm4x10_port_vcos_get(unit, port, pm_info, speed_config, size, &dual_vcos));
  10441     /* Only support refclock 156.25M now */
  10442     for (pll_index = 0; pll_index <2; pll_index++) {
  10443         switch (*(vco + pll_index)){
  10444             case portmodVCO10P3125G:
  10445                 *(div + pll_index) = phymod_TSCE_PLL_DIV66;
  10446                 break;
  10447             case portmodVCO10P9375G:
  10448                 *(div + pll_index) = phymod_TSCE_PLL_DIV70;
  10449                 break;
  10450             case portmodVCO12P5G:
  10451                 *(div + pll_index) = phymod_TSCE_PLL_DIV80;
  10452                 break;
  10453             case portmodVCO6P5625G:
  10454                 *(div + pll_index) = phymod_TSCE_PLL_DIV42;
  10455                 break;
  10456             case portmodVCO6P25G:
  10457                 *(div + pll_index) = phymod_TSCE_PLL_DIV40;
  10458                 break;
  10459             default:
  10460                 *(div + pll_index) = phymod_TSCE_PLL_DIV66;
  10461                 break;
  10462         }
  10463     }
  10464 
  10465 exit:
  10466     SOC_FUNC_RETURN;
  10467 }
  10468 
  10469 
  10470 int pm4x10_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)
  10471 {
  10472     pm_version_t pm_version;
  10473     SOC_INIT_FUNC_DEFS;
  10474 
  10475     _SOC_IF_ERR_EXIT(_pm4x10_pm_version_get(unit, pm_info, &pm_version));
  10476     /* Add other dual PLLs PM here*/
  10477     if (!PORTMOD_PM4x10_IS_GEN3_28nm(pm_version)) {
  10478         return SOC_E_UNAVAIL;
  10479     }
  10480 
  10481     if (size == 0) {
  10482         return SOC_E_PARAM;
  10483     }
  10484 
  10485     _SOC_IF_ERR_EXIT(_pm4x10_port_vcos_get(unit, port, pm_info, speed_config_list, size, dual_vco));
  10486 
  10487 exit:
  10488     SOC_FUNC_RETURN;
  10489 }
  10490 
  10491 int pm4x10_port_master_set(int unit, int port, pm_info_t pm_info, int master_mode)
  10492 {
  10493     SOC_INIT_FUNC_DEFS;
  10494 
  10495     _SOC_IF_ERR_EXIT(portmod_port_phychain_master_set(unit, port, pm_info, master_mode));
  10496 
  10497 exit:
  10498     SOC_FUNC_RETURN;
  10499 }
  10500 
  10501 int pm4x10_port_master_get(int unit, int port, pm_info_t pm_info, int* master_mode)
  10502 {
  10503     SOC_INIT_FUNC_DEFS;
  10504 
  10505     _SOC_IF_ERR_EXIT(portmod_port_phychain_master_get(unit, port, pm_info, master_mode));
  10506 
  10507 exit:
  10508     SOC_FUNC_RETURN;
  10509 }
  10510 
  10511 /*
  10512  * Function:
  10513  *      _pm4x10_preemption_rx_frag_size_set
  10514  * Purpose:
  10515  *      This function configures preemption rx fragment size
  10516  *      of final and non-final fragments.
  10517  *
  10518  * Parameters:
  10519  *      unit                -(IN) Device unit number
  10520  *      port                -(IN) logical port
  10521  *      final_frag          -(IN) if set indicates final fragment
  10522  *      value               -(IN) value of fragment size
  10523  */
  10524 STATIC
  10525 int _pm4x10_preemption_rx_frag_size_set(int unit, int port, pm_info_t pm_info,
  10526                                         uint32 frag, uint32 value)
  10527 {
  10528     int phy_acc;
  10529     uint32_t rval;
  10530     soc_field_t field;
  10531     SOC_INIT_FUNC_DEFS;
  10532 
  10533     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  10534 
  10535     _SOC_IF_ERR_EXIT(READ_XLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, &rval));
  10536 
  10537     if (frag == PORTMOD_PREEMPTION_FINAL_FRAG) {
  10538         field = MIN_FINAL_FRAG_SIZEf;
  10539     } else {
  10540         field = MIN_NON_FINAL_FRAG_SIZEf;
  10541     }
  10542 
  10543     soc_reg_field_set(unit, XLPORT_MIB_MIN_FRAG_SIZEr, &rval, field, value);
  10544     _SOC_IF_ERR_EXIT(WRITE_XLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, rval));
  10545 
  10546 exit:
  10547     SOC_FUNC_RETURN;
  10548 
  10549 }
  10550 
  10551 /*
  10552  * Function:
  10553  *      _pm4x10_preemption_rx_frag_size_get
  10554  * Purpose:
  10555  *      This function configures preemption rx fragment size
  10556  *      of final and non-final fragments.
  10557  *
  10558  * Parameters:
  10559  *      unit                -(IN)  Device unit number
  10560  *      port                -(IN)  logical port
  10561  *      final_frag          -(IN)  if set indicates final fragment
  10562  *      value               -(OUT) value of fragment size
  10563  */
  10564 STATIC
  10565 int _pm4x10_preemption_rx_frag_size_get(int unit, int port, pm_info_t pm_info,
  10566                                         uint32 frag, uint32 *value)
  10567 {
  10568     int phy_acc;
  10569     uint32_t rval;
  10570     soc_field_t field;
  10571     SOC_INIT_FUNC_DEFS;
  10572 
  10573     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  10574 
  10575     _SOC_IF_ERR_EXIT(READ_XLPORT_MIB_MIN_FRAG_SIZEr(unit, phy_acc, &rval));
  10576 
  10577     if (frag == PORTMOD_PREEMPTION_FINAL_FRAG) {
  10578         field = MIN_FINAL_FRAG_SIZEf;
  10579     } else {
  10580         field = MIN_NON_FINAL_FRAG_SIZEf;
  10581     }
  10582 
  10583     *value = soc_reg_field_get(unit, XLPORT_MIB_MIN_FRAG_SIZEr, rval, field);
  10584 
  10585 exit:
  10586     SOC_FUNC_RETURN;
  10587 
  10588 }
  10589 
  10590 /*
  10591  * Function:
  10592  *      pm4x10_preemption_control_set
  10593  * Purpose:
  10594  *      This function configures preemption feature parameters
  10595  *      The application layer has to call this function with
  10596  *      associated preemption-controls to configure parameters.
  10597  * Parameters:
  10598  *      unit                -(IN) Device unit number
  10599  *      port                -(IN) logical port
  10600  *      type                -(IN) preemption parameter to be configured
  10601  *      value               -(IN) value
  10602  * Returns:
  10603  *      Status
  10604  */
  10605 int pm4x10_preemption_control_set(int unit, int port, pm_info_t pm_info,
  10606                                   portmod_preemption_control_t type,
  10607                                   uint32 value)
  10608 {
  10609     SOC_INIT_FUNC_DEFS;
  10610 
  10611     switch(type) {
  10612         case  portmodPreemptionControlInvalid:
  10613             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10614               (_SOC_MSG("Invalid preemption control type(%d)"), type));
  10615             break;
  10616         case  portmodPreemptionControlPreemptionSupport:
  10617             /* Enable/disable port preemption capability support */
  10618             _SOC_IF_ERR_EXIT(xlmac_preemption_mode_set(unit, port, value));
  10619             break;
  10620         case  portmodPreemptionControlEnableTx:
  10621             /*
  10622              * Enable/disable port preemption on tx side
  10623              * if verify_enable = 1
  10624              * this function call blocks until, verify operation is complete
  10625              * if verify_enable = 0
  10626              * means static preemption, function call returns immediately
  10627              * after enabling preemption in the hardware in tx direction
  10628              */
  10629             _SOC_IF_ERR_EXIT(xlmac_preemption_tx_enable_set(unit, port, value));
  10630             break;
  10631         case  portmodPreemptionControlVerifyEnable:
  10632             /*
  10633              * Enable/disable verify operation.
  10634              * Before enabling the verify operation on a port,
  10635              * the number of attempts for a veriy operation and
  10636              * the timeout for each verify operation should be configured
  10637              */
  10638             _SOC_IF_ERR_EXIT(
  10639                 xlmac_preemption_verify_enable_set(unit, port, value));
  10640             break;
  10641         case  portmodPreemptionControlVerifyTime:
  10642             /*
  10643              * Configuring the verify timeout is valid only when verify
  10644              * operation is enabled.
  10645              * The timeout here means, if verify operation is not complete
  10646              * success/failure/inprogress after the (timeout + 1) millisecs
  10647              * the MAC sends another verify message to the link partner
  10648              */
  10649             _SOC_IF_ERR_EXIT(
  10650                 xlmac_preemption_verify_time_set(unit, port, value));
  10651             break;
  10652         case  portmodPreemptionControlVerifyAttempts:
  10653             /*
  10654              * Configuring the number of verify attempts is valid only when
  10655              * verify operation is enabled.
  10656              * If verify operation is not complete success/failure/inprogress
  10657              * after the (timeout + 1) millisecs the MAC sends another verify
  10658              * to the link partner. The MAC tries for (num_verify_attempts + 1)
  10659              * to complete the verify operation.
  10660              */
  10661             _SOC_IF_ERR_EXIT(
  10662                 xlmac_preemption_verify_attempts_set(unit, port, value));
  10663             break;
  10664         case  portmodPreemptionControlNonFinalFragSizeRx:
  10665             /* configure non-final rx fragment size */
  10666             _SOC_IF_ERR_EXIT(
  10667                 _pm4x10_preemption_rx_frag_size_set(unit, port, pm_info,
  10668                                       PORTMOD_PREEMPTION_NON_FINAL_FRAG,
  10669                                       value));
  10670             break;
  10671         case  portmodPreemptionControlFinalFragSizeRx:
  10672             /* configure final rx fragment size */
  10673             _SOC_IF_ERR_EXIT(
  10674                 _pm4x10_preemption_rx_frag_size_set(unit, port, pm_info,
  10675                                           PORTMOD_PREEMPTION_FINAL_FRAG,
  10676                                           value));
  10677             break;
  10678         default:
  10679             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10680               (_SOC_MSG("Invalid preemption control type(%d)"), type));
  10681             break;
  10682     }
  10683 
  10684 exit:
  10685     SOC_FUNC_RETURN;
  10686 
  10687 }
  10688 
  10689 /*
  10690  * Function:
  10691  *      pm4x10_preemption_control_get
  10692  * Purpose:
  10693  *      This function gets the value of preemption parameters
  10694  *      configured. The application layer has to call this function with
  10695  *      associated preemption-controls to configure parameters.
  10696  * Parameters:
  10697  *      unit                -(IN) Device unit number
  10698  *      port                -(IN) logical port
  10699  *      type                -(IN) preemption parameter to be configured
  10700  *      value               -(OUT) value returned from hardware
  10701  * Returns:
  10702  *      Status
  10703  */
  10704 int pm4x10_preemption_control_get(int unit, int port, pm_info_t pm_info,
  10705                                   portmod_preemption_control_t type,
  10706                                   uint32 *value)
  10707 {
  10708     SOC_INIT_FUNC_DEFS;
  10709 
  10710     switch(type) {
  10711         case  portmodPreemptionControlInvalid:
  10712             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10713               (_SOC_MSG("Invalid preemption control type(%d)"), type));
  10714             break;
  10715         case  portmodPreemptionControlPreemptionSupport:
  10716             _SOC_IF_ERR_EXIT(xlmac_preemption_mode_get(unit, port, value));
  10717             break;
  10718         case  portmodPreemptionControlEnableTx:
  10719             _SOC_IF_ERR_EXIT(xlmac_preemption_tx_enable_get(unit, port, value));
  10720             break;
  10721         case  portmodPreemptionControlVerifyEnable:
  10722             _SOC_IF_ERR_EXIT(
  10723                 xlmac_preemption_verify_enable_get(unit, port, value));
  10724             break;
  10725         case  portmodPreemptionControlVerifyTime:
  10726             _SOC_IF_ERR_EXIT(
  10727                 xlmac_preemption_verify_time_get(unit, port, value));
  10728             break;
  10729         case  portmodPreemptionControlVerifyAttempts:
  10730             _SOC_IF_ERR_EXIT(
  10731                 xlmac_preemption_verify_attempts_get(unit, port, value));
  10732             break;
  10733         case  portmodPreemptionControlNonFinalFragSizeRx:
  10734             /* get non-final rx fragment size */
  10735             _SOC_IF_ERR_EXIT(
  10736                 _pm4x10_preemption_rx_frag_size_get(unit, port, pm_info,
  10737                                       PORTMOD_PREEMPTION_NON_FINAL_FRAG,
  10738                                       value));
  10739             break;
  10740         case  portmodPreemptionControlFinalFragSizeRx:
  10741             /* get final rx fragment size */
  10742             _SOC_IF_ERR_EXIT(
  10743                 _pm4x10_preemption_rx_frag_size_get(unit, port, pm_info,
  10744                                           PORTMOD_PREEMPTION_FINAL_FRAG,
  10745                                           value));
  10746             break;
  10747         default:
  10748             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10749               (_SOC_MSG("Invalid preemption control type(%d)"), type));
  10750             break;
  10751     }
  10752 
  10753 exit:
  10754     SOC_FUNC_RETURN;
  10755 }
  10756 
  10757 /*!
  10758  * pm4x10_preemption_tx_status_get
  10759  *
  10760  * @brief Get the preemption status on the transmit side Indicates if
  10761  *        preemption on a port is
  10762  *        Inactive: (Verifiy is enabled but its status is either failed
  10763  *                  or not initiated) or (preemption is not enabled)
  10764  *        Verify in progress: Preemption is enabled and Verify is
  10765  *                            enabled and its operation is in progress
  10766  *        Active: Preemption is enabled and ((Verify is enabled and
  10767  *                succeeded) or (Verify is NOT enabled))
  10768  *
  10769  * @param [in]  unit            - unit id
  10770  * @param [in]  port            - logical port
  10771  * @param [out] value           - indicates preemption status in tx direction.
  10772  */
  10773 int pm4x10_preemption_tx_status_get(int unit, int port,
  10774                                     pm_info_t pm_info,
  10775                                     uint32* value)
  10776 {
  10777     return (xlmac_preemption_tx_status_get(unit, port,
  10778                                            XLMAC_PREEMPTION_TX_STATUS,
  10779                                            value));
  10780 }
  10781 
  10782 /*!
  10783  * pm4x10_preemption_verify_status_get
  10784  *
  10785  * @brief Get the preemption verify status.
  10786  *        This function gets verify operation status or verify count
  10787  *        status based on the verify status type argument.
  10788  *
  10789  * @param [in]  unit            - unit id
  10790  * @param [in]  port            - logical port
  10791  * @param [in]  type            - portmod_preemption_verify_status_type_t
  10792  * @param [out] value           - indicates preemption verify op status
  10793  */
  10794 int pm4x10_preemption_verify_status_get(int unit, int port,
  10795                                  pm_info_t pm_info,
  10796                                  portmod_preemption_verify_status_type_t type,
  10797                                  uint32* value)
  10798 {
  10799     SOC_INIT_FUNC_DEFS;
  10800 
  10801     switch (type) {
  10802         case portmodPreemptionVerifyStatus:
  10803             _SOC_IF_ERR_EXIT(xlmac_preemption_tx_status_get(unit, port,
  10804                                        XLMAC_PREEMPTION_VERIFY_STATUS,
  10805                                        value));
  10806             break;
  10807         case portmodPreemptionVerifyCountStatus:
  10808             _SOC_IF_ERR_EXIT(xlmac_preemption_tx_status_get(unit, port,
  10809                                   XLMAC_PREEMPTION_VERIFY_CNT_STATUS,
  10810                                   value));
  10811             break;
  10812         default:
  10813             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10814               (_SOC_MSG("Invalid verify status type(%d)"), type));
  10815             break;
  10816     }
  10817 exit:
  10818     SOC_FUNC_RETURN;
  10819 }
  10820 int pm4x10_port_lane_count_get (int unit, int port, pm_info_t pm_info, int line_side, int* num_lanes)
  10821 {
  10822     portmod_access_get_params_t params;
  10823     phymod_phy_access_t phy_access;
  10824     int nof_phys;
  10825     int is_outer_most = 0;
  10826     SOC_INIT_FUNC_DEFS;
  10827 
  10828     /* coverity[check_return] */
  10829     portmod_access_get_params_t_init(unit, &params);
  10830 
  10831     if(line_side){
  10832         params.sys_side =  PORTMOD_SIDE_LINE;
  10833     } else {
  10834         params.sys_side =  PORTMOD_SIDE_SYSTEM;
  10835     }
  10836 
  10837     _SOC_IF_ERR_EXIT(pm4x10_port_phy_lane_access_get(unit, port, pm_info,
  10838                                                      &params, 1 , &phy_access,
  10839                                                      &nof_phys, &is_outer_most));
  10840 
  10841     *num_lanes = 0;
  10842     PORTMOD_BIT_COUNT(phy_access.access.lane_mask,*num_lanes);
  10843 
  10844 exit:
  10845     SOC_FUNC_RETURN;
  10846 }
  10847 
  10848 /*!
  10849  * portmod_preemption_force_rx_eop_mode_set
  10850  *
  10851  * @brief Set preemption forced rx lost eop(end of packet) sequence mode
  10852  * setting. The rx lost eop sequence can be either software or hardware
  10853  * enforced.
  10854  * If HW based rx lost eop is enabled, link down or rx disable even
  10855  * forces rx_lost_eop sequence after some internal delay if preempt
  10856  * packet EOP was not sent.
  10857  * If Sw based rx lost eop is enabled,  the application rx eop sequence
  10858  * When SW rx lost EOP is enabled(done by application layer), rising
  10859  * edge MAC forces rx_lost_eop sequence after some internal delay if
  10860  * preempt packet EOP was not sent.
  10861  *
  10862  * @param [in]  unit            - unit id
  10863  * @param [in]  port            - logical port
  10864  * @param [in]  type            - portmod_preemption_force_rx_eop_mode_t
  10865  * @param [in]  value           - enable/disable
  10866  */
  10867 int pm4x10_preemption_force_rx_eop_mode_set(int unit, int port,
  10868                               pm_info_t pm_info,
  10869                               portmod_preemption_force_rx_eop_mode_t type,
  10870                               uint32 value)
  10871 {
  10872     SOC_INIT_FUNC_DEFS;
  10873 
  10874     switch (type) {
  10875         case portmodPreemptionForceSwRxEop:
  10876             _SOC_IF_ERR_EXIT(xlmac_preemption_force_rx_lost_eop_set(unit, port,
  10877                                               XLMAC_PREEMPTION_FORCE_SW_RX_EOP,
  10878                                               value));
  10879             break;
  10880         case portmodPreemptionForceAutoHwEop:
  10881             _SOC_IF_ERR_EXIT(xlmac_preemption_force_rx_lost_eop_set(unit, port,
  10882                                          XLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP,
  10883                                          value));
  10884             break;
  10885         default:
  10886             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10887               (_SOC_MSG("Invalid Force RX lost EOP type(%d)"), type));
  10888             break;
  10889     }
  10890 
  10891 exit:
  10892     SOC_FUNC_RETURN;
  10893 }
  10894 
  10895 /*!
  10896  * pm4x10_preemption_force_rx_eop_mode_get
  10897  *
  10898  * @brief Get preemption forced rx lost eop(end of packet) sequence mode
  10899  * setting. The rx lost eop sequence can be either software or hardware
  10900  * enforced.
  10901  * This functin returns the rx lost eop setting based on the type
  10902  * of lost eop is enforced.
  10903  *
  10904  *
  10905  * @param [in]  unit            - unit id
  10906  * @param [in]  port            - logical port
  10907  * @param [in]  type            - portmod_preemption_force_rx_eop_mode_t
  10908  * @param [in]  value           - enable/disable
  10909  */
  10910 int pm4x10_preemption_force_rx_eop_mode_get(int unit, int port,
  10911                                  pm_info_t pm_info,
  10912                                  portmod_preemption_force_rx_eop_mode_t type,
  10913                                  uint32 *value)
  10914 {
  10915     SOC_INIT_FUNC_DEFS;
  10916 
  10917     switch (type) {
  10918         case portmodPreemptionForceSwRxEop:
  10919             _SOC_IF_ERR_EXIT(xlmac_preemption_force_rx_lost_eop_get(unit, port,
  10920                                               XLMAC_PREEMPTION_FORCE_SW_RX_EOP,
  10921                                               value));
  10922             break;
  10923         case portmodPreemptionForceAutoHwEop:
  10924             _SOC_IF_ERR_EXIT(xlmac_preemption_force_rx_lost_eop_get(unit, port,
  10925                                          XLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP,
  10926                                          value));
  10927             break;
  10928         default:
  10929             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
  10930               (_SOC_MSG("Invalid Force RX lost EOP type(%d)"), type));
  10931             break;
  10932     }
  10933 
  10934 exit:
  10935     SOC_FUNC_RETURN;
  10936 }
  10937 
  10938 /*!
  10939  * pm4x10_preemption_rx_timeout_set
  10940  *
  10941  * @brief Set specified preemption rx timeout and timeout count.
  10942  * This function should only be called during device init.
  10943  * There are 2 rx parameters rx timeout enable, rx timeout value in microsec
  10944  * that can be configured using this function.
  10945  * If set, enables TIMEOUT mechanism for Rx preempt traffic.
  10946  * Timeout value in microsec, this configuration indicates link idle
  10947  * time(in microsec) after which Rx timeout will force rx_lost_eop sequence
  10948  * if preempt packet EOP was not sent.
  10949  *
  10950  * @param [in]  unit            - unit id
  10951  * @param [in]  port            - logical port
  10952  * @param [in]  enable          - enables timeout for rx preempt traffic
  10953  * @param [in]  timeout_cnt     - timeout in microsecs
  10954  */
  10955 int pm4x10_preemption_rx_timeout_set(int unit, int port, pm_info_t pm_info,
  10956                                      uint32 enable, uint32 timeout_cnt)
  10957 {
  10958     return (xlmac_preemption_rx_timeout_info_set(unit, port, enable,
  10959                                                  timeout_cnt));
  10960 }
  10961 
  10962 /*!
  10963  * pm4x10_preemption_rx_timeout_set
  10964  *
  10965  * @brief Get specified preemption rx timeout and timeout count.
  10966  *
  10967  * @param [in]  unit            - unit id
  10968  * @param [in]  port            - logical port
  10969  * @param [in]  enable          - enables timeout for rx preempt traffic
  10970  * @param [out] timeout_cnt     - timeout in millisec
  10971  */
  10972 int pm4x10_preemption_rx_timeout_get(int unit, int port, pm_info_t pm_info,
  10973                                      uint32 *enable, uint32 *timeout_cnt)
  10974 {
  10975     return (xlmac_preemption_rx_timeout_info_get(unit, port, enable,
  10976                                                  timeout_cnt));
  10977 }
  10978 
  10979 STATIC
  10980 int _pm4x10_phy_timesync_tx_info_get(int unit, int port, pm_info_t pm_info, portmod_fifo_status_t* tx_info)
  10981 {
  10982     phymod_phy_access_t phy_access[1+MAX_PHYN];
  10983     int nof_phys;
  10984     phymod_ts_fifo_status_t phy_ts_tx_info;
  10985     SOC_INIT_FUNC_DEFS;
  10986 
  10987     _SOC_IF_ERR_EXIT(phymod_ts_fifo_status_t_init(&phy_ts_tx_info));
  10988 
  10989     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
  10990                                                        phy_access ,(1+MAX_PHYN),
  10991                                                        &nof_phys));
  10992     _SOC_IF_ERR_EXIT(portmod_port_phychain_timesync_tx_info_get(unit, port, phy_access,
  10993                                                                   nof_phys, &phy_ts_tx_info));
  10994 
  10995     tx_info->timestamps_in_fifo = phy_ts_tx_info.ts_in_fifo_lo;
  10996     tx_info->timestamps_in_fifo_hi = phy_ts_tx_info.ts_in_fifo_hi;
  10997     tx_info->sequence_id = phy_ts_tx_info.ts_seq_id;
  10998     tx_info->timestamp_sub_nanosec = phy_ts_tx_info.ts_sub_nanosec;
  10999 
  11000 exit:
  11001     SOC_FUNC_RETURN;
  11002 }
  11003 
  11004 /*
  11005  * pm4x10_port_timesync_tx_info_get
  11006  *
  11007  * @brief get port timestamps in fifo
  11008  *
  11009  * @param [in]  unit            - unit id
  11010  * @param [in]  port            - logical port
  11011  * @param [inout]  tx_info         - timestamp and seq id form fifo
  11012  */
  11013 
  11014 int pm4x10_port_timesync_tx_info_get(int unit, int port, pm_info_t pm_info, portmod_fifo_status_t* tx_info)
  11015 {
  11016     int phy_acc, mac_ts_disable;
  11017     uint32 reg_val;
  11018     SOC_INIT_FUNC_DEFS;
  11019 
  11020     mac_ts_disable = 0;
  11021 
  11022     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11023     if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
  11024         _SOC_IF_ERR_EXIT(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
  11025         mac_ts_disable = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr, reg_val, XLMAC_TS_DISABLEf);
  11026     }
  11027 
  11028    /*
  11029     * 1 = disable MAC timestamp, use TSC for timestamp.
  11030     * 0 = legacy mode, use MAC for timestamp.
  11031     */
  11032     if (mac_ts_disable) {
  11033         _SOC_IF_ERR_EXIT(_pm4x10_phy_timesync_tx_info_get(unit, port, pm_info, tx_info));
  11034     } else {
  11035         _SOC_IF_ERR_EXIT(xlmac_timesync_tx_info_get(unit, port, tx_info));
  11036     }
  11037 
  11038 exit:
  11039     SOC_FUNC_RETURN;
  11040 }
  11041 
  11042 int pm4x10_port_lane_mask_get (int unit, int port, pm_info_t pm_info, 
  11043         const portmod_access_get_params_t *params, 
  11044         int* lane_mask, int *xphy_id)
  11045 {
  11046     phymod_phy_access_t phy_access;
  11047     portmod_access_get_params_t tmp_params;
  11048     int nof_phys;
  11049     int is_outer_most = 0;
  11050     SOC_INIT_FUNC_DEFS;
  11051 
  11052     /* coverity[check_return] */
  11053     portmod_access_get_params_t_init(unit, &tmp_params);
  11054     sal_memcpy(&tmp_params, params, 
  11055                 sizeof(portmod_access_get_params_t));
  11056 
  11057     tmp_params.lane = -1;
  11058 
  11059     _SOC_IF_ERR_EXIT(pm4x10_port_phy_lane_access_get(unit, port, pm_info,
  11060                                                      &tmp_params, 1 , &phy_access,
  11061                                                      &nof_phys, &is_outer_most));
  11062 
  11063     *lane_mask = phy_access.access.lane_mask;
  11064 
  11065     if ( tmp_params.phyn > 0 ) { 
  11066         *xphy_id = PM_4x10_INFO(pm_info)->lane_conn[0][0].xphy_id;
  11067     } else {
  11068         *xphy_id = PORTMOD_XPHY_ID_INVALID; 
  11069     }
  11070 
  11071 exit:
  11072     SOC_FUNC_RETURN;
  11073 }
  11074 
  11075 int pm4x10_port_mac_timestamp_enable_set(int unit, int port, pm_info_t pm_info, int enable)
  11076 {
  11077     int phy_acc;
  11078     uint32 reg_val;
  11079 
  11080     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11081     if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
  11082         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
  11083         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &reg_val,
  11084                                 XLMAC_TS_DISABLEf, (enable) ? 0 : 1);
  11085         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, phy_acc, reg_val));
  11086     } else {
  11087         return SOC_E_UNAVAIL;
  11088     }
  11089 
  11090     if (!enable) {
  11091         /* Disable XLMAC byte_adjust if MAC timestamp is disabled.
  11092          * Otherwise, it will affect the timestamp value of PHY timestamping.
  11093          */
  11094         SOC_IF_ERROR_RETURN
  11095             (xlmac_timestamp_byte_adjust_set(unit,
  11096                                              port,
  11097                                              XLMAC_TIMESTAMP_BYTE_ADJUST_CLEAR,
  11098                                              0));
  11099     }
  11100 
  11101     return (SOC_E_NONE);
  11102 }
  11103 
  11104 int pm4x10_port_mac_timestamp_enable_get(int unit, int port, pm_info_t pm_info, int* enable)
  11105 {
  11106     int phy_acc, tmp;
  11107     uint32 reg_val;
  11108 
  11109     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11110     if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
  11111         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, phy_acc, &reg_val));
  11112         tmp = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr, reg_val, XLMAC_TS_DISABLEf);
  11113     } else {
  11114         return SOC_E_UNAVAIL;
  11115     }
  11116 
  11117     if (tmp) {
  11118         *enable = FALSE;
  11119     } else {
  11120         *enable = TRUE;
  11121     }
  11122 
  11123     return (SOC_E_NONE);
  11124 }
  11125 
  11126 /*
  11127  *Function:
  11128  *  _pm4x10_txpi_lane_select_set
  11129  *
  11130  *Purpose:
  11131  *  Set Portmacro TXPI lane select
  11132  *  Defaults to using TXPI for it's own lane
  11133  *  This is a core level API
  11134 */
  11135 STATIC
  11136 int _pm4x10_txpi_lane_select_set(int unit, int port, pm_info_t pm_info, uint32_t *lane_select)
  11137 {
  11138     int phy_acc;
  11139     uint32 reg_val = 0;
  11140     SOC_INIT_FUNC_DEFS;
  11141 
  11142     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11143 
  11144     soc_reg_field_set(unit, XLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_0f, lane_select[0]);
  11145     soc_reg_field_set(unit, XLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_1f, lane_select[1]);
  11146     soc_reg_field_set(unit, XLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_2f, lane_select[2]);
  11147     soc_reg_field_set(unit, XLPORT_TXPI_LANE_SELECTIONr, &reg_val, TXPI_LANE_SELECTION_3f, lane_select[3]);
  11148     _SOC_IF_ERR_EXIT(WRITE_XLPORT_TXPI_LANE_SELECTIONr(unit, phy_acc, reg_val));
  11149 
  11150 exit:
  11151     SOC_FUNC_RETURN;
  11152 }
  11153 
  11154 /*
  11155  *Function:
  11156  *  _pm4x10_port_phy_txpi_mode_set
  11157  *
  11158  *Purpose:
  11159  *  Set PMD TXPI mode: normal or external PD
  11160  *  This is a port level API
  11161 */
  11162 STATIC
  11163 int _pm4x10_port_phy_txpi_mode_set(int unit, int port, pm_info_t pm_info, uint32 mode)
  11164 {
  11165     phymod_phy_access_t phy_access[1+MAX_PHYN];
  11166     int nof_phys;
  11167     phymod_txpi_config_t config;
  11168     SOC_INIT_FUNC_DEFS;
  11169 
  11170     config.enable = mode ? 1: 0;
  11171     config.mode   = mode;
  11172 
  11173     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
  11174                                                        phy_access ,(1+MAX_PHYN),
  11175                                                        &nof_phys));
  11176     SOC_IF_ERROR_RETURN(portmod_port_phychain_txpi_config_set(unit, phy_access, nof_phys, &config));
  11177 
  11178 exit:
  11179     SOC_FUNC_RETURN;
  11180 }
  11181 
  11182 /*
  11183  *Function:
  11184  *  pm4x10_port_txpi_override_set
  11185  *
  11186  *Purpose:
  11187  *  Override Portmacro TXPI SDM value
  11188  *  Defaults to using value from CMIC
  11189  *  This is a port level API
  11190 */
  11191 int pm4x10_port_txpi_override_set (int unit, int port, pm_info_t pm_info, const portmod_txpi_override_t *override)
  11192 {
  11193     int phy_acc;
  11194     uint32 reg_val_en, bitmap;
  11195     int i, first_index;
  11196     int64 reg_value;
  11197 
  11198     soc_field_t field[MAX_PORTS_PER_PM4X10] = {TXPI_CSR_OVER_EN_0f, TXPI_CSR_OVER_EN_1f, TXPI_CSR_OVER_EN_2f, TXPI_CSR_OVER_EN_3f};
  11199     soc_reg_t over_reg_low[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_CSR_OVER_VAL_0_LOWr, XLPORT_TXPI_CSR_OVER_VAL_1_LOWr, 
  11200                                                     XLPORT_TXPI_CSR_OVER_VAL_2_LOWr, XLPORT_TXPI_CSR_OVER_VAL_3_LOWr};
  11201     soc_reg_t over_reg_high[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_CSR_OVER_VAL_0_HIGHr, XLPORT_TXPI_CSR_OVER_VAL_1_HIGHr, 
  11202                                                     XLPORT_TXPI_CSR_OVER_VAL_2_HIGHr, XLPORT_TXPI_CSR_OVER_VAL_3_HIGHr};
  11203     SOC_INIT_FUNC_DEFS;
  11204 
  11205     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11206     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &first_index, &bitmap));
  11207 
  11208     /* Enable TXPI DSM override */
  11209     _SOC_IF_ERR_EXIT(READ_XLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, &reg_val_en));
  11210     for (i = 0; i < MAX_PORTS_PER_PM4X10; i++) {
  11211         if (bitmap & (0x1 << i)) {
  11212             soc_reg_field_set(unit, XLPORT_TXPI_CSR_OVER_ENr, &reg_val_en, field[i], override->enable ? TRUE : FALSE);
  11213         }
  11214     }
  11215     _SOC_IF_ERR_EXIT(WRITE_XLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, reg_val_en));
  11216 
  11217     /* Write TXPI DSM override value. Low 32 bits must be wroten before high regist
  11218          *reg_value = txpi_dsm_value_1ppm * override->value;
  11219          */
  11220         COMPILER_64_SET(reg_value, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
  11221     COMPILER_64_UMUL_32(reg_value, override->value);
  11222 
  11223         for (i = 0; i < MAX_PORTS_PER_PM4X10; i++) {
  11224             if (bitmap & (0x1 << i)) {
  11225             soc_reg32_set(unit, over_reg_low[i], phy_acc, 0, override->enable ? COMPILER_64_LO(reg_value) : 0);
  11226             soc_reg32_set(unit, over_reg_high[i], phy_acc, 0, override->enable ? (COMPILER_64_HI(reg_value) & 0xffff) : 0);
  11227         }
  11228     }
  11229 
  11230 exit:
  11231     SOC_FUNC_RETURN;
  11232 }
  11233 
  11234 /*
  11235  *Function:
  11236  *  pm4x10_port_txpi_override_get
  11237  *
  11238  *Purpose:
  11239  *  Get Portmacro TXPI SDM override status and value
  11240  *  Defaults to using value from CMIC
  11241  *  This is a port level API
  11242 */
  11243 int pm4x10_port_txpi_override_get (int unit, int port, pm_info_t pm_info, portmod_txpi_override_t *override)
  11244 {
  11245     int phy_acc;
  11246     uint32 reg_val_en, bitmap;
  11247     int first_index;
  11248     uint32 reg_value_lo, reg_value_hi;
  11249     int64 tmp_reg_val64, txpi_dsm_value_1ppm;
  11250 
  11251     soc_field_t field[MAX_PORTS_PER_PM4X10] = {TXPI_CSR_OVER_EN_0f, TXPI_CSR_OVER_EN_1f, TXPI_CSR_OVER_EN_2f, TXPI_CSR_OVER_EN_3f};
  11252     soc_reg_t over_reg_low[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_CSR_OVER_VAL_0_LOWr, XLPORT_TXPI_CSR_OVER_VAL_1_LOWr, 
  11253                                                     XLPORT_TXPI_CSR_OVER_VAL_2_LOWr, XLPORT_TXPI_CSR_OVER_VAL_3_LOWr};
  11254     soc_reg_t over_reg_high[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_CSR_OVER_VAL_0_HIGHr, XLPORT_TXPI_CSR_OVER_VAL_1_HIGHr, 
  11255                                                     XLPORT_TXPI_CSR_OVER_VAL_2_HIGHr, XLPORT_TXPI_CSR_OVER_VAL_3_HIGHr};
  11256     SOC_INIT_FUNC_DEFS;
  11257 
  11258     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11259      _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &first_index, &bitmap));
  11260 
  11261     /*Get enable status of TXPI DSM override */
  11262     _SOC_IF_ERR_EXIT(READ_XLPORT_TXPI_CSR_OVER_ENr(unit, phy_acc, &reg_val_en));
  11263     override->enable = soc_reg_field_get(unit, XLPORT_TXPI_CSR_OVER_ENr, reg_val_en, field[first_index]);
  11264 
  11265     /* Get TXPI DSM override value */
  11266     if (override->enable == TRUE) {
  11267         /*  The LOW register should be read first before reading from the HIGH register. */
  11268         _SOC_IF_ERR_EXIT(soc_reg32_get(unit, over_reg_low[first_index],
  11269                                        phy_acc, 0, &reg_value_lo));
  11270         _SOC_IF_ERR_EXIT(soc_reg32_get(unit, over_reg_high[first_index],
  11271                                        phy_acc, 0, &reg_value_hi));
  11272         /*
  11273          * bit47 : 0 -- positive; 1 -- negative.
  11274          * If it is negative, the high 16 bits must be filled with 1.
  11275          */
  11276         reg_value_hi = (reg_value_hi & 0x8000) ? (reg_value_hi | 0xffff0000) : (reg_value_hi & 0xffff);
  11277         
  11278         /*
  11279          *Use COMPILER_64_XXX macros to put together 64 bit variables txpi_dsm_value_1ppm and tmp_reg_val64
  11280          *and then generate the override->value
  11281          */
  11282         COMPILER_64_SET(txpi_dsm_value_1ppm, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
  11283         COMPILER_64_SET(tmp_reg_val64, reg_value_hi, reg_value_lo);
  11284         COMPILER_64_UDIV_64(tmp_reg_val64,txpi_dsm_value_1ppm);
  11285 
  11286         COMPILER_64_TO_32_LO(override->value, tmp_reg_val64);
  11287     } else {
  11288         override->value = 0;
  11289     }
  11290 
  11291 exit:
  11292     SOC_FUNC_RETURN;
  11293 }
  11294 
  11295 /*
  11296  *Function:
  11297  *  pm4x10_port_txpi_sdm_data_get
  11298  *
  11299  *Purpose:
  11300  *  Get Portmacro TXPI SDM value of resolution
  11301  *  This is a port level API
  11302 */
  11303 int pm4x10_port_txpi_sdm_data_get(int unit, int port, pm_info_t pm_info, int *value)
  11304 
  11305 {
  11306     int phy_acc;
  11307     uint32 bitmap;
  11308     int first_index;
  11309     uint32 reg_value_lo, reg_value_hi;
  11310     int64 tmp_reg_val64, txpi_dsm_value_1ppm;
  11311 
  11312     soc_reg_t data_reg_low[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_DATA_OUT_STS_0_LOWr, XLPORT_TXPI_DATA_OUT_STS_1_LOWr, 
  11313                                                     XLPORT_TXPI_DATA_OUT_STS_2_LOWr, XLPORT_TXPI_DATA_OUT_STS_3_LOWr};
  11314     soc_reg_t data_reg_high[MAX_PORTS_PER_PM4X10] = {XLPORT_TXPI_DATA_OUT_STS_0_HIGHr, XLPORT_TXPI_DATA_OUT_STS_1_HIGHr, 
  11315                                                     XLPORT_TXPI_DATA_OUT_STS_2_HIGHr, XLPORT_TXPI_DATA_OUT_STS_3_HIGHr};
  11316     SOC_INIT_FUNC_DEFS;
  11317 
  11318     PM4x10_PHY_ACCESS_GET(unit, port, pm_info, phy_acc);
  11319     _SOC_IF_ERR_EXIT(_pm4x10_port_index_get(unit, port, pm_info, &first_index, &bitmap));
  11320 
  11321     /* get the first sub-port if the port is dual-lane or quad-lane mode.
  11322      * The LOW register should be read first before reading from the HIGH register.
  11323      */
  11324     _SOC_IF_ERR_EXIT(soc_reg32_get(unit, data_reg_low[first_index],
  11325                                    phy_acc, 0, &reg_value_lo));
  11326     _SOC_IF_ERR_EXIT(soc_reg32_get(unit, data_reg_high[first_index],
  11327                                    phy_acc, 0, &reg_value_hi));
  11328     /*
  11329      * bit47 : 0 -- positive; 1 -- negative.
  11330      * If it is negative, the high 16 bits must be filled with 1.
  11331      */
  11332     reg_value_hi = (reg_value_hi & 0x8000) ? (reg_value_hi | 0xffff0000) : (reg_value_hi & 0xffff);
  11333 
  11334     /*
  11335      *Use COMPILER_64_XXX macros to put together 64 bit variables txpi_dsm_value_1ppm and tmp_reg_val64
  11336      *and then generate the override->value
  11337      */
  11338     COMPILER_64_SET(txpi_dsm_value_1ppm, TXPI_DSM_VALUE_1PPM_HI, TXPI_DSM_VALUE_1PPM_LO);
  11339     COMPILER_64_SET(tmp_reg_val64, reg_value_hi, reg_value_lo);
  11340     COMPILER_64_UDIV_64(tmp_reg_val64,txpi_dsm_value_1ppm);
  11341 
  11342     COMPILER_64_TO_32_LO(*value, tmp_reg_val64);
  11343 
  11344 exit:
  11345     SOC_FUNC_RETURN;
  11346 }
  11347 
  11348 
  11349 int pm4x10_port_synce_clk_ctrl_set(int unit, int port, pm_info_t pm_info,
  11350                                    const portmod_port_synce_clk_ctrl_t* cfg)
  11351 {
  11352     phymod_synce_clk_ctrl_t phy_synce_cfg;
  11353     phymod_phy_access_t phy_access[1+MAX_PHYN];
  11354     int nof_phys;
  11355     SOC_INIT_FUNC_DEFS;
  11356 
  11357     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
  11358                                                        phy_access ,(1+MAX_PHYN),
  11359                                                        &nof_phys));
  11360 
  11361     phymod_synce_clk_ctrl_t_init(&phy_synce_cfg);
  11362     phy_synce_cfg.stg0_mode = cfg->stg0_mode;
  11363     phy_synce_cfg.stg1_mode = cfg->stg1_mode;
  11364     phy_synce_cfg.sdm_val = cfg->sdm_val;
  11365 
  11366     _SOC_IF_ERR_EXIT(phymod_phy_synce_clk_ctrl_set(&phy_access[0],
  11367                                                    phy_synce_cfg));
  11368 
  11369 exit:
  11370     SOC_FUNC_RETURN;
  11371 }
  11372 
  11373 int pm4x10_port_synce_clk_ctrl_get(int unit, int port, pm_info_t pm_info,
  11374                                    portmod_port_synce_clk_ctrl_t* cfg)
  11375 {
  11376     phymod_synce_clk_ctrl_t phy_synce_cfg;
  11377     phymod_phy_access_t phy_access[1+MAX_PHYN];
  11378     int nof_phys;
  11379     SOC_INIT_FUNC_DEFS;
  11380 
  11381     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info,
  11382                                                        phy_access ,(1+MAX_PHYN),
  11383                                                        &nof_phys));
  11384 
  11385     phymod_synce_clk_ctrl_t_init(&phy_synce_cfg);
  11386 
  11387     _SOC_IF_ERR_EXIT(phymod_phy_synce_clk_ctrl_get(&phy_access[0],
  11388                                                     &phy_synce_cfg));
  11389 
  11390     cfg->stg0_mode = phy_synce_cfg.stg0_mode;
  11391     cfg->stg1_mode = phy_synce_cfg.stg1_mode;
  11392     cfg->sdm_val = phy_synce_cfg.sdm_val;
  11393 
  11394 exit:
  11395     SOC_FUNC_RETURN;
  11396 }
  11397 
  11398 #endif /* PORTMOD_PM4X10_SUPPORT */
  11399 
  11400 #undef _ERR_MSG_MODULE_NAME
  11401