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

portmod_common.c (128049B)


      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 #include <soc/drv.h>
     10 #include <soc/portmod/portmod.h>
     11 #include <soc/portmod/portmod_internal.h>
     12 #include <soc/portmod/portmod_common.h>
     13 #include <soc/portmod/portmod_system.h>
     14 #include <soc/portmod/portmod_chain.h>
     15 #include <soc/portmod/portmod_legacy_phy.h>
     16 #include <soc/phy/phymod_port_control.h>
     17 
     18 #ifdef CRASH_RECOVERY_SUPPORT
     19 #include <soc/hwstate/hw_log.h>
     20 #include <soc/dcmn/dcmn_crash_recovery.h>
     21 #endif /* CRASH_RECOVERY_SUPPORT */
     22 
     23 #ifdef _ERR_MSG_MODULE_NAME 
     24 #error "_ERR_MSG_MODULE_NAME redefined" 
     25 #endif
     26 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     27 
     28 
     29 #define PORT_MAX_PHY_ACCESS_STRUCTURES (6)
     30 #define PM_MDIO_BUS_COUNT (8)
     31 
     32 #define MAC_WAN_MODE_THROTTLE_10G_TO_5G   256
     33 #define MAC_WAN_MODE_THROTTLE_10G_TO_2P5G 257
     34 
     35 #include <soc/portmod/portmod_dispatch.h>
     36 
     37 STATIC int _portmod_common_ext_phy_addr_get(int unit, soc_port_t port, uint32 *xphy_id);
     38 
     39 int
     40 portmod_common_phy_prbs_config_set(int unit, int port, pm_info_t pm_info, int flags, const phymod_prbs_t* config)
     41 {
     42     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
     43     int chain_length = 0;
     44 
     45 
     46     SOC_INIT_FUNC_DEFS;
     47 
     48     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
     49                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
     50                                                         &chain_length));
     51     _SOC_IF_ERR_EXIT(portmod_port_phychain_prbs_config_set(unit, phy_access, chain_length, flags, config));
     52 
     53 exit:
     54     SOC_FUNC_RETURN; 
     55 }
     56 
     57 int
     58 portmod_common_phy_prbs_config_get(int unit, int port, pm_info_t pm_info, int flags, phymod_prbs_t* config)
     59 {
     60     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
     61     int chain_length = 0;
     62 
     63     SOC_INIT_FUNC_DEFS;
     64 
     65     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
     66                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
     67                                                         &chain_length));
     68     _SOC_IF_ERR_EXIT(portmod_port_phychain_prbs_config_get(unit, phy_access, chain_length, flags, config));
     69     
     70 exit:
     71     SOC_FUNC_RETURN; 
     72 }
     73 
     74 int portmod_commmon_portmod_to_phymod_loopback_type(int unit, portmod_loopback_mode_t loopback_type, phymod_loopback_mode_t *phymod_lb_type)
     75 {
     76         
     77     SOC_INIT_FUNC_DEFS;
     78     switch(loopback_type){
     79     case portmodLoopbackPhyGloopPCS:
     80         *phymod_lb_type = phymodLoopbackGlobal;
     81         break;
     82     case portmodLoopbackPhyGloopPMD:
     83         *phymod_lb_type = phymodLoopbackGlobalPMD;
     84         break;
     85     case portmodLoopbackPhyRloopPCS:
     86         *phymod_lb_type = phymodLoopbackRemotePCS;
     87         break;
     88     case portmodLoopbackPhyRloopPMD:
     89         *phymod_lb_type = phymodLoopbackRemotePMD;
     90         break;
     91     default:
     92         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, ("unsupported loopback type %d", loopback_type));
     93     }
     94 exit:
     95     SOC_FUNC_RETURN; 
     96 }
     97 
     98 int
     99 portmod_common_phy_loopback_set(int unit, int port, pm_info_t pm_info, portmod_loopback_mode_t loopback_type, int enable)
    100 {
    101     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
    102     int chain_length = 0;
    103     phymod_loopback_mode_t phymod_lb_type;
    104 
    105     SOC_INIT_FUNC_DEFS;
    106 
    107     _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, loopback_type, &phymod_lb_type));
    108     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
    109                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
    110                                                         &chain_length));
    111     _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_set (unit, port, phy_access, chain_length, phymod_lb_type, enable));
    112 
    113 exit:
    114     SOC_FUNC_RETURN; 
    115 }
    116 
    117 int
    118 portmod_common_phy_loopback_get(int unit, int port, pm_info_t pm_info, portmod_loopback_mode_t loopback_type, int *enable)
    119 {
    120     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
    121     int chain_length = 0;
    122     phymod_loopback_mode_t phymod_lb_type;
    123     uint32_t tmp_enable=0;
    124 
    125     SOC_INIT_FUNC_DEFS;
    126 
    127     _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, loopback_type, &phymod_lb_type));
    128     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
    129                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
    130                                                         &chain_length));
    131     _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_get(unit, port,  phy_access, chain_length, phymod_lb_type, &tmp_enable));
    132      *enable = tmp_enable;
    133 exit:
    134     SOC_FUNC_RETURN; 
    135 }
    136 
    137 int portmod_common_phy_prbs_enable_set(int unit, int port, pm_info_t pm_info, int flags, int enable)
    138 {
    139     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
    140     int chain_length = 0;
    141 
    142     SOC_INIT_FUNC_DEFS;
    143 
    144     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,
    145                                                         PORT_MAX_PHY_ACCESS_STRUCTURES,
    146                                                         &chain_length));
    147     _SOC_IF_ERR_EXIT(portmod_port_phychain_prbs_enable_set(unit, phy_access, chain_length, flags, enable));
    148 
    149 exit:
    150     SOC_FUNC_RETURN;
    151 }
    152 
    153 
    154 int portmod_common_phy_prbs_enable_get(int unit, int port, pm_info_t pm_info, int flags, int* enable)
    155 {
    156     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
    157     int chain_length = 0;
    158     uint32_t tmp_enable;
    159 
    160     SOC_INIT_FUNC_DEFS;
    161 
    162     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,
    163                                                         PORT_MAX_PHY_ACCESS_STRUCTURES,
    164                                                         &chain_length));
    165     _SOC_IF_ERR_EXIT(portmod_port_phychain_prbs_enable_get(unit, phy_access, chain_length, flags, &tmp_enable));
    166     *enable = tmp_enable;
    167 exit:
    168     SOC_FUNC_RETURN;
    169 }
    170 
    171 
    172 int portmod_common_phy_prbs_status_get(int unit, int port, pm_info_t pm_info, int flags, phymod_prbs_status_t* status)
    173 {
    174     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
    175     int chain_length = 0;
    176 
    177     SOC_INIT_FUNC_DEFS;
    178     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access,
    179                                                         PORT_MAX_PHY_ACCESS_STRUCTURES,
    180                                                         &chain_length));
    181     _SOC_IF_ERR_EXIT(portmod_port_phychain_prbs_status_get(unit, phy_access, chain_length, flags, status));
    182 exit:
    183     SOC_FUNC_RETURN;
    184 }
    185 
    186 int portmod_common_phy_firmware_mode_set(int unit, int port, phymod_firmware_mode_t fw_mode)
    187 {
    188     SOC_INIT_FUNC_DEFS;
    189     SOC_FUNC_RETURN; 
    190 }
    191 
    192 
    193 int portmod_common_phy_firmware_mode_get(int unit, int port, phymod_firmware_mode_t *fw_mode)
    194 {
    195     SOC_INIT_FUNC_DEFS;
    196     SOC_FUNC_RETURN; 
    197 }
    198 
    199 /*!
    200  * portmod_common_pmd_lane_config_decode
    201  *
    202  * @brief decode the lane_config passed in from multi_resource_set
    203  *
    204  * @param [in]  unit     - lane_config
    205  * @param [out] name     - portmod_lane_config.
    206  */
    207 int portmod_common_pmd_lane_config_decode(uint32_t lane_config, portmod_pmd_lane_config_t* portmod_lane_config)
    208 {
    209     SOC_INIT_FUNC_DEFS;
    210     portmod_lane_config->pmd_firmware_lane_config.DfeOn   = PORTMOD_PORT_PHY_LANE_CONFIG_DFE_GET(lane_config);
    211     portmod_lane_config->pmd_firmware_lane_config.LpDfeOn = PORTMOD_PORT_PHY_LANE_CONFIG_LP_DFE_GET(lane_config);
    212     portmod_lane_config->pmd_firmware_lane_config.ForceBrDfe = PORTMOD_PORT_PHY_LANE_CONFIG_BR_DFE_GET(lane_config);
    213     portmod_lane_config->pmd_firmware_lane_config.MediaType = PORTMOD_PORT_PHY_LANE_CONFIG_MEDIUM_GET(lane_config);
    214     portmod_lane_config->pmd_firmware_lane_config.UnreliableLos = PORTMOD_PORT_PHY_LANE_CONFIG_UNRELIABLE_LOS_GET(lane_config);
    215     portmod_lane_config->pmd_firmware_lane_config.ScramblingDisable = PORTMOD_PORT_PHY_LANE_CONFIG_SCRAMBLING_DISABLE_GET(lane_config);
    216     portmod_lane_config->pmd_firmware_lane_config.Cl72AutoPolEn = PORTMOD_PORT_PHY_LANE_CONFIG_CL72_POLARITY_AUTO_EN_GET(lane_config);
    217     portmod_lane_config->pmd_firmware_lane_config.Cl72RestTO = PORTMOD_PORT_PHY_LANE_CONFIG_CL72_RESTART_TIMEOUT_EN_GET(lane_config);
    218     portmod_lane_config->pmd_firmware_lane_config.ForceExtenedReach = PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_ES_GET(lane_config);
    219     portmod_lane_config->pmd_firmware_lane_config.ForceNormalReach = PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_NS_GET(lane_config);
    220     portmod_lane_config->pmd_firmware_lane_config.LpPrecoderEnabled = PORTMOD_PORT_PHY_LANE_CONFIG_LP_PREC_EN_GET(lane_config);
    221     portmod_lane_config->pmd_firmware_lane_config.ForcePAM4Mode = PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_PAM4_GET(lane_config);
    222     portmod_lane_config->pmd_firmware_lane_config.ForceNRZMode = PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_NRZ_GET(lane_config);
    223     portmod_lane_config->pam4_channel_loss = PORTMOD_PORT_PHY_LANE_CONFIG_PAM4_CHANNEL_LOSS_GET(lane_config);
    224 
    225     SOC_FUNC_RETURN;
    226 }
    227 
    228 /*!
    229  * portmod_common_pmd_lane_config_encode
    230  *
    231  * @brief encode the portmod lane_config passed into a 32-bit encoded value
    232  *
    233  * @param [in]  unit     - portmod_lane_config
    234  * @param [out] name     - lane_config
    235  */
    236 int portmod_common_pmd_lane_config_encode(portmod_pmd_lane_config_t* portmod_lane_config, uint32_t* lane_config)
    237 {
    238     SOC_INIT_FUNC_DEFS;
    239 
    240     *lane_config = 0;
    241     if (portmod_lane_config->pmd_firmware_lane_config.DfeOn) {
    242         PORTMOD_PORT_PHY_LANE_CONFIG_DFE_SET(*lane_config);
    243     }
    244 
    245     if (portmod_lane_config->pmd_firmware_lane_config.LpDfeOn) {
    246         PORTMOD_PORT_PHY_LANE_CONFIG_LP_DFE_SET(*lane_config);
    247     }
    248 
    249     if (portmod_lane_config->pmd_firmware_lane_config.ForceBrDfe) {
    250         PORTMOD_PORT_PHY_LANE_CONFIG_BR_DFE_SET(*lane_config);
    251     }
    252 
    253     PORTMOD_PORT_PHY_LANE_CONFIG_MEDIUM_SET(*lane_config,
    254          portmod_lane_config->pmd_firmware_lane_config.MediaType);
    255 
    256     if (portmod_lane_config->pmd_firmware_lane_config.UnreliableLos) {
    257         PORTMOD_PORT_PHY_LANE_CONFIG_UNRELIABLE_LOS_SET(*lane_config);
    258     }
    259 
    260     if (portmod_lane_config->pmd_firmware_lane_config.ScramblingDisable) {
    261         PORTMOD_PORT_PHY_LANE_CONFIG_SCRAMBLING_DISABLE_SET(*lane_config);
    262     }
    263     if (portmod_lane_config->pmd_firmware_lane_config.Cl72AutoPolEn) {
    264         PORTMOD_PORT_PHY_LANE_CONFIG_CL72_POLARITY_AUTO_EN_SET(*lane_config);
    265     }
    266     if (portmod_lane_config->pmd_firmware_lane_config.Cl72RestTO) {
    267         PORTMOD_PORT_PHY_LANE_CONFIG_CL72_RESTART_TIMEOUT_EN_SET(*lane_config);
    268     }
    269     if (portmod_lane_config->pmd_firmware_lane_config.ForceExtenedReach) {
    270         PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_ES_SET(*lane_config);
    271     }
    272     if (portmod_lane_config->pmd_firmware_lane_config.ForceNormalReach) {
    273         PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_NS_SET(*lane_config);
    274     }
    275     if (portmod_lane_config->pmd_firmware_lane_config.LpPrecoderEnabled) {
    276         PORTMOD_PORT_PHY_LANE_CONFIG_LP_PREC_EN_SET(*lane_config);
    277     }
    278     if (portmod_lane_config->pmd_firmware_lane_config.ForcePAM4Mode) {
    279         PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_PAM4_SET(*lane_config);
    280     }
    281     if (portmod_lane_config->pmd_firmware_lane_config.ForceNRZMode) {
    282         PORTMOD_PORT_PHY_LANE_CONFIG_FORCE_NRZ_SET(*lane_config);
    283     }
    284 
    285     PORTMOD_PORT_PHY_LANE_CONFIG_PAM4_CHANNEL_LOSS_SET(*lane_config,
    286         portmod_lane_config->pam4_channel_loss);
    287 
    288     SOC_FUNC_RETURN;
    289 
    290 }
    291 
    292 
    293 
    294 
    295 /** 
    296  *  @brief generic function for register write for PM4X25,
    297  *         PM4X10, PM 12X10
    298  *  @param reg_access_mem - the memory that used for access PHY
    299  *                        registers. e.g: CLPORT_UCMEM_DATAm,
    300  *                        XLPORT_UCMEM_DATA
    301  *  @param user_acc - user data. this function expect to get
    302  *                  portmod_phy_op_data_t structure
    303  *  @param core_address -  only 5 bits of PHY id used in case
    304  *                       of sbus
    305  *  @param reg_addr - the reigister addrress
    306  *  @param val - the value to write to register. 16 bits value +
    307  *             16 bits mask
    308 
    309  */
    310 int
    311 portmod_common_phy_sbus_reg_write(soc_mem_t reg_access_mem, void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    312 {
    313     int rv= SOC_E_NONE;
    314     soc_reg_above_64_val_t mem_data;
    315     portmod_default_user_access_t *user_data = user_acc;
    316     uint32 data, data_mask;
    317     SOC_REG_ABOVE_64_CLEAR(mem_data);
    318 
    319     if(user_data == NULL){
    320         return SOC_E_PARAM;
    321     }
    322 
    323     /* If write mask (upper 16 bits) is empty, add full mask */
    324     if ((val & 0xffff0000) == 0) {
    325         val |= 0xffff0000;
    326     }
    327 
    328     /* assigning TSC register address to ucmem_data[31:0]  and write the 
    329      * data/datamask to to ucmem_data[63:32] */
    330     mem_data[0] = (reg_addr & 0xffffffff) | ((core_addr & 0x1f) << 19);
    331     /* data: ucmem_data[48:63]
    332        datamask: ucmem_data[32:47]
    333     */
    334     data = (val & 0xffff) << 16;
    335     data_mask = (~val & 0xffff0000) >> 16;
    336     mem_data[1] = data | data_mask;
    337     mem_data[2] = 1; /* for TSC register write */
    338 
    339 #ifdef CRASH_RECOVERY_SUPPORT
    340         if (BCM_UNIT_DO_HW_READ_WRITE(user_data->unit)){
    341             soc_dcmn_cr_suppress(user_data->unit, dcmn_cr_no_support_portmod);
    342         }
    343 #endif /* CRASH_RECOVERY_SUPPORT */
    344 
    345     rv = soc_mem_write(user_data->unit, reg_access_mem, user_data->blk_id, 0, mem_data); 
    346 
    347     LOG_DEBUG(BSL_LS_SOC_MII,
    348               (BSL_META_U(user_data->unit,
    349                           "_portmod_utils_sbus_reg_write[%d]: "
    350                           "addr=0x%x reg=0x%08x data=0x%08x mask=0x%08x(%d/%d)\n"),
    351                user_data->unit, core_addr, reg_addr, val , data_mask, user_data->blk_id, rv));
    352 
    353     return rv;
    354 }
    355 
    356 
    357 /** 
    358  *  @brief generic function for register read for PM4X25,
    359  *         PM4X10, PM 12X10
    360  *  @param reg_access_mem - the memory that used for access PHY
    361  *                        registers. e.g: CLPORT_UCMEM_DATAm,
    362  *                        XLPORT_UCMEM_DATA
    363  *  @param user_acc - user data. this function expect to get
    364  *                  portmod_phy_op_data_t structure
    365  *  @param core_address -  only 5 bits of PHY id used in case
    366  *                       of sbus
    367  *  @param reg_addr - the reigister addrress
    368  *  @param val - the value to write to register. no mask for
    369  *             read
    370  */
    371 int
    372 portmod_common_phy_sbus_reg_read(soc_mem_t reg_access_mem, void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    373 {
    374     int rv = SOC_E_NONE, reg_val_offset;
    375     soc_reg_above_64_val_t mem_data;
    376     portmod_default_user_access_t *user_data = user_acc;
    377     SOC_REG_ABOVE_64_CLEAR(mem_data);
    378 
    379     if(user_data == NULL){
    380         return SOC_E_PARAM;
    381     }
    382     
    383     /* assigning TSC register address to ucmem_data[31:0] */
    384     mem_data[0] = (reg_addr & 0xffffffff) | ((core_addr & 0x1f) << 19);
    385     mem_data[2] = 0; /* for TSC register READ */
    386 
    387 #if defined(BCM_PETRA_SUPPORT) || defined (BCM_DFE_SUPPORT)
    388 #ifdef CRASH_RECOVERY_SUPPORT
    389     soc_hw_set_immediate_hw_access(user_data->unit);
    390 #endif /* CRASH_RECOVERY_SUPPORT */
    391 #endif /* defined(BCM_PETRA_SUPPORT) || defined (BCM_DFE_SUPPORT) */
    392 
    393     SOC_ALLOW_WB_WRITE(user_data->unit, soc_mem_write(user_data->unit, reg_access_mem, user_data->blk_id, 0, mem_data), rv);
    394    
    395     /* read data back from ucmem_data[47:32] */
    396     if (SOC_SUCCESS(rv)) {
    397         rv = soc_mem_read(user_data->unit, reg_access_mem, user_data->blk_id, 0, mem_data);
    398     }
    399 
    400 #if defined(BCM_PETRA_SUPPORT) || defined (BCM_DFE_SUPPORT)
    401 #ifdef CRASH_RECOVERY_SUPPORT
    402     soc_hw_restore_immediate_hw_access(user_data->unit);
    403 #endif /* CRASH_RECOVERY_SUPPORT */
    404 #endif /* defined(BCM_PETRA_SUPPORT) || defined (BCM_DFE_SUPPORT) */
    405 
    406     if (PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_GET(user_data)) {
    407         reg_val_offset = 0;
    408     } else {
    409         reg_val_offset = 1; /* default behaviour */
    410     }
    411 
    412     *val = mem_data[reg_val_offset];
    413 
    414     LOG_DEBUG(BSL_LS_SOC_MII, (BSL_META_U(user_data->unit,
    415                  "_portmod_utils_sbus_reg_read[%d]: "
    416                  "addr=0x%x reg=0x%08x data=0x%08x (%d/%d)\n"),
    417                  user_data->unit, core_addr, reg_addr, *val, user_data->blk_id, rv));
    418 
    419     return rv;
    420 }
    421 
    422 int
    423 portmod_common_mutex_take(void* user_acc)
    424 {
    425     portmod_default_user_access_t* user_data;
    426     SOC_INIT_FUNC_DEFS;
    427 
    428     user_data = (portmod_default_user_access_t*)user_acc;
    429 
    430     if(user_data->mutex != NULL) {
    431         _SOC_IF_ERR_EXIT(sal_mutex_take(user_data->mutex, sal_mutex_FOREVER));
    432     }
    433 
    434 exit:
    435     SOC_FUNC_RETURN;
    436 }
    437 
    438 int 
    439 portmod_common_mutex_give(void* user_acc)
    440 {
    441     portmod_default_user_access_t* user_data;
    442     SOC_INIT_FUNC_DEFS;
    443 
    444     user_data = (portmod_default_user_access_t*)user_acc;
    445 
    446     if(user_data->mutex != NULL) {
    447         _SOC_IF_ERR_EXIT(sal_mutex_give(user_data->mutex));
    448     }
    449 
    450 exit:
    451     SOC_FUNC_RETURN;
    452 }
    453 
    454 static
    455 int _portmod_dma_buf_alloc(int unit, const uint8 *data, uint32 datalen,
    456                            portmod_ucode_buf_t *dmabuf, portmod_ucode_buf_order_t data_swap,
    457                            int endian, int entry_bytes)
    458 {
    459     int count, extra_bytes, i, j;
    460     uint8 *dma_buf_ptr;
    461     const uint8 *array_ptr;
    462     int arr_pos_le[3] [16]
    463         = {{15, 14, 13, 12, 11, 10,  9,  8, 7, 6, 5, 4, 3, 2, 1, 0},
    464            { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},
    465            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
    466     int arr_pos_be[3] [16]
    467         = {{12, 13, 14, 15,  8,  9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},
    468             {11, 10,  9,  8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4},
    469             {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12}};
    470     int *arr_pos;
    471     SOC_INIT_FUNC_DEFS;
    472 
    473     if(endian) {
    474         arr_pos = arr_pos_be[data_swap];
    475     } else {
    476         arr_pos = arr_pos_le[data_swap];
    477     }
    478 
    479     count = datalen / entry_bytes;
    480     extra_bytes = datalen % entry_bytes;
    481     dmabuf->ucode_alloc_size = datalen;
    482 
    483     /* align to entry_bytes */
    484     if (extra_bytes != 0) {
    485         dmabuf->ucode_alloc_size += entry_bytes - extra_bytes;
    486     }
    487 
    488     dmabuf->ucode_dma_buf = portmod_sys_dma_alloc(unit, dmabuf->ucode_alloc_size,
    489                                                   "WC ucode DMA buffer");
    490     if (dmabuf->ucode_dma_buf == NULL) {
    491         _SOC_EXIT_WITH_ERR(SOC_E_MEMORY, ("Failed to alloc WC ucode DMA buffer"));
    492     }
    493 
    494     /* copy image into dma buffer */
    495     array_ptr = data;
    496     dma_buf_ptr = dmabuf->ucode_dma_buf;
    497     for (i = 0; i < count; i++) {
    498         for (j = 0; j < 16; j++) {
    499             dma_buf_ptr[arr_pos[j]] = array_ptr[j];
    500         }
    501         array_ptr += entry_bytes;
    502         dma_buf_ptr += entry_bytes;
    503     }
    504     if (extra_bytes != 0) {
    505         sal_memset(dma_buf_ptr, 0, entry_bytes);
    506         for (j = 0; j < extra_bytes; j++) {
    507             dma_buf_ptr[arr_pos[j]] = array_ptr[j];
    508         }
    509     }
    510 
    511 exit:
    512     SOC_FUNC_RETURN;
    513 }
    514 
    515 /**
    516  * this function will download ucode through UCMEM, if ucode size exceeds UCMEM limitation,
    517  * the second DMA buffer is required to download extra data
    518  */
    519 int
    520 portmod_firmware_set(int unit,
    521                      int blk_id,
    522                      const uint8 *array,
    523                      uint32 datalen,
    524                      portmod_ucode_buf_order_t data_swap,
    525                      int bcast_en,
    526                      portmod_ucode_buf_t* buf,
    527                      portmod_ucode_buf_t* buf_2nd,
    528                      soc_mem_t ucmem_data,
    529                      soc_reg_t ucmem_ctrl)
    530 {
    531     int entry_bytes, entry_num, ucmem_size, endian;
    532     const uint8 *array_2nd;
    533     uint32 datalen_2nd = 0;
    534     int reg_access_idx = (blk_id | SOC_REG_ADDR_BLOCK_ID_MASK);
    535     uint64 reg_val;
    536 #ifdef FW_BCAST_DOWNLOAD
    537     int flags = 0;
    538 #endif
    539     SOC_INIT_FUNC_DEFS;
    540 
    541     entry_bytes = soc_mem_entry_bytes(unit, ucmem_data);
    542     entry_num = soc_mem_index_count(unit, ucmem_data);
    543     ucmem_size = entry_bytes * entry_num;
    544 
    545     /* this is for PM8x50 16nm B0  UCMEM memory increase */
    546     if (ucmem_size > 65536) {
    547         ucmem_size = 65536;
    548     }
    549 
    550     if (datalen > ucmem_size) {
    551         if (buf_2nd==NULL || datalen>2*ucmem_size) {
    552             _SOC_EXIT_WITH_ERR(SOC_E_RESOURCE, ("Can't fit all of the firmware into the device load table."));
    553         }
    554 
    555         array_2nd = array + ucmem_size;
    556         datalen_2nd = datalen - ucmem_size;
    557         datalen = ucmem_size;
    558     } else {
    559         array_2nd = NULL;
    560     }
    561 
    562     portmod_sys_get_endian(unit, &endian);
    563 
    564     if (buf->ucode_dma_buf == NULL) {
    565         _SOC_IF_ERR_EXIT(_portmod_dma_buf_alloc(unit, array, datalen, buf, data_swap, endian, entry_bytes));
    566     }
    567 
    568     if (datalen_2nd>0 && buf_2nd!=NULL && buf_2nd->ucode_dma_buf==NULL) {
    569         _SOC_IF_ERR_EXIT(_portmod_dma_buf_alloc(unit, array_2nd, datalen_2nd, buf_2nd, data_swap, endian, entry_bytes));
    570     }
    571 
    572     /* enable parallel bus access */
    573     _SOC_IF_ERR_EXIT(soc_reg_get(unit,ucmem_ctrl, reg_access_idx, 0, &reg_val));
    574     soc_reg64_field32_set(unit, ucmem_ctrl, &reg_val, ACCESS_MODEf, 1);
    575     _SOC_IF_ERR_EXIT(soc_reg_set(unit,ucmem_ctrl, reg_access_idx, 0, reg_val));
    576 
    577 #ifdef FW_BCAST_DOWNLOAD
    578     if (bcast_en) {
    579         flags = SOC_MEM_WRITE_BCAST_OP;
    580     }
    581 
    582     _SOC_IF_ERR_EXIT
    583         (soc_mem_array_write_range_multi_cmc(unit, flags, ucmem_data, 0, blk_id, 0,
    584                              buf->ucode_alloc_size / entry_bytes - 1,
    585                              buf->ucode_dma_buf, -1));
    586 
    587     /* if ucode size exceeds UCMEM limitation, the second buffer is used to download the extra data */
    588     if (datalen_2nd>0 && buf_2nd!=NULL) {
    589         _SOC_IF_ERR_EXIT
    590             (soc_mem_array_write_range_multi_cmc(unit, flags, ucmem_data, 0, blk_id, 0,
    591                                  buf_2nd->ucode_alloc_size / entry_bytes - 1,
    592                                  buf_2nd->ucode_dma_buf, -1));
    593     }
    594 #else
    595     /* coverity[stack_use_overflow] */
    596     _SOC_IF_ERR_EXIT
    597         (soc_mem_write_range(unit, ucmem_data, blk_id, 0,
    598                              buf->ucode_alloc_size / entry_bytes - 1,
    599                              buf->ucode_dma_buf));
    600 
    601     /* if ucode size exceeds UCMEM limitation, the second buffer is used to download the extra data */
    602     if (datalen_2nd>0 && buf_2nd!=NULL) {
    603         _SOC_IF_ERR_EXIT
    604             (soc_mem_write_range(unit, ucmem_data, blk_id, 0,
    605                                  buf_2nd->ucode_alloc_size / entry_bytes - 1,
    606                                  buf_2nd->ucode_dma_buf));
    607     }
    608 #endif
    609 
    610     /* disable parallel bus access, and enable MDIO access */
    611     _SOC_IF_ERR_EXIT(soc_reg_get(unit,ucmem_ctrl, reg_access_idx, 0, &reg_val));
    612     soc_reg64_field32_set(unit, ucmem_ctrl, &reg_val, ACCESS_MODEf, 0);
    613     _SOC_IF_ERR_EXIT(soc_reg_set(unit,ucmem_ctrl, reg_access_idx, 0, reg_val));
    614 
    615 exit:
    616     SOC_FUNC_RETURN;
    617 }
    618 
    619 void portmod_common_phy_to_port_ability (phymod_autoneg_ability_t *anAbility,
    620                                          portmod_port_ability_t *portAbility)
    621 {
    622     int                       abil37;
    623     int                       abil73;
    624     _shr_port_mode_t          spd_fd = 0;  /* Speed full duplex */
    625     int                       abil73bam;
    626 
    627     /* retrieve CL73 abilities */
    628     abil73 = anAbility->an_cap;
    629     spd_fd|= PHYMOD_AN_CAP_100G_CR10_GET(abil73) ?SOC_PA_SPEED_100GB:0;
    630     spd_fd|= PHYMOD_AN_CAP_100G_CR4_GET(abil73) ?SOC_PA_SPEED_100GB:0;
    631     spd_fd|= PHYMOD_AN_CAP_100G_KR4_GET(abil73) ?SOC_PA_SPEED_100GB:0;
    632     spd_fd|= PHYMOD_AN_CAP_40G_CR4_GET(abil73) ?SOC_PA_SPEED_40GB:0;
    633     spd_fd|= PHYMOD_AN_CAP_40G_KR4_GET(abil73) ?SOC_PA_SPEED_40GB:0;
    634     spd_fd|= PHYMOD_AN_CAP_10G_KR_GET(abil73)  ?SOC_PA_SPEED_10GB:0;
    635     spd_fd|= PHYMOD_AN_CAP_10G_KX4_GET(abil73) ?SOC_PA_SPEED_10GB:0;
    636     spd_fd|= PHYMOD_AN_CAP_1G_KX_GET(abil73)   ?SOC_PA_SPEED_1000MB:0;
    637     spd_fd|= PHYMOD_AN_CAP_100M_GET(abil73)   ?SOC_PA_SPEED_100MB:0;
    638     spd_fd|= PHYMOD_AN_CAP_25G_CR1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    639     spd_fd|= PHYMOD_AN_CAP_25G_KR1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    640     spd_fd|= PHYMOD_AN_CAP_25G_CRS1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    641     spd_fd|= PHYMOD_AN_CAP_25G_KRS1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    642 
    643     /* retrieve CL73bam abilities */
    644     abil73 = anAbility->cl73bam_cap;
    645     spd_fd|= PHYMOD_BAM_CL73_CAP_50G_CR4_GET(abil73)? SOC_PA_SPEED_50GB:0;
    646     spd_fd|= PHYMOD_BAM_CL73_CAP_50G_KR4_GET(abil73)? SOC_PA_SPEED_50GB:0;
    647     spd_fd|= PHYMOD_BAM_CL73_CAP_50G_CR2_GET(abil73)? SOC_PA_SPEED_50GB:0;
    648     spd_fd|= PHYMOD_BAM_CL73_CAP_50G_KR2_GET(abil73)? SOC_PA_SPEED_50GB:0;
    649     spd_fd|= PHYMOD_BAM_CL73_CAP_40G_CR2_GET(abil73)? SOC_PA_SPEED_40GB:0;
    650     spd_fd|= PHYMOD_BAM_CL73_CAP_40G_KR2_GET(abil73)? SOC_PA_SPEED_40GB:0;
    651     spd_fd|= PHYMOD_BAM_CL73_CAP_25G_CR1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    652     spd_fd|= PHYMOD_BAM_CL73_CAP_25G_KR1_GET(abil73)? SOC_PA_SPEED_25GB:0;
    653     spd_fd|= PHYMOD_BAM_CL73_CAP_20G_CR2_GET(abil73)? SOC_PA_SPEED_20GB:0;
    654     spd_fd|= PHYMOD_BAM_CL73_CAP_20G_KR2_GET(abil73)? SOC_PA_SPEED_20GB:0;
    655     spd_fd|= PHYMOD_BAM_CL73_CAP_20G_CR1_GET(abil73)? SOC_PA_SPEED_20GB:0;
    656     spd_fd|= PHYMOD_BAM_CL73_CAP_20G_KR1_GET(abil73)? SOC_PA_SPEED_20GB:0;
    657     
    658     /* retrieve CL37 abilities */
    659     abil37 = anAbility->cl37bam_cap;
    660     spd_fd|= PHYMOD_BAM_CL37_CAP_40G_GET(abil37)  ? SOC_PA_SPEED_40GB:0;
    661     spd_fd|= PHYMOD_BAM_CL37_CAP_31P5G_GET(abil37)? SOC_PA_SPEED_30GB:0;
    662     spd_fd|= PHYMOD_BAM_CL37_CAP_32P7G_GET(abil37)? SOC_PA_SPEED_32GB:0;
    663 
    664     spd_fd|= PHYMOD_BAM_CL37_CAP_25P455G_GET(abil37)   ? SOC_PA_SPEED_25GB:0;
    665     spd_fd|= PHYMOD_BAM_CL37_CAP_21G_X4_GET(abil37)    ? SOC_PA_SPEED_21GB:0;
    666     spd_fd|= PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(abil37)? SOC_PA_SPEED_20GB:0;
    667     spd_fd|= PHYMOD_BAM_CL37_CAP_20G_X2_GET(abil37)    ? SOC_PA_SPEED_20GB:0;
    668     spd_fd|= PHYMOD_BAM_CL37_CAP_20G_X4_GET(abil37)    ? SOC_PA_SPEED_20GB:0;
    669     spd_fd|= PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(abil37)? SOC_PA_SPEED_20GB:0;
    670     spd_fd|= PHYMOD_BAM_CL37_CAP_16G_X4_GET(abil37)    ? SOC_PA_SPEED_16GB:0;
    671     spd_fd|= PHYMOD_BAM_CL37_CAP_15P75G_R2_GET(abil37) ? SOC_PA_SPEED_16GB:0;
    672     spd_fd|= PHYMOD_BAM_CL37_CAP_15G_X4_GET(abil37)?     SOC_PA_SPEED_15GB:0;
    673     spd_fd|= PHYMOD_BAM_CL37_CAP_13G_X4_GET(abil37)?     SOC_PA_SPEED_13GB:0;
    674     spd_fd|= PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(abil37)? SOC_PA_SPEED_13GB:0;
    675     spd_fd|= PHYMOD_BAM_CL37_CAP_12P5_X4_GET(abil37)?    SOC_PA_SPEED_12P5GB:0;
    676     spd_fd|= PHYMOD_BAM_CL37_CAP_12G_X4_GET(abil37)?     SOC_PA_SPEED_12GB:0;
    677     spd_fd|= PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(abil37)?SOC_PA_SPEED_11GB:0;
    678     spd_fd|= PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(abil37)? SOC_PA_SPEED_10GB:0;
    679     spd_fd|= PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(abil37)?  SOC_PA_SPEED_10GB:0;
    680     spd_fd|= PHYMOD_BAM_CL37_CAP_10G_CX4_GET(abil37)?    SOC_PA_SPEED_10GB:0;
    681     spd_fd|= PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(abil37)?  SOC_PA_SPEED_10GB:0; /* 4-lane */
    682     spd_fd|= PHYMOD_BAM_CL37_CAP_6G_X4_GET(abil37)?      SOC_PA_SPEED_6000MB:0;
    683     spd_fd|= PHYMOD_BAM_CL37_CAP_5G_X4_GET(abil37)?      SOC_PA_SPEED_5000MB:0;
    684     spd_fd|= PHYMOD_BAM_CL37_CAP_2P5G_GET(abil37)?       SOC_PA_SPEED_2500MB:0;
    685 
    686     if (PHYMOD_AN_CAP_CL37_GET(anAbility)){
    687         spd_fd|= SOC_PA_SPEED_1000MB;
    688     }
    689 
    690     if (PHYMOD_AN_CAP_SGMII_GET(anAbility)){
    691         switch (anAbility->sgmii_speed){
    692             case phymod_CL37_SGMII_10M:
    693                 spd_fd|= SOC_PA_SPEED_10MB;
    694                 break;
    695             case phymod_CL37_SGMII_100M:
    696                 spd_fd|= SOC_PA_SPEED_100MB;
    697                 break;
    698             case phymod_CL37_SGMII_1000M:
    699                 spd_fd|= SOC_PA_SPEED_1000MB;
    700                 break;
    701             default:
    702                 break;
    703         }
    704     }
    705 
    706     portAbility->pause = 0;
    707     if (anAbility->capabilities & PHYMOD_AN_CAP_ASYM_PAUSE) {
    708         if (anAbility->capabilities & PHYMOD_AN_CAP_SYMM_PAUSE) {
    709             portAbility->pause = SOC_PA_PAUSE_RX;
    710         } else {
    711             portAbility->pause = SOC_PA_PAUSE_TX;
    712         }
    713     } else if (anAbility->capabilities & PHYMOD_AN_CAP_SYMM_PAUSE) {
    714         portAbility->pause = SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX;
    715     }
    716 
    717     portAbility->speed_full_duplex = spd_fd;
    718 
    719     abil73    = anAbility->an_cap;
    720     abil73bam = anAbility->cl73bam_cap;
    721     
    722     if (PHYMOD_AN_CAP_25G_KRS1_GET(abil73) || PHYMOD_AN_CAP_25G_CRS1_GET(abil73)) {
    723         portAbility->channel = SOC_PA_CHANNEL_SHORT;
    724     } else {
    725         portAbility->channel = SOC_PA_CHANNEL_LONG;
    726     }
    727 
    728     if (PHYMOD_AN_CAP_100G_CR4_GET(abil73) || PHYMOD_AN_CAP_40G_CR4_GET(abil73)  ||
    729         PHYMOD_AN_CAP_25G_CR1_GET(abil73)  || PHYMOD_AN_CAP_25G_CRS1_GET(abil73) ||
    730         PHYMOD_BAM_CL73_CAP_20G_CR2_GET(abil73bam)  || PHYMOD_BAM_CL73_CAP_40G_CR2_GET(abil73bam) ||
    731         PHYMOD_BAM_CL73_CAP_50G_CR2_GET(abil73bam)  || PHYMOD_BAM_CL73_CAP_25G_CR1_GET(abil73bam) ||
    732         PHYMOD_BAM_CL73_CAP_50G_CR4_GET(abil73bam)) {
    733         portAbility->medium = SOC_PA_MEDIUM_COPPER;
    734     } else {
    735         portAbility->medium = SOC_PA_MEDIUM_BACKPLANE;
    736     }
    737 
    738     portAbility->fec = 0;
    739     if (PHYMOD_AN_FEC_OFF_GET(anAbility->an_fec)) {
    740         portAbility->fec = SOC_PA_FEC_NONE;
    741     } else {
    742         if (PHYMOD_AN_FEC_CL74_GET(anAbility->an_fec)) {
    743             portAbility->fec |= SOC_PA_FEC_CL74;
    744         }
    745         if (PHYMOD_AN_FEC_CL91_GET(anAbility->an_fec)) {
    746             portAbility->fec |= SOC_PA_FEC_CL91;
    747         }
    748     }
    749 
    750     if (anAbility->an_hg2) {
    751         portAbility->encap = SOC_ENCAP_HIGIG2;
    752     } else {
    753         portAbility->encap = SOC_ENCAP_IEEE;
    754     }
    755 
    756 }
    757 
    758 
    759 /* phy_tsce_ability_advert_set */
    760 #define PHYMOD_INTF_CR4    (1 << SOC_PORT_IF_CR4)
    761 void portmod_common_port_to_phy_ability (portmod_port_ability_t *portAbility, 
    762                                          phymod_autoneg_ability_t *anAbility,
    763                                          int port_num_lanes, 
    764                                          int line_interface, 
    765                                          int cx4_10g,
    766                                          int an_cl72,
    767                                          int an_fec,
    768                                          int hg_mode)
    769 {
    770     uint32_t                  an_tech_ability   = 0;
    771     uint32_t                  an_bam37_ability  = 0;
    772     uint32_t                  an_bam73_ability  = 0;
    773     _shr_port_mode_t          speed_full_duplex = portAbility->speed_full_duplex;
    774     phymod_autoneg_ability_t_init(anAbility);
    775 
    776     /* an_tech_ability */
    777     if (port_num_lanes == 4  ||
    778         port_num_lanes == 10 ||
    779         port_num_lanes == 12 ) {
    780         if ((speed_full_duplex & SOC_PA_SPEED_100GB) ||
    781             (speed_full_duplex & SOC_PA_SPEED_106GB) ||
    782             (speed_full_duplex & SOC_PA_SPEED_120GB) ||
    783             (speed_full_duplex & SOC_PA_SPEED_127GB)) {
    784             if (SOC_PORT_IF_CR4 == line_interface) {
    785                 PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
    786             } else if ((SOC_PORT_IF_KR4 == line_interface)
    787                        ||(SOC_PORT_IF_CAUI4 == line_interface)) {
    788                 PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
    789             } else {
    790                 if(port_num_lanes == 4){
    791                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
    792                 } else if (port_num_lanes == 10){
    793                     PHYMOD_AN_CAP_100G_CR10_SET(an_tech_ability);
    794                 } else {
    795                     PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
    796                 } 
    797             }
    798         }
    799         if (speed_full_duplex & SOC_PA_SPEED_50GB) {
    800             if (SOC_PORT_IF_CR4 == line_interface) {
    801                 PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_bam73_ability);
    802             } else {
    803                 PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_bam73_ability);
    804             }
    805         }
    806         if (speed_full_duplex & SOC_PA_SPEED_40GB) {
    807             if (SOC_PORT_IF_CR4 == line_interface) {
    808                 PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
    809             } else {
    810                 PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
    811             }
    812         }
    813         if(speed_full_duplex & SOC_PA_SPEED_20GB) {
    814             if (SOC_PORT_IF_CR4 == line_interface) {
    815                 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
    816             } else {
    817                 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
    818             }
    819         }
    820         if(speed_full_duplex & SOC_PA_SPEED_10GB) {
    821             PHYMOD_AN_CAP_10G_KX4_SET(an_tech_ability);
    822         }
    823         if (speed_full_duplex & SOC_PA_SPEED_1000MB)
    824             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
    825     } else if (port_num_lanes == 2) {
    826         if(speed_full_duplex & SOC_PA_SPEED_50GB) {
    827             if (SOC_PORT_IF_CR2 == line_interface) {
    828                 PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_bam73_ability);
    829             } else {
    830                 PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_bam73_ability);
    831             }
    832         }
    833         if(speed_full_duplex & SOC_PA_SPEED_40GB) {
    834             if (SOC_PORT_IF_CR2 == line_interface) {
    835                 PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_bam73_ability);
    836             /*support AN ability set for external PHY with Gearbox mode*/
    837             } else if (SOC_PORT_IF_CR4 == line_interface) {
    838                 PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
    839             } else if (SOC_PORT_IF_KR4 == line_interface) {
    840                 PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
    841             } else {
    842                 PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_bam73_ability);
    843             }
    844         }
    845         if(speed_full_duplex & SOC_PA_SPEED_20GB) {
    846             if (SOC_PORT_IF_CR2 == line_interface) {
    847                 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability);
    848             } else {
    849                 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability);
    850             }
    851         }
    852         if (speed_full_duplex & SOC_PA_SPEED_10GB)
    853             PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
    854         if (speed_full_duplex & SOC_PA_SPEED_1000MB)
    855             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
    856     } else {
    857         if(speed_full_duplex & SOC_PA_SPEED_25GB) {
    858             if (SOC_PORT_IF_CR == line_interface) {
    859                 PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_bam73_ability);
    860                 PHYMOD_AN_CAP_25G_CR1_SET(an_tech_ability);
    861             } else {
    862                 PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_bam73_ability);
    863                 PHYMOD_AN_CAP_25G_KR1_SET(an_tech_ability);
    864             }
    865         }
    866         if(speed_full_duplex & SOC_PA_SPEED_20GB) {
    867             if (SOC_PORT_IF_CR == line_interface) {
    868                 PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_bam73_ability);
    869             } else {
    870                 PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_bam73_ability);
    871             }
    872         }
    873         if (speed_full_duplex & SOC_PA_SPEED_10GB)
    874             PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
    875         if (speed_full_duplex & SOC_PA_SPEED_1000MB)
    876             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);        
    877     }
    878     
    879     /* an_bam37_ability */
    880     if (port_num_lanes == 4 ||
    881         port_num_lanes == 10 ||
    882         port_num_lanes == 12) {
    883         if(speed_full_duplex & SOC_PA_SPEED_40GB)
    884             PHYMOD_BAM_CL37_CAP_40G_SET(an_bam37_ability);
    885         /* if(speed_full_duplex & SOC_PA_SPEED_33GB)
    886             an_bam37_ability |= (1<<PHYMOD_BAM37ABL_32P7G); */
    887          if(speed_full_duplex & SOC_PA_SPEED_30GB)
    888             PHYMOD_BAM_CL37_CAP_31P5G_SET(an_bam37_ability);
    889         if(speed_full_duplex & SOC_PA_SPEED_25GB)
    890             PHYMOD_BAM_CL37_CAP_25P455G_SET(an_bam37_ability);
    891         if(speed_full_duplex & SOC_PA_SPEED_21GB)
    892             PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_bam37_ability);
    893         if(speed_full_duplex & SOC_PA_SPEED_20GB){
    894             PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_bam37_ability);
    895             PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_bam37_ability);
    896         }
    897         if(speed_full_duplex & SOC_PA_SPEED_16GB)
    898             PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_bam37_ability);
    899         if(speed_full_duplex & SOC_PA_SPEED_15GB)
    900             PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_bam37_ability);
    901         if(speed_full_duplex & SOC_PA_SPEED_13GB)
    902             PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_bam37_ability);
    903         if(speed_full_duplex & SOC_PA_SPEED_12P5GB)
    904             PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_bam37_ability);
    905         if(speed_full_duplex & SOC_PA_SPEED_12GB)
    906             PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_bam37_ability);
    907         if(speed_full_duplex & SOC_PA_SPEED_10GB) {
    908             if (cx4_10g) {
    909                 PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_bam37_ability);
    910             } else {
    911                 PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_bam37_ability);
    912             }
    913         }     
    914         if(speed_full_duplex & SOC_PA_SPEED_6000MB)
    915             PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_bam37_ability);
    916         if(speed_full_duplex & SOC_PA_SPEED_5000MB)
    917             PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_bam37_ability);
    918         if(speed_full_duplex & SOC_PA_SPEED_2500MB)
    919             PHYMOD_BAM_CL37_CAP_2P5G_SET(an_bam37_ability);
    920         if(speed_full_duplex & SOC_PA_SPEED_1000MB)
    921             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
    922 
    923     } else if (port_num_lanes == 2) {     /* 2 lanes */
    924 
    925         if(speed_full_duplex & SOC_PA_SPEED_20GB){
    926             PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_bam37_ability);
    927             PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_bam37_ability);
    928         }
    929         if (speed_full_duplex & SOC_PA_SPEED_16GB)
    930             PHYMOD_BAM_CL37_CAP_15P75G_R2_SET(an_bam37_ability);
    931         if (speed_full_duplex & SOC_PA_SPEED_13GB)
    932             PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_bam37_ability);
    933         if (speed_full_duplex & SOC_PA_SPEED_11GB)
    934             PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_bam37_ability);
    935         if (speed_full_duplex & SOC_PA_SPEED_10GB){
    936             PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_bam37_ability);
    937             PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_bam37_ability);
    938         }
    939         if (speed_full_duplex & SOC_PA_SPEED_2500MB)
    940             PHYMOD_BAM_CL37_CAP_2P5G_SET(an_bam37_ability);
    941         if (speed_full_duplex & SOC_PA_SPEED_1000MB)
    942             PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability);
    943 
    944     } else {                              /* 1 lane */
    945         if (speed_full_duplex & SOC_PA_SPEED_2500MB)
    946             PHYMOD_BAM_CL37_CAP_2P5G_SET(an_bam37_ability);
    947     }
    948     anAbility->an_cap = an_tech_ability;
    949     anAbility->cl73bam_cap = an_bam73_ability; 
    950     anAbility->cl37bam_cap = an_bam37_ability; 
    951 
    952     
    953 
    954     switch (portAbility->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
    955     case SOC_PA_PAUSE_TX:
    956         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
    957         break;
    958     case SOC_PA_PAUSE_RX:
    959         /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
    960         PHYMOD_AN_CAP_ASYM_PAUSE_SET(anAbility);
    961         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
    962         break;
    963     case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
    964         PHYMOD_AN_CAP_SYMM_PAUSE_SET(anAbility);
    965         break;
    966     }
    967 
    968     if ((speed_full_duplex & SOC_PA_SPEED_10MB) ||
    969         (speed_full_duplex & SOC_PA_SPEED_100MB) ||
    970         (speed_full_duplex & SOC_PA_SPEED_1000MB)) {
    971         if (SOC_PORT_IF_SGMII == line_interface) {
    972             /* also set the sgmii speed */
    973             if(portAbility->speed_full_duplex & SOC_PA_SPEED_1000MB) {
    974                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
    975                 anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
    976             } else if(portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
    977                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
    978                 anAbility->sgmii_speed = phymod_CL37_SGMII_100M;
    979             } else if(portAbility->speed_full_duplex & SOC_PA_SPEED_10MB) {
    980                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
    981                 anAbility->sgmii_speed = phymod_CL37_SGMII_10M;
    982             } else {
    983                 PHYMOD_AN_CAP_SGMII_SET(anAbility);
    984                 anAbility->sgmii_speed = phymod_CL37_SGMII_1000M;
    985             }
    986         } else {
    987             if(portAbility->speed_full_duplex & SOC_PA_SPEED_100MB) {
    988                 PHYMOD_AN_CAP_100M_SET(anAbility->an_cap);
    989             }
    990         }
    991     }
    992 
    993     /* next check if we need to set cl37 attribute */
    994     if (an_cl72) {
    995         anAbility->an_cl72 = 1;
    996     }
    997     if (hg_mode) {
    998         anAbility->an_hg2 = 1;
    999     }
   1000 
   1001     /* check if Cl74/CL91 fec is to be set */
   1002     if (portAbility->fec == SOC_PA_FEC_NONE) {
   1003         PHYMOD_AN_FEC_OFF_SET(anAbility->an_fec);
   1004     } else {
   1005         if(portAbility->fec & SOC_PA_FEC_CL74) {
   1006             PHYMOD_AN_FEC_CL74_SET(anAbility->an_fec);
   1007         }
   1008         if(portAbility->fec & SOC_PA_FEC_CL91) {
   1009            PHYMOD_AN_FEC_CL91_SET(anAbility->an_fec);
   1010         }
   1011     }
   1012 
   1013     if (an_fec) {
   1014         PHYMOD_AN_FEC_CL74_SET(anAbility->an_fec);
   1015     }
   1016 
   1017 }
   1018 
   1019 /*!
   1020  * portmod_port_main_core_access_get
   1021  *
   1022  * @brief get port main cores' phymod access
   1023  *
   1024  * @param [in]  unit               - unit id
   1025  * @param [in]  port               - logical port
   1026  * @param [in]  phyn               - the number of hops from the internal phy. 0 - internal, 1- first external PHY, etc.
   1027  * @param [out]  core_access_arr   - port phymod cores array
   1028  * @param [out]  nof_cores         - number of core access structutres filled by the function
   1029  */
   1030 int portmod_port_main_core_access_get(int unit, int port, int phyn,
   1031                                       phymod_core_access_t *core_access,
   1032                                       int *nof_cores)
   1033 {
   1034     int ncores = 0;
   1035     if (IS_C_PORT(unit, port) || IS_CXX_PORT(unit, port)) {
   1036         phymod_core_access_t core_acc_100g[3];
   1037         portmod_port_core_access_get(unit, port, phyn, 3, core_acc_100g, &ncores, NULL);
   1038         sal_memcpy(core_access, &core_acc_100g[0], sizeof(phymod_core_access_t));
   1039     } else {
   1040         phymod_core_access_t core_acc;
   1041         portmod_port_core_access_get(unit, port, phyn, 1, &core_acc, &ncores, NULL);
   1042         sal_memcpy(core_access, &core_acc, sizeof(phymod_core_access_t));
   1043     }
   1044     *nof_cores = ncores;
   1045     return SOC_E_NONE;
   1046 }
   1047 
   1048 /*!
   1049  * portmod_port_to_phyaddr
   1050  *
   1051  * @brief Get Phy addr for a given port.
   1052  *
   1053  * @param [in]  unit            - unit id
   1054  * @param [in]  port            - logical port
   1055  */
   1056 int portmod_port_to_phyaddr(int unit, int port)
   1057 {
   1058     int nof_cores = 0, phyaddr;
   1059 
   1060     phymod_core_access_t core_acc;
   1061     portmod_port_main_core_access_get(unit, port, -1, &core_acc, &nof_cores);
   1062     phyaddr = (nof_cores == 0)? -1 : core_acc.access.addr;
   1063 
   1064     return (phyaddr);
   1065 }
   1066 
   1067 /*!
   1068  * portmod_port_to_phyaddr_int
   1069  *
   1070  * @brief Get internal Phy addr for a given port.
   1071  *
   1072  * @param [in]  unit            - unit id
   1073  * @param [in]  port            - logical port
   1074  */
   1075 int portmod_port_to_phyaddr_int(int unit, int port)
   1076 {
   1077     phymod_core_access_t internal_core;
   1078     int nof_cores = 0;
   1079 
   1080     portmod_port_core_access_get(unit, port, 0, 1, &internal_core, &nof_cores, NULL);
   1081 
   1082     return ((nof_cores == 0)? -1 : internal_core.access.addr);
   1083 }
   1084 
   1085 int portmod_intf_to_phymod_intf(int unit, int speed, soc_port_if_t interface,
   1086                                        phymod_interface_t *phymod_interface)
   1087 {
   1088     return soc_phymod_phy_intf_from_port_intf(unit, speed, interface, phymod_interface);
   1089 }
   1090 
   1091 int portmod_intf_from_phymod_intf (int unit, 
   1092                                    phymod_interface_t phymod_interface,
   1093                                    soc_port_if_t *interface)
   1094 {
   1095     return soc_phymod_phy_intf_to_port_intf(unit, phymod_interface, interface);
   1096 }
   1097 
   1098 int portmod_line_intf_from_config_get(const portmod_port_interface_config_t *config, soc_port_if_t *interface)
   1099 {
   1100     *interface = (config->line_interface != SOC_PORT_IF_NULL ? config->line_interface : config->interface);
   1101     return SOC_E_NONE;
   1102 }
   1103 
   1104 int
   1105 portmod_port_redirect_loopback_set(int unit, soc_port_t port, 
   1106                                    int phyn, int phy_lane,
   1107                                    int sys_side, uint32 enable)
   1108 {
   1109     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1110     int nof_phys = 0;
   1111     portmod_access_get_params_t params;
   1112     SOC_INIT_FUNC_DEFS;
   1113 
   1114     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   1115     params.lane = phy_lane;
   1116     params.phyn = phyn;
   1117     params.sys_side = (sys_side ? PORTMOD_SIDE_SYSTEM : PORTMOD_SIDE_LINE);
   1118 
   1119     _SOC_IF_ERR_EXIT(portmod_port_phy_lane_access_get(unit, port, &params, 
   1120                                                       PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1121                                                       phy_access, &nof_phys, NULL));
   1122 
   1123     _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_set (unit, port, phy_access, nof_phys, portmodLoopbackPhyGloopPCS, enable));
   1124 
   1125 exit:
   1126     SOC_FUNC_RETURN;
   1127 
   1128 #if 0
   1129     /* leave this code to look  sys_side need to be taken care of. The comment need to delete before commit. tlwin*/
   1130     phymod_phy_access_t phy_access;
   1131     int nof_phys;
   1132     portmod_access_get_params_t params;
   1133 
   1134     portmod_access_get_params_t_init(unit, &params);
   1135     params.lane = phy_lane;
   1136     params.phyn = phyn;
   1137     params.sys_side = (sys_side == 1) ? PORTMOD_SIDE_SYSTEM: PORTMOD_SIDE_LINE;
   1138 
   1139     SOC_IF_ERROR_RETURN(
   1140         portmod_port_phy_lane_access_get(unit,
   1141                                          port,
   1142                                          &params,
   1143                                          1, 
   1144                                          &phy_access,
   1145                                          &nof_phys));
   1146 
   1147     SOC_IF_ERROR_RETURN(phymod_phy_loopback_set(&phy_access, 
   1148                                   portmodLoopbackPhyGloopPCS, enable));
   1149 
   1150     return SOC_E_NONE;
   1151 #endif
   1152 }
   1153 
   1154 int
   1155 portmod_port_redirect_loopback_get(int unit, soc_port_t port, 
   1156                                    int phyn, int phy_lane,
   1157                                    int sys_side, uint32 *enable)
   1158 {
   1159     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1160     int nof_phys = 0;
   1161     portmod_access_get_params_t params;
   1162     SOC_INIT_FUNC_DEFS;
   1163 
   1164     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   1165     params.lane = phy_lane;
   1166     params.phyn = phyn;
   1167     params.sys_side = (sys_side ? PORTMOD_SIDE_SYSTEM : PORTMOD_SIDE_LINE);
   1168 
   1169     _SOC_IF_ERR_EXIT(portmod_port_phy_lane_access_get(unit, port, &params, 
   1170                                                       PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1171                                                       phy_access, &nof_phys, NULL));
   1172 
   1173     _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_get (unit, port, phy_access, nof_phys, portmodLoopbackPhyGloopPCS, enable));
   1174 
   1175 exit:
   1176     SOC_FUNC_RETURN;
   1177 
   1178 #if 0
   1179     /* need to review before deleting this */
   1180     phymod_phy_access_t phy_access;
   1181     int nof_phys;
   1182     portmod_access_get_params_t params;
   1183 
   1184     portmod_access_get_params_t_init(unit, &params);
   1185     params.lane = phy_lane;
   1186     params.phyn = phyn;
   1187     params.sys_side = (sys_side == 1) ? PORTMOD_SIDE_SYSTEM: PORTMOD_SIDE_LINE;
   1188 
   1189     SOC_IF_ERROR_RETURN(
   1190         portmod_port_phy_lane_access_get(unit,
   1191                                          port,
   1192                                          &params,
   1193                                          1, 
   1194                                          &phy_access,
   1195                                          &nof_phys));
   1196 
   1197     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&phy_access, 
   1198                                   portmodLoopbackPhyGloopPCS, enable));
   1199 
   1200     return SOC_E_NONE;
   1201 #endif
   1202 }
   1203 
   1204 int
   1205 portmod_port_redirect_autoneg_set (int unit, soc_port_t port,
   1206                                    int phyn, int phy_lane,
   1207                                    int sys_side, phymod_autoneg_control_t* an)
   1208 {
   1209     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1210     int nof_phys = 0, num_lanes = 0;
   1211     portmod_access_get_params_t params;
   1212     SOC_INIT_FUNC_DEFS;
   1213 
   1214     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   1215     params.lane = phy_lane;
   1216     params.phyn = phyn;
   1217     params.sys_side = (sys_side ? PORTMOD_SIDE_SYSTEM : PORTMOD_SIDE_LINE);
   1218 
   1219     _SOC_IF_ERR_EXIT(portmod_port_lane_count_get(unit, port, !sys_side, &num_lanes));
   1220     an->num_lane_adv = num_lanes;
   1221 
   1222     _SOC_IF_ERR_EXIT(portmod_port_phy_lane_access_get(unit, port, &params, 
   1223                                                       PORT_MAX_PHY_ACCESS_STRUCTURES,
   1224                                                       phy_access, &nof_phys, NULL));
   1225 
   1226     _SOC_IF_ERR_EXIT(portmod_port_phychain_autoneg_set(unit, port, phy_access, nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, an));
   1227 
   1228 exit:
   1229     SOC_FUNC_RETURN;
   1230 }
   1231 
   1232 int
   1233 portmod_port_redirect_autoneg_get (int unit, soc_port_t port,
   1234                                    int phyn, int phy_lane,
   1235                                    int sys_side, phymod_autoneg_control_t* an)
   1236 {
   1237     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1238     int nof_phys = 0;
   1239     uint32_t an_done =0;
   1240     portmod_access_get_params_t params;
   1241     SOC_INIT_FUNC_DEFS;
   1242 
   1243     _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   1244     params.lane = phy_lane;
   1245     params.phyn = phyn;
   1246     params.sys_side = (sys_side ? PORTMOD_SIDE_SYSTEM : PORTMOD_SIDE_LINE);
   1247 
   1248     _SOC_IF_ERR_EXIT(portmod_port_phy_lane_access_get(unit, port, &params, 
   1249                                                       PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1250                                                       phy_access, &nof_phys, NULL));
   1251 
   1252     _SOC_IF_ERR_EXIT(portmod_port_phychain_autoneg_get(unit, port, phy_access, nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, an, &an_done));
   1253 
   1254 exit:
   1255     SOC_FUNC_RETURN;
   1256 }
   1257 
   1258 /*
   1259  * This is a temporary  fix for the PHY_FLAGS_TST code which
   1260  * gets updated in linkscan. Proper code will be added
   1261  */
   1262 int portmod_port_flags_test(int unit, soc_port_t port, int flag)
   1263 {
   1264     phymod_core_access_t core_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1265     phymod_autoneg_control_t an;
   1266     portmod_port_interface_config_t cfg;
   1267     phymod_operation_mode_t  op_mode = 0;
   1268     int is_legacy_present;
   1269 
   1270     int nof_cores = 0, is_most_ext;
   1271 
   1272     /* always get the MOST-EXT phy */
   1273     SOC_IF_ERROR_RETURN(portmod_port_core_access_get(unit, port, -1, PORT_MAX_PHY_ACCESS_STRUCTURES,
   1274                                                      core_access, &nof_cores, &is_most_ext));
   1275     SOC_IF_ERROR_RETURN(
   1276         portmod_port_is_legacy_ext_phy_present(unit, port, &is_legacy_present));
   1277 
   1278     if (is_legacy_present) {
   1279         /* call legacy driver functions */
   1280         return portmod_port_legacy_phy_flags_test(unit, port, flag);
   1281     }
   1282 
   1283     if (nof_cores < 1) return (SOC_E_PARAM);
   1284 
   1285     switch (flag) {
   1286         case PHY_FLAGS_MEDIUM_CHANGE:
   1287              return (0);
   1288              break;
   1289 
   1290         case PHY_FLAGS_C45:
   1291              {
   1292              return (PHYMOD_ACC_F_CLAUSE45_GET(&core_access[0].access));
   1293              }
   1294              break;
   1295 
   1296         case PHY_FLAGS_EXTERNAL_PHY:
   1297              {
   1298               /* whether exists ext-phy */
   1299              SOC_IF_ERROR_RETURN(portmod_port_core_access_get(unit, port, 1, PORT_MAX_PHY_ACCESS_STRUCTURES,
   1300                                                               core_access, &nof_cores, &is_most_ext));
   1301              return (nof_cores ? 1 : 0);
   1302              }
   1303              break;
   1304 
   1305         case PHY_FLAGS_FORCED_SGMII:
   1306              SOC_IF_ERROR_RETURN(portmod_port_autoneg_get(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &an));
   1307              if (an.enable) return (0);
   1308 
   1309              SOC_IF_ERROR_RETURN(portmod_port_interface_config_get(unit, port, &cfg, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   1310              return ((cfg.interface == SOC_PORT_IF_SGMII)? 1 : 0);
   1311              break;
   1312 
   1313         case PHY_FLAGS_REPEATER:
   1314              SOC_IF_ERROR_RETURN(portmod_port_phy_op_mode_get(unit, port, &op_mode));
   1315              return ((op_mode == phymodOperationModeRetimer) ? 0 : 1);
   1316              break;
   1317 
   1318         default:
   1319              break;
   1320     }
   1321 
   1322     return (SOC_E_UNAVAIL);
   1323 }
   1324 
   1325 int portmod_port_chain_core_access_get(int unit, int port, pm_info_t pm_info, phymod_core_access_t* core_access_arr, int max_buf, int* nof_cores)
   1326 {
   1327     int phyn = 0, is_most_ext = 0, core_count;
   1328     int arr_idx = 0, rv;
   1329     SOC_INIT_FUNC_DEFS;
   1330     
   1331     while (!is_most_ext) {
   1332 
   1333         if (max_buf <= 0) { /* buffer protection */
   1334             _SOC_EXIT_WITH_ERR(SOC_E_FULL, (_SOC_MSG("max buffer size exceeded.")));
   1335         }
   1336 
   1337         rv = __portmod__dispatch__[pm_info->type]->f_portmod_port_core_access_get(unit, port, pm_info, phyn, max_buf, &(core_access_arr[arr_idx]), &core_count, &is_most_ext);
   1338         _SOC_IF_ERR_EXIT(rv);
   1339         arr_idx += core_count;
   1340         phyn++;
   1341         max_buf -= core_count;
   1342     }
   1343 
   1344     *nof_cores = arr_idx;
   1345 
   1346 exit:
   1347     SOC_FUNC_RETURN; 
   1348     
   1349 }
   1350 
   1351 int portmod_port_chain_phy_access_get(int unit, int port, pm_info_t pm_info, phymod_phy_access_t* core_access_arr, int max_buf, int* nof_cores)
   1352 {
   1353     int phyn = 0, is_most_ext = 0, core_count, arr_idx = 0, rv;
   1354     portmod_access_get_params_t params;
   1355     SOC_INIT_FUNC_DEFS;
   1356 
   1357     while (!is_most_ext) {
   1358 
   1359         if (max_buf <= 0) { /* buffer protection */
   1360             _SOC_EXIT_WITH_ERR(SOC_E_FULL, (_SOC_MSG("max buffer size exceeded.")));
   1361         }
   1362 
   1363         _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, &params));
   1364         params.phyn = phyn;
   1365         rv = __portmod__dispatch__[pm_info->type]->f_portmod_port_phy_lane_access_get(unit, port, pm_info, &params, max_buf, &(core_access_arr[arr_idx]), &core_count, &is_most_ext);
   1366         _SOC_IF_ERR_EXIT(rv);
   1367 
   1368         arr_idx += core_count;
   1369         phyn++;
   1370         max_buf -= core_count;
   1371     }
   1372 
   1373     *nof_cores = arr_idx;
   1374 
   1375 exit:
   1376     SOC_FUNC_RETURN; 
   1377     
   1378 }
   1379 int portmod_ext_to_int_cmd_set(int unit, int port, portmod_ext_to_int_phy_ctrlcode_t cmd, void *data) {
   1380     pm_info_t pm_info;
   1381     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1382     int chain_length = 0, flags = 0, is_intf_valid = 0, spacing_value = 0;
   1383     phymod_autoneg_control_t *an;
   1384     portmod_port_ability_t *port_ability;
   1385 
   1386     portmod_port_interface_config_t interface_config;
   1387 
   1388     int *cmd_data = (int *)data;
   1389 
   1390     SOC_INIT_FUNC_DEFS;
   1391 
   1392     _SOC_IF_ERR_EXIT(portmod_pm_info_get(unit, port, &pm_info));
   1393 
   1394     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
   1395                                                        PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1396                                                        &chain_length));
   1397     sal_memset(&interface_config, 0, sizeof(interface_config));
   1398 
   1399    /* call portmod_port_chain function */
   1400     switch(cmd) {
   1401         case portmodExtToInt_CtrlCode_Link:
   1402             break;
   1403         case portmodExtToInt_CtrlCode_Enable:
   1404             PORTMOD_PORT_ENABLE_PHY_SET(flags);
   1405             PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_SET(flags);
   1406             _SOC_IF_ERR_EXIT(portmod_port_enable_set(unit, port, flags, *cmd_data));
   1407             break;
   1408         case portmodExtToInt_CtrlCode_Speed:
   1409             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit, port, &interface_config, 
   1410                                               PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   1411             interface_config.speed = *cmd_data;    
   1412             _SOC_IF_ERR_EXIT(portmod_port_interface_config_set(unit, port, &interface_config, 
   1413                                               PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1414             break;
   1415         case portmodExtToInt_CtrlCode_Interface:
   1416             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit, port, &interface_config,    
   1417                                               PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));    
   1418             interface_config.interface = *cmd_data;
   1419 
   1420             /*
   1421              * Some legacy external PHYs call portmod_ext_to_int_cmd_set() twice. First
   1422              * with cmd portmodExtToInt_CtrlCode_Interface followed by cmd
   1423              * portmodExtToInt_CtrlCode_Speed. During system init it is possible that
   1424              * the internal PHY is still in its default state, so the speed fetched from
   1425              * the above portmod_port_interface_config_get() call may not be compatible
   1426              * with the new interface type (cmd_data). In this case the wrong speed +
   1427              * interface config should not be provided to the internal PHY.
   1428              */
   1429             _SOC_IF_ERR_EXIT(portmod_port_interface_check(unit, port, &interface_config,
   1430                                                           0, *cmd_data, &is_intf_valid));
   1431             if (!is_intf_valid) {
   1432                 return SOC_E_PARAM;
   1433             }
   1434 
   1435             _SOC_IF_ERR_EXIT(portmod_port_interface_config_set(unit, port, &interface_config, 
   1436                                               PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1437             break;
   1438         case portmodExtToInt_CtrlCode_AN:
   1439             an = (phymod_autoneg_control_t *)data;
   1440             _SOC_IF_ERR_EXIT(portmod_port_autoneg_set(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, an));
   1441             break;  
   1442         case portmodExtToInt_CtrlCode_AbilityAdvert:
   1443             port_ability = (portmod_port_ability_t *)data;
   1444             _SOC_IF_ERR_EXIT(portmod_port_ability_advert_set(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, port_ability));
   1445             break;      
   1446         case portmodExtToInt_CtrlCode_SpeedLine:
   1447             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit, port, &interface_config,
   1448                                               PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1449             if ((*cmd_data == 2500) && (interface_config.speed == 10000)) {
   1450                 spacing_value = MAC_WAN_MODE_THROTTLE_10G_TO_2P5G;
   1451             } else if ((*cmd_data == 5000) && (interface_config.speed == 10000)) {
   1452                 spacing_value = MAC_WAN_MODE_THROTTLE_10G_TO_5G;
   1453             }
   1454             _SOC_IF_ERR_EXIT(portmod_port_frame_spacing_stretch_set(unit, port, spacing_value));
   1455             break;
   1456         default:
   1457             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, ("Invalid command input %d\n", cmd));
   1458     }
   1459 
   1460    /* call portmod_port_chain function */
   1461 exit:
   1462     SOC_FUNC_RETURN; 
   1463    
   1464 
   1465 }
   1466 
   1467 
   1468 int portmod_ext_to_int_cmd_get(int unit, int port, portmod_ext_to_int_phy_ctrlcode_t cmd, void *data) {
   1469     pm_info_t pm_info;
   1470     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1471     int chain_length = 0;
   1472     uint32 flags = 0;
   1473     portmod_port_interface_config_t interface_config;
   1474     phymod_autoneg_control_t *an;
   1475     portmod_port_ability_t *port_ability;
   1476 
   1477     int value;
   1478     int *cmd_data = (int *)data;
   1479 
   1480     SOC_INIT_FUNC_DEFS;
   1481 
   1482     _SOC_IF_ERR_EXIT(portmod_pm_info_get(unit, port, &pm_info));
   1483 
   1484     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
   1485                                                        PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1486                                                        &chain_length));
   1487     sal_memset(&interface_config, 0, sizeof(interface_config));
   1488 
   1489     /* call portmod_port_chain function */
   1490     switch(cmd) {
   1491         case portmodExtToInt_CtrlCode_Link:
   1492             _SOC_IF_ERR_EXIT(portmod_port_link_get(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, &value));
   1493             *cmd_data = value;
   1494             break;
   1495     case portmodExtToInt_CtrlCode_Enable:
   1496             PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_SET(flags);
   1497             _SOC_IF_ERR_EXIT(portmod_port_enable_get(unit, port, flags, &value));
   1498             *cmd_data = value;
   1499             break;
   1500         case portmodExtToInt_CtrlCode_Speed:
   1501             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit, port, &interface_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1502             *cmd_data = interface_config.speed;
   1503             break;
   1504         case portmodExtToInt_CtrlCode_Interface:
   1505             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit, port, &interface_config, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1506             *cmd_data = interface_config.interface;
   1507             break;
   1508         case portmodExtToInt_CtrlCode_AN:
   1509             an = (phymod_autoneg_control_t *)data;
   1510             _SOC_IF_ERR_EXIT(portmod_port_autoneg_get(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, an));
   1511             break;
   1512         case portmodExtToInt_CtrlCode_AbilityAdvert:
   1513             port_ability = (portmod_port_ability_t *)data;
   1514             _SOC_IF_ERR_EXIT(portmod_port_ability_advert_get(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, port_ability));
   1515             break;
   1516         case portmodExtToInt_CtrlCode_AbilityLocal:
   1517             port_ability = (portmod_port_ability_t *)data;
   1518             _SOC_IF_ERR_EXIT(portmod_port_ability_local_get(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, port_ability));
   1519             break;                   
   1520         case portmodExtToInt_CtrlCode_AbilityRemote:
   1521             port_ability = (portmod_port_ability_t *)data;
   1522             _SOC_IF_ERR_EXIT(portmod_port_ability_remote_get(unit, port, PORTMOD_INIT_F_INTERNAL_SERDES_ONLY, port_ability));
   1523             break;
   1524         default:
   1525             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, ("Invalid command input %d\n", cmd));
   1526     }
   1527 
   1528 exit:
   1529     SOC_FUNC_RETURN; 
   1530 
   1531 }
   1532 
   1533 int portmod_port_is_legacy_ext_phy_present(int unit, int port, int *is_legacy_present) {
   1534     pm_info_t pm_info;
   1535     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1536     int chain_length = 0;
   1537     portmod_dispatch_type_t __type__;
   1538     int ext_phy_threshold = 1;
   1539 
   1540     SOC_INIT_FUNC_DEFS;
   1541 
   1542     *is_legacy_present = 0;
   1543 
   1544     if (IS_IL_PORT(unit, port)) {
   1545         /* ILKN does not support ext phy */
   1546         SOC_EXIT;
   1547     }
   1548     _SOC_IF_ERR_EXIT(portmod_port_pm_type_get(unit, port, &port, &__type__));
   1549 
   1550     _SOC_IF_ERR_EXIT(portmod_pm_info_get(unit, port, &pm_info));
   1551 
   1552     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
   1553                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1554                                                         &chain_length));
   1555 
   1556 #ifdef PORTMOD_PM12X10_SUPPORT
   1557     if (__type__ == portmodDispatchTypePm12x10) {
   1558         ext_phy_threshold = 3;
   1559     }
   1560 #endif /*PORTMOD_PM12X10_SUPPORT  */
   1561 
   1562 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
   1563      if (__type__ == portmodDispatchTypePm12x10_xgs) {
   1564         ext_phy_threshold = 3;
   1565     }
   1566 #endif /*PORTMOD_PM12X10_XGS_SUPPORT  */
   1567     
   1568     if (chain_length > ext_phy_threshold) {
   1569         /* external phy is present in this system */
   1570         _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_get(unit, phy_access[chain_length - 1].access.addr, is_legacy_present));
   1571     }   
   1572 exit:
   1573     SOC_FUNC_RETURN; 
   1574 
   1575 }
   1576 
   1577 int portmod_port_ext_phy_control_set(int unit, int port, int phyn, int phy_lane, int sys_side,
   1578                                      soc_phy_control_t control, uint32 value) {
   1579 
   1580     portmod_dispatch_type_t __type__;
   1581 
   1582     SOC_INIT_FUNC_DEFS;
   1583 
   1584     _SOC_IF_ERR_EXIT(portmod_port_pm_type_get(unit, port, &port, &__type__));
   1585 
   1586     _SOC_IF_ERR_EXIT(portmod_port_legacy_phy_control_set(unit, port, phyn, phy_lane, sys_side,
   1587                                                control, value));
   1588 
   1589     exit:
   1590         SOC_FUNC_RETURN;
   1591 }
   1592 
   1593 int portmod_port_ext_phy_control_get(int unit, int port, int phyn, int phy_lane, int sys_side, 
   1594                                      soc_phy_control_t control, uint32* value) {
   1595 
   1596     portmod_dispatch_type_t __type__;
   1597 
   1598     SOC_INIT_FUNC_DEFS;
   1599 
   1600     _SOC_IF_ERR_EXIT(portmod_port_pm_type_get(unit, port, &port, &__type__));
   1601 
   1602     /*
   1603      * _SOC_IF_ERR_EXIT() could cause unwanted error message printings if it is used in
   1604      * the following function call.
   1605      */
   1606     return portmod_port_legacy_phy_control_get(unit, port, phyn, phy_lane, sys_side,
   1607                                                control, value);
   1608 
   1609     exit:
   1610         SOC_FUNC_RETURN;
   1611 }
   1612 
   1613 int portmod_port_ext_phy_mdix_set(int unit, int port, soc_port_mdix_t mode) {
   1614     return portmod_port_legacy_phy_mdix_set(unit, port, mode);
   1615 }
   1616 
   1617 int portmod_port_ext_phy_mdix_get(int unit, int port, soc_port_mdix_t *mode) {
   1618     return portmod_port_legacy_phy_mdix_get(unit, port, mode);
   1619 }
   1620 
   1621 int portmod_port_ext_phy_mdix_status_get(int unit, soc_port_t port,
   1622                                          soc_port_mdix_status_t *status) {
   1623     return portmod_port_legacy_phy_mdix_status_get(unit, port, status);
   1624 }
   1625 
   1626 
   1627 int portmod_port_status_notify(int unit, int port, int link)
   1628 {
   1629     pm_info_t pm_info;
   1630     phymod_phy_access_t phy_access[PORT_MAX_PHY_ACCESS_STRUCTURES];
   1631     int chain_length = 0;
   1632     portmod_port_interface_config_t interface_config;
   1633 
   1634     SOC_INIT_FUNC_DEFS;
   1635  
   1636     _SOC_IF_ERR_EXIT(portmod_pm_info_get(unit, port, &pm_info));
   1637 
   1638     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
   1639                                                         PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1640                                                         &chain_length));
   1641     _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access, 
   1642                                                        PORT_MAX_PHY_ACCESS_STRUCTURES, 
   1643                                                        &chain_length));
   1644   
   1645     sal_memset(&interface_config, 0 , sizeof(interface_config));
   1646 
   1647     if (link) {
   1648         if (chain_length > 1) {
   1649             /* get the line side speed and program the internal phy 
   1650             * to the same speed */
   1651             _SOC_IF_ERR_EXIT(portmod_port_interface_config_get(unit,
   1652                                                                port,
   1653                                                                &interface_config,
   1654                                                                PORTMOD_INIT_F_EXTERNAL_MOST_ONLY));
   1655             /* set the speed for internal phy */
   1656             _SOC_IF_ERR_EXIT(portmod_port_interface_config_set(unit,
   1657                                                                port,
   1658                                                                &interface_config, 
   1659                                                                PORTMOD_INIT_F_INTERNAL_SERDES_ONLY));
   1660         }
   1661     } else {
   1662         /* TBD Disable the internal PHY */
   1663     }
   1664 
   1665 exit:
   1666     SOC_FUNC_RETURN; 
   1667 }
   1668 #define PORTMOD_IF_ERROR_RETURN(_op)   _SHR_E_IF_ERROR_RETURN(_op)
   1669 
   1670 int portmod_common_timesync_config_set(const phymod_phy_access_t* phy_access,
   1671                                        const portmod_phy_timesync_config_t* conf)
   1672 {
   1673     phymod_timesync_config_t  ts_conf;
   1674 
   1675     PORTMOD_IF_ERROR_RETURN(
   1676         phymod_timesync_config_get(phy_access, &ts_conf));
   1677 
   1678     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_FLAGS) {
   1679 
   1680         if (conf->flags & SOC_PORT_PHY_TIMESYNC_ENABLE) {
   1681             phymod_timesync_enable_set(phy_access, 0, TRUE);
   1682         } else {
   1683             phymod_timesync_enable_set(phy_access, 0, FALSE);
   1684         }
   1685 
   1686         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TS_ENABLE) {
   1687             PHYMOD_TS_F_CAPTURE_TS_ENABLE_SET(ts_conf.flags);
   1688         } else {
   1689             PHYMOD_TS_F_CAPTURE_TS_ENABLE_CLR(ts_conf.flags);
   1690         }
   1691 
   1692         if (conf->flags & SOC_PORT_PHY_TIMESYNC_HEARTBEAT_TS_ENABLE) {
   1693             PHYMOD_TS_F_HEARTBEAT_TS_ENABLE_SET(ts_conf.flags);
   1694         } else {
   1695             PHYMOD_TS_F_HEARTBEAT_TS_ENABLE_CLR(ts_conf.flags);
   1696         }
   1697 
   1698         if (conf->flags & SOC_PORT_PHY_TIMESYNC_RX_CRC_ENABLE) {
   1699             PHYMOD_TS_F_RX_CRC_ENABLE_SET(ts_conf.flags);
   1700         } else {
   1701             PHYMOD_TS_F_RX_CRC_ENABLE_CLR(ts_conf.flags);
   1702         }
   1703 
   1704         if (conf->flags & SOC_PORT_PHY_TIMESYNC_8021AS_ENABLE) {
   1705             PHYMOD_TS_F_8021AS_ENABLE_SET(ts_conf.flags);
   1706         } else {
   1707             PHYMOD_TS_F_8021AS_ENABLE_CLR(ts_conf.flags);
   1708         }
   1709 
   1710         if (conf->flags & SOC_PORT_PHY_TIMESYNC_L2_ENABLE) {
   1711             PHYMOD_TS_F_L2_ENABLE_SET(ts_conf.flags);
   1712         } else {
   1713             PHYMOD_TS_F_L2_ENABLE_CLR(ts_conf.flags);
   1714         }
   1715 
   1716         if (conf->flags & SOC_PORT_PHY_TIMESYNC_IP4_ENABLE) {
   1717             PHYMOD_TS_F_IP4_ENABLE_SET(ts_conf.flags);
   1718         } else {
   1719             PHYMOD_TS_F_IP4_ENABLE_CLR(ts_conf.flags);
   1720         }
   1721 
   1722         if (conf->flags & SOC_PORT_PHY_TIMESYNC_IP6_ENABLE) {
   1723             PHYMOD_TS_F_IP6_ENABLE_SET(ts_conf.flags);
   1724         } else {
   1725             PHYMOD_TS_F_IP6_ENABLE_CLR(ts_conf.flags);
   1726         }
   1727 
   1728         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CLOCK_SRC_EXT) {
   1729             PHYMOD_TS_F_CLOCK_SRC_EXT_SET(ts_conf.flags);
   1730         } else {
   1731             PHYMOD_TS_F_CLOCK_SRC_EXT_CLR(ts_conf.flags);
   1732         }
   1733 
   1734         if (conf->flags & SOC_PORT_PHY_TIMESYNC_64BIT_TIMESTAMP_ENABLE) {
   1735             PHYMOD_TS_F_64BIT_TIMESTAMP_ENABLE_SET(ts_conf.flags);
   1736         } else {
   1737             PHYMOD_TS_F_64BIT_TIMESTAMP_ENABLE_CLR(ts_conf.flags);
   1738         }
   1739 
   1740         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_SYNC) {
   1741             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_SYNC_SET(ts_conf.flags);
   1742         }
   1743 
   1744         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_DELAY_REQ) {
   1745             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_DELAY_REQ_SET(ts_conf.flags);
   1746         }
   1747 
   1748         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_PDELAY_REQ) {
   1749             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_PDELAY_REQ_SET(ts_conf.flags);
   1750         }
   1751 
   1752         if (conf->
   1753             flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_PDELAY_RESP) {
   1754             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_PDELAY_RESP_SET(ts_conf.flags);
   1755         }
   1756 
   1757         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_SYNC) {
   1758             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_SYNC_SET(ts_conf.flags);
   1759         }
   1760 
   1761         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_DELAY_REQ) {
   1762             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_DELAY_REQ_SET(ts_conf.flags);
   1763         }
   1764 
   1765         if (conf->flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_PDELAY_REQ) {
   1766             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_PDELAY_REQ_SET(ts_conf.flags);
   1767         }
   1768 
   1769         if (conf->
   1770             flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_PDELAY_RESP) {
   1771             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_PDELAY_RESP_SET(ts_conf.flags);
   1772         }
   1773     }
   1774 
   1775     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_ITPID) {
   1776         ts_conf.itpid = conf->itpid;
   1777     }
   1778 
   1779     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_OTPID) {
   1780         ts_conf.otpid = conf->otpid;
   1781     }
   1782 
   1783     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_OTPID2) {
   1784         ts_conf.otpid2 = conf->otpid2;
   1785     }
   1786 
   1787     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TS_DIVIDER) {
   1788         ts_conf.ts_divider= conf->ts_divider;
   1789     }
   1790 
   1791     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_LINK_DELAY) {
   1792         ts_conf.rx_link_delay= conf->rx_link_delay;
   1793     }
   1794 
   1795     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_ORIGINAL_TIMECODE) {
   1796         sal_memcpy(&ts_conf.original_timecode, &conf->original_timecode,
   1797                    sizeof(phymod_timesync_timespec_t));
   1798     }
   1799 
   1800     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_GMODE) {
   1801         /* coverity[mixed_enums] */
   1802         ts_conf.gmode = conf->gmode;
   1803     }
   1804 
   1805     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_FRAMESYNC_MODE) {
   1806         PORTMOD_IF_ERROR_RETURN(
   1807             phymod_timesync_framesync_mode_set(phy_access,
   1808                 (portmod_timesync_framesync_t*) &conf->framesync));
   1809     }
   1810 
   1811     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_SYNCOUT_MODE) {
   1812         sal_memcpy(&ts_conf.syncout, &conf->syncout,
   1813                    sizeof(phymod_timesync_syncout_t));
   1814     }
   1815 
   1816     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_TIMESTAMP_OFFSET) {
   1817         PORTMOD_IF_ERROR_RETURN(
   1818             phymod_timesync_rx_timestamp_offset_set(phy_access,
   1819                                                conf->rx_timestamp_offset));
   1820     }
   1821 
   1822     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_TIMESTAMP_OFFSET) {
   1823         PORTMOD_IF_ERROR_RETURN(
   1824             phymod_timesync_tx_timestamp_offset_set(phy_access,
   1825                                                conf->tx_timestamp_offset));
   1826     }
   1827 
   1828     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_SYNC_MODE) {
   1829         /* coverity[mixed_enums] */
   1830         ts_conf.tx_sync_mode = conf->tx_sync_mode;
   1831     }
   1832 
   1833     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_DELAY_REQUEST_MODE) {
   1834         /* coverity[mixed_enums] */
   1835         ts_conf.tx_delay_req_mode = conf->tx_delay_request_mode;
   1836     }
   1837 
   1838     if (conf->
   1839         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_PDELAY_REQUEST_MODE) {
   1840         /* coverity[mixed_enums] */
   1841         ts_conf.tx_pdelay_req_mode = conf->tx_pdelay_request_mode;
   1842     }
   1843 
   1844     if (conf->
   1845         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_PDELAY_RESPONSE_MODE) {
   1846         /* coverity[mixed_enums] */
   1847         ts_conf.tx_pdelay_resp_mode = conf->tx_pdelay_response_mode;
   1848     }
   1849 
   1850     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_SYNC_MODE) {
   1851         /* coverity[mixed_enums] */
   1852         ts_conf.rx_sync_mode = conf->rx_sync_mode;
   1853     }
   1854 
   1855     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_DELAY_REQUEST_MODE) {
   1856         /* coverity[mixed_enums] */
   1857         ts_conf.rx_delay_req_mode = conf->rx_delay_request_mode;
   1858     }
   1859 
   1860     if (conf->
   1861         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_PDELAY_REQUEST_MODE) {
   1862         /* coverity[mixed_enums] */
   1863         ts_conf.rx_pdelay_req_mode = conf->rx_pdelay_request_mode;
   1864     }
   1865 
   1866     if (conf->
   1867         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_PDELAY_RESPONSE_MODE) {
   1868         /* coverity[mixed_enums] */
   1869         ts_conf.rx_pdelay_resp_mode = conf->rx_pdelay_response_mode;
   1870     }
   1871 
   1872     if (conf->
   1873         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_REF_PHASE) {
   1874         ts_conf.phy_1588_dpll_ref_phase = conf->phy_1588_dpll_ref_phase;
   1875     }
   1876 
   1877     if (conf->
   1878         validity_mask &
   1879         SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_REF_PHASE_DELTA) {
   1880         ts_conf.phy_1588_dpll_ref_phase_delta = conf->phy_1588_dpll_ref_phase_delta;
   1881     }
   1882 
   1883     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K1) {
   1884         ts_conf.phy_1588_dpll_k1 = conf->phy_1588_dpll_k1;
   1885     }
   1886 
   1887     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K2) {
   1888         ts_conf.phy_1588_dpll_k2 = conf->phy_1588_dpll_k2;
   1889     }
   1890 
   1891     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K3) {
   1892         ts_conf.phy_1588_dpll_k3 = conf->phy_1588_dpll_k3;
   1893     }
   1894 
   1895     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_MPLS_CONTROL) {
   1896         sal_memcpy(&ts_conf.mpls_ctrl, &conf->mpls_control,
   1897                    sizeof(phymod_timesync_mpls_ctrl_t));
   1898     }
   1899 
   1900     PORTMOD_IF_ERROR_RETURN(
   1901         phymod_timesync_config_set(phy_access, &ts_conf));
   1902 
   1903     return SOC_E_NONE;
   1904 }
   1905 
   1906 
   1907 int portmod_common_timesync_config_get(const phymod_phy_access_t* phy_access,
   1908                                        portmod_phy_timesync_config_t* conf)
   1909 {
   1910     uint32 enable;
   1911     phymod_timesync_config_t  ts_conf;
   1912 
   1913     PORTMOD_IF_ERROR_RETURN(
   1914         phymod_timesync_config_get(phy_access, &ts_conf));
   1915 
   1916     conf->flags = 0;
   1917 
   1918     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_FLAGS) {
   1919         PORTMOD_IF_ERROR_RETURN(
   1920             phymod_timesync_enable_get(phy_access, 0, &enable));
   1921 
   1922         if(enable) {
   1923             conf->flags |= SOC_PORT_PHY_TIMESYNC_ENABLE;
   1924         } else {
   1925             conf->flags &= ~SOC_PORT_PHY_TIMESYNC_ENABLE;
   1926         }
   1927 
   1928         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TS_ENABLE) {
   1929             PHYMOD_TS_F_CAPTURE_TS_ENABLE_SET(conf->flags);
   1930         } else {
   1931             PHYMOD_TS_F_CAPTURE_TS_ENABLE_CLR(conf->flags);
   1932         }
   1933 
   1934         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_HEARTBEAT_TS_ENABLE) {
   1935             PHYMOD_TS_F_HEARTBEAT_TS_ENABLE_SET(conf->flags);
   1936         } else {
   1937             PHYMOD_TS_F_HEARTBEAT_TS_ENABLE_CLR(conf->flags);
   1938         }
   1939 
   1940         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_RX_CRC_ENABLE) {
   1941             PHYMOD_TS_F_RX_CRC_ENABLE_SET(conf->flags);
   1942         } else {
   1943             PHYMOD_TS_F_RX_CRC_ENABLE_CLR(conf->flags);
   1944         }
   1945 
   1946         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_8021AS_ENABLE) {
   1947             PHYMOD_TS_F_8021AS_ENABLE_SET(conf->flags);
   1948         } else {
   1949             PHYMOD_TS_F_8021AS_ENABLE_CLR(conf->flags);
   1950         }
   1951 
   1952         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_L2_ENABLE) {
   1953             PHYMOD_TS_F_L2_ENABLE_SET(conf->flags);
   1954         } else {
   1955             PHYMOD_TS_F_L2_ENABLE_CLR(conf->flags);
   1956         }
   1957 
   1958         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_IP4_ENABLE) {
   1959             PHYMOD_TS_F_IP4_ENABLE_SET(conf->flags);
   1960         } else {
   1961             PHYMOD_TS_F_IP4_ENABLE_CLR(conf->flags);
   1962         }
   1963 
   1964         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_IP6_ENABLE) {
   1965             PHYMOD_TS_F_IP6_ENABLE_SET(conf->flags);
   1966         } else {
   1967             PHYMOD_TS_F_IP6_ENABLE_CLR(conf->flags);
   1968         }
   1969 
   1970         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CLOCK_SRC_EXT) {
   1971             PHYMOD_TS_F_CLOCK_SRC_EXT_SET(conf->flags);
   1972         } else {
   1973             PHYMOD_TS_F_CLOCK_SRC_EXT_CLR(conf->flags);
   1974         }
   1975 
   1976         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_64BIT_TIMESTAMP_ENABLE) {
   1977             PHYMOD_TS_F_64BIT_TIMESTAMP_ENABLE_SET(conf->flags);
   1978         } else {
   1979             PHYMOD_TS_F_64BIT_TIMESTAMP_ENABLE_CLR(conf->flags);
   1980         }
   1981 
   1982         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_SYNC) {
   1983             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_SYNC_SET(conf->flags);
   1984         }
   1985 
   1986         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_DELAY_REQ) {
   1987             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_DELAY_REQ_SET(conf->flags);
   1988         }
   1989 
   1990         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_PDELAY_REQ) {
   1991             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_PDELAY_REQ_SET(conf->flags);
   1992         }
   1993 
   1994         if (ts_conf.flags
   1995             & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_TX_PDELAY_RESP) {
   1996             PHYMOD_TS_F_CAPTURE_TIMESTAMP_TX_PDELAY_RESP_SET(conf->flags);
   1997         }
   1998 
   1999         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_SYNC) {
   2000             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_SYNC_SET(conf->flags);
   2001         }
   2002 
   2003         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_DELAY_REQ) {
   2004             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_DELAY_REQ_SET(conf->flags);
   2005         }
   2006 
   2007         if (ts_conf.flags & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_PDELAY_REQ) {
   2008             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_PDELAY_REQ_SET(conf->flags);
   2009         }
   2010 
   2011         if (ts_conf.flags
   2012             & SOC_PORT_PHY_TIMESYNC_CAPTURE_TIMESTAMP_RX_PDELAY_RESP) {
   2013             PHYMOD_TS_F_CAPTURE_TIMESTAMP_RX_PDELAY_RESP_SET(conf->flags);
   2014         }
   2015     }
   2016 
   2017     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_ITPID) {
   2018         conf->itpid = ts_conf.itpid;
   2019     }
   2020 
   2021     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_OTPID) {
   2022         conf->otpid = ts_conf.otpid;
   2023     }
   2024 
   2025     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_OTPID2) {
   2026         conf->otpid2 = ts_conf.otpid2;
   2027     }
   2028 
   2029     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TS_DIVIDER) {
   2030         conf->ts_divider= ts_conf.ts_divider;
   2031     }
   2032 
   2033     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_LINK_DELAY) {
   2034         conf->rx_link_delay= ts_conf.rx_link_delay;
   2035     }
   2036 
   2037     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_ORIGINAL_TIMECODE) {
   2038         sal_memcpy(&conf->original_timecode, &ts_conf.original_timecode,
   2039                    sizeof(phymod_timesync_timespec_t));
   2040     }
   2041 
   2042     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_GMODE) {
   2043         /* coverity[mixed_enums] */
   2044         conf->gmode = ts_conf.gmode;
   2045     }
   2046 
   2047     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_FRAMESYNC_MODE) {
   2048         PORTMOD_IF_ERROR_RETURN(
   2049             phymod_timesync_framesync_mode_get(phy_access,
   2050                     (portmod_timesync_framesync_t*) &conf->framesync));
   2051     }
   2052 
   2053     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_SYNCOUT_MODE) {
   2054         sal_memcpy(&conf->syncout, &ts_conf.syncout,
   2055                    sizeof(phymod_timesync_syncout_t));
   2056     }
   2057 
   2058     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_TIMESTAMP_OFFSET) {
   2059         PORTMOD_IF_ERROR_RETURN(
   2060             phymod_timesync_rx_timestamp_offset_get(phy_access,
   2061                                                    &conf->rx_timestamp_offset));
   2062     }
   2063 
   2064     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_TIMESTAMP_OFFSET) {
   2065         PORTMOD_IF_ERROR_RETURN(
   2066             phymod_timesync_tx_timestamp_offset_get(phy_access,
   2067                                                    &conf->tx_timestamp_offset));
   2068     }
   2069 
   2070     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_SYNC_MODE) {
   2071         /* coverity[mixed_enums] */
   2072         conf->tx_sync_mode = ts_conf.tx_sync_mode;
   2073     }
   2074 
   2075     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_DELAY_REQUEST_MODE) {
   2076         /* coverity[mixed_enums] */
   2077         conf->tx_delay_request_mode = ts_conf.tx_delay_req_mode;
   2078     }
   2079 
   2080     if (conf->
   2081         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_PDELAY_REQUEST_MODE) {
   2082         /* coverity[mixed_enums] */
   2083         conf->tx_pdelay_request_mode = ts_conf.tx_pdelay_req_mode;
   2084     }
   2085 
   2086     if (conf->
   2087         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_TX_PDELAY_RESPONSE_MODE) {
   2088         /* coverity[mixed_enums] */
   2089         conf->tx_pdelay_response_mode = ts_conf.tx_pdelay_resp_mode;
   2090     }
   2091 
   2092 
   2093     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_SYNC_MODE) {
   2094         /* coverity[mixed_enums] */
   2095         conf->rx_sync_mode = ts_conf.rx_sync_mode;
   2096     }
   2097 
   2098     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_DELAY_REQUEST_MODE) {
   2099         /* coverity[mixed_enums] */
   2100         conf->rx_delay_request_mode = ts_conf.rx_delay_req_mode;
   2101     }
   2102 
   2103     if (conf->
   2104         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_PDELAY_REQUEST_MODE) {
   2105         /* coverity[mixed_enums] */
   2106         conf->rx_pdelay_request_mode = ts_conf.rx_pdelay_req_mode;
   2107     }
   2108 
   2109     if (conf->
   2110         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_RX_PDELAY_RESPONSE_MODE) {
   2111         /* coverity[mixed_enums] */
   2112         conf->rx_pdelay_response_mode = ts_conf.rx_pdelay_resp_mode;
   2113     }
   2114 
   2115     if (conf->
   2116         validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_REF_PHASE) {
   2117         conf->phy_1588_dpll_ref_phase = ts_conf.phy_1588_dpll_ref_phase;
   2118     }
   2119 
   2120     if (conf->
   2121         validity_mask &
   2122         SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_REF_PHASE_DELTA) {
   2123         conf->phy_1588_dpll_ref_phase_delta = ts_conf.phy_1588_dpll_ref_phase_delta;
   2124     }
   2125 
   2126     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K1) {
   2127         conf->phy_1588_dpll_k1 = ts_conf.phy_1588_dpll_k1;
   2128     }
   2129 
   2130     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K2) {
   2131         conf->phy_1588_dpll_k2 = ts_conf.phy_1588_dpll_k2;
   2132     }
   2133 
   2134     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_PHY_1588_DPLL_K3) {
   2135         conf->phy_1588_dpll_k3 = ts_conf.phy_1588_dpll_k3;
   2136     }
   2137 
   2138     if (conf->validity_mask & SOC_PORT_PHY_TIMESYNC_VALID_MPLS_CONTROL) {
   2139         sal_memcpy(&conf->mpls_control, &ts_conf.mpls_ctrl,
   2140                    sizeof(phymod_timesync_mpls_ctrl_t));
   2141     }
   2142 
   2143     return SOC_E_NONE;
   2144 }
   2145 
   2146 int portmod_media_type_from_port_intf(int unit, soc_port_if_t interface,
   2147                                        phymod_phy_inf_config_t *phy_interface_config)
   2148 {
   2149     return soc_phymod_media_type_from_port_intf(unit, interface, phy_interface_config);
   2150 }
   2151 
   2152 int portmod_intf_mode_from_phymod_intf(int unit, phymod_interface_t phymod_interface,
   2153                                        phymod_phy_inf_config_t *phy_interface_config)
   2154 {
   2155     return soc_phymod_intf_mode_from_phymod_intf(unit, phymod_interface, phy_interface_config);
   2156 }
   2157 
   2158 
   2159 int portmod_common_control_phy_timesync_set(const phymod_phy_access_t* phy_access, 
   2160                                             const portmod_port_control_phy_timesync_t type, 
   2161                                             const uint64 value)
   2162 {
   2163     uint32 val_lo;
   2164     uint32 once = 0, always = 0, flags = 0;
   2165     uint32 value0;
   2166     phymod_core_access_t core_access;
   2167     phymod_timesync_compensation_mode_t timesync_am_norm_mode;
   2168 
   2169     val_lo = COMPILER_64_LO(value);
   2170 
   2171     switch (type) {
   2172     case SOC_PORT_CONTROL_PHY_TIMESYNC_CAPTURE_TIMESTAMP:
   2173     case SOC_PORT_CONTROL_PHY_TIMESYNC_HEARTBEAT_TIMESTAMP:
   2174         return SOC_E_NONE;
   2175 
   2176     case SOC_PORT_CONTROL_PHY_TIMESYNC_NCOADDEND:
   2177         PORTMOD_IF_ERROR_RETURN(phymod_timesync_nco_addend_set(phy_access, val_lo));
   2178         PORTMOD_IF_ERROR_RETURN(
   2179             phymod_timesync_nco_addend_set(phy_access, val_lo));
   2180         break;
   2181 
   2182     case SOC_PORT_CONTROL_PHY_TIMESYNC_FRAMESYNC:
   2183         PORTMOD_IF_ERROR_RETURN(
   2184             phymod_timesync_do_sync(phy_access));
   2185         break;
   2186     case SOC_PORT_CONTROL_PHY_TIMESYNC_LOCAL_TIME:
   2187         PORTMOD_IF_ERROR_RETURN(
   2188             phymod_timesync_local_time_set(phy_access, value));
   2189         break;
   2190     case SOC_PORT_CONTROL_PHY_TIMESYNC_LOAD_CONTROL:
   2191         if (val_lo & SOC_PORT_PHY_TIMESYNC_TN_LOAD) {
   2192             PHYMOD_TS_LDCTL_TN_LOAD_SET(once);
   2193         }
   2194         if (val_lo & SOC_PORT_PHY_TIMESYNC_TN_ALWAYS_LOAD) {
   2195             PHYMOD_TS_LDCTL_TN_LOAD_SET(always);
   2196         }
   2197         if (val_lo & SOC_PORT_PHY_TIMESYNC_TIMECODE_LOAD) {
   2198             PHYMOD_TS_LDCTL_TIMECODE_LOAD_SET(once);
   2199         }
   2200         if (val_lo & SOC_PORT_PHY_TIMESYNC_TIMECODE_ALWAYS_LOAD) {
   2201             PHYMOD_TS_LDCTL_TIMECODE_LOAD_SET(always);
   2202         }
   2203         if (val_lo & SOC_PORT_PHY_TIMESYNC_SYNCOUT_LOAD) {
   2204             PHYMOD_TS_LDCTL_SYNCOUT_LOAD_SET(once);
   2205         }
   2206         if (val_lo & SOC_PORT_PHY_TIMESYNC_SYNCOUT_ALWAYS_LOAD) {
   2207             PHYMOD_TS_LDCTL_SYNCOUT_LOAD_SET(always);
   2208         }
   2209         if (val_lo & SOC_PORT_PHY_TIMESYNC_NCO_DIVIDER_LOAD) {
   2210             PHYMOD_TS_LDCTL_NCO_DIVIDER_LOAD_SET(once);
   2211         }
   2212         if (val_lo & SOC_PORT_PHY_TIMESYNC_NCO_DIVIDER_ALWAYS_LOAD) {
   2213             PHYMOD_TS_LDCTL_NCO_DIVIDER_LOAD_SET(always);
   2214         }
   2215         if (val_lo & SOC_PORT_PHY_TIMESYNC_LOCAL_TIME_LOAD) {
   2216             PHYMOD_TS_LDCTL_LOCAL_TIME_LOAD_SET(once);
   2217         }
   2218         if (val_lo & SOC_PORT_PHY_TIMESYNC_LOCAL_TIME_ALWAYS_LOAD) {
   2219             PHYMOD_TS_LDCTL_LOCAL_TIME_LOAD_SET(always);
   2220         }
   2221         if (val_lo & SOC_PORT_PHY_TIMESYNC_NCO_ADDEND_LOAD) {
   2222             PHYMOD_TS_LDCTL_NCO_ADDEND_LOAD_SET(once);
   2223         }
   2224         if (val_lo & SOC_PORT_PHY_TIMESYNC_NCO_ADDEND_ALWAYS_LOAD) {
   2225             PHYMOD_TS_LDCTL_NCO_ADDEND_LOAD_SET(always);
   2226         }
   2227         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_LOOP_FILTER_LOAD) {
   2228             PHYMOD_TS_LDCTL_DPLL_LOOP_FILTER_LOAD_SET(once);
   2229         }
   2230         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_LOOP_FILTER_ALWAYS_LOAD) {
   2231             PHYMOD_TS_LDCTL_DPLL_LOOP_FILTER_LOAD_SET(always);
   2232         }
   2233         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_LOAD) {
   2234             PHYMOD_TS_LDCTL_DPLL_REF_PHASE_LOAD_SET(once);
   2235         }
   2236         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_ALWAYS_LOAD) {
   2237             PHYMOD_TS_LDCTL_DPLL_REF_PHASE_LOAD_SET(always);
   2238         }
   2239         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_DELTA_LOAD) {
   2240             PHYMOD_TS_LDCTL_DPLL_REF_PHASE_DELTA_LOAD_SET(once);
   2241         }
   2242         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_DELTA_ALWAYS_LOAD) {
   2243             PHYMOD_TS_LDCTL_DPLL_REF_PHASE_DELTA_LOAD_SET(always);
   2244         }
   2245         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K3_LOAD) {
   2246             PHYMOD_TS_LDCTL_DPLL_K3_LOAD_SET(once);
   2247         }
   2248         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K3_ALWAYS_LOAD) {
   2249             PHYMOD_TS_LDCTL_DPLL_K3_LOAD_SET(always);
   2250         }
   2251         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K2_LOAD) {
   2252             PHYMOD_TS_LDCTL_DPLL_K2_LOAD_SET(once);
   2253         }
   2254         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K2_ALWAYS_LOAD) {
   2255             PHYMOD_TS_LDCTL_DPLL_K2_LOAD_SET(always);
   2256         }
   2257         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K1_LOAD) {
   2258             PHYMOD_TS_LDCTL_DPLL_K1_LOAD_SET(once);
   2259         }
   2260         if (val_lo & SOC_PORT_PHY_TIMESYNC_DPLL_K1_ALWAYS_LOAD) {
   2261             PHYMOD_TS_LDCTL_DPLL_K1_LOAD_SET(always);
   2262         }
   2263 
   2264         PORTMOD_IF_ERROR_RETURN(
   2265             phymod_timesync_load_ctrl_set(phy_access, once, always));
   2266         break;
   2267 
   2268     case SOC_PORT_CONTROL_PHY_TIMESYNC_INTERRUPT:
   2269 
   2270         if (val_lo & SOC_PORT_PHY_TIMESYNC_TIMESTAMP_INTERRUPT) {
   2271             PORTMOD_IF_ERROR_RETURN(
   2272                 phymod_phy_intr_status_clear(phy_access,
   2273                                          PHYMOD_INTR_TIMESYNC_TIMESTAMP));
   2274         }
   2275         if (val_lo & SOC_PORT_PHY_TIMESYNC_FRAMESYNC_INTERRUPT) {
   2276             PORTMOD_IF_ERROR_RETURN(
   2277                 phymod_phy_intr_status_clear(phy_access,
   2278                                            PHYMOD_INTR_TIMESYNC_FRAMESYNC));
   2279         }
   2280         break;
   2281     case SOC_PORT_CONTROL_PHY_TIMESYNC_INTERRUPT_MASK:
   2282 
   2283         PORTMOD_IF_ERROR_RETURN(
   2284             phymod_phy_intr_enable_get(phy_access, &value0));
   2285 
   2286         if (val_lo & SOC_PORT_PHY_TIMESYNC_TIMESTAMP_INTERRUPT){
   2287             value0 |= PHYMOD_INTR_TIMESYNC_TIMESTAMP ;
   2288         } else {
   2289             value0 &= ~PHYMOD_INTR_TIMESYNC_TIMESTAMP ;
   2290         } 
   2291 
   2292         if (val_lo & SOC_PORT_PHY_TIMESYNC_FRAMESYNC_INTERRUPT){
   2293             value0 |= PHYMOD_INTR_TIMESYNC_FRAMESYNC;
   2294         } else {
   2295             value0 &= ~PHYMOD_INTR_TIMESYNC_FRAMESYNC;
   2296         }
   2297 
   2298         PORTMOD_IF_ERROR_RETURN(
   2299             phymod_phy_intr_enable_set(phy_access, value0));
   2300 
   2301         break;
   2302     case SOC_PORT_CONTROL_PHY_TIMESYNC_TX_TIMESTAMP_OFFSET:
   2303         val_lo = COMPILER_64_LO(value);
   2304 
   2305         PORTMOD_IF_ERROR_RETURN(
   2306             phymod_timesync_tx_timestamp_offset_set(phy_access, val_lo));
   2307 
   2308         break;
   2309     case SOC_PORT_CONTROL_PHY_TIMESYNC_RX_TIMESTAMP_OFFSET:
   2310         val_lo = COMPILER_64_LO(value);
   2311         PORTMOD_IF_ERROR_RETURN(
   2312             phymod_timesync_rx_timestamp_offset_set(phy_access, val_lo));
   2313 
   2314         break;
   2315     case SOC_PORT_CONTROL_PHY_TIMESYNC_TIMESTAMP_OFFSET:
   2316         val_lo = COMPILER_64_LO(value);
   2317         sal_memcpy(&core_access, phy_access, sizeof(core_access));
   2318         PORTMOD_IF_ERROR_RETURN(
   2319             phymod_timesync_offset_set(&core_access, val_lo));
   2320         break;
   2321     case SOC_PORT_CONTROL_PHY_TIMESYNC_TIMESTAMP_ADJUST:
   2322         timesync_am_norm_mode = COMPILER_64_LO(value);
   2323         PORTMOD_IF_ERROR_RETURN(
   2324             phymod_timesync_adjust_set(phy_access, timesync_am_norm_mode));
   2325         break;
   2326     case SOC_PORT_CONTROL_PHY_TIMESYNC_ONE_STEP_ENABLE:
   2327         val_lo = COMPILER_64_LO(value);
   2328         PHYMOD_TIMESYNC_ENABLE_F_ONE_STEP_PIPELINE_SET(flags);
   2329         PORTMOD_IF_ERROR_RETURN(
   2330             phymod_timesync_enable_set(phy_access, flags, val_lo));
   2331         break;
   2332     default:
   2333         return SOC_E_UNAVAIL;
   2334     }
   2335         return SOC_E_NONE;
   2336 }
   2337 
   2338 int portmod_common_control_phy_timesync_get(const phymod_phy_access_t* phy_access, 
   2339                                             const portmod_port_control_phy_timesync_t type, 
   2340                                             uint64* value)
   2341 {
   2342     uint32 val_lo;
   2343     uint32 once = 0, always = 0, flags = 0;
   2344     uint32 value0;
   2345     uint32 intr_status;
   2346 
   2347     switch (type) {
   2348     case SOC_PORT_CONTROL_PHY_TIMESYNC_HEARTBEAT_TIMESTAMP:
   2349         PORTMOD_IF_ERROR_RETURN(
   2350             phymod_timesync_heartbeat_timestamp_get(phy_access, value));
   2351 
   2352         break;
   2353     case SOC_PORT_CONTROL_PHY_TIMESYNC_CAPTURE_TIMESTAMP:
   2354         PORTMOD_IF_ERROR_RETURN(
   2355             phymod_timesync_capture_timestamp_get(phy_access, value));
   2356 
   2357         break;
   2358     case SOC_PORT_CONTROL_PHY_TIMESYNC_NCOADDEND:
   2359         PORTMOD_IF_ERROR_RETURN(
   2360             phymod_timesync_nco_addend_get(phy_access, &val_lo));
   2361         COMPILER_64_SET((*value), 0, val_lo);
   2362 
   2363         break;
   2364     case SOC_PORT_CONTROL_PHY_TIMESYNC_LOCAL_TIME:
   2365         PORTMOD_IF_ERROR_RETURN(
   2366             phymod_timesync_local_time_get(phy_access, value));
   2367         break;
   2368 
   2369     case SOC_PORT_CONTROL_PHY_TIMESYNC_LOAD_CONTROL:
   2370 
   2371         PORTMOD_IF_ERROR_RETURN(
   2372             phymod_timesync_load_ctrl_get(phy_access, &once, &always));
   2373 
   2374         val_lo = 0;
   2375 
   2376         if (once & PHYMOD_TS_LDCTL_TN_LOAD) {
   2377             val_lo |= SOC_PORT_PHY_TIMESYNC_TN_LOAD;
   2378         }
   2379         if (always & PHYMOD_TS_LDCTL_TN_LOAD) {
   2380             val_lo |= SOC_PORT_PHY_TIMESYNC_TN_ALWAYS_LOAD;
   2381         }
   2382         if (once & PHYMOD_TS_LDCTL_TIMECODE_LOAD) {
   2383             val_lo |= SOC_PORT_PHY_TIMESYNC_TIMECODE_LOAD;
   2384         }
   2385         if (always & PHYMOD_TS_LDCTL_TIMECODE_LOAD) {
   2386             val_lo |= SOC_PORT_PHY_TIMESYNC_TIMECODE_ALWAYS_LOAD;
   2387         }
   2388         if (once & PHYMOD_TS_LDCTL_SYNCOUT_LOAD) {
   2389             val_lo |= SOC_PORT_PHY_TIMESYNC_SYNCOUT_LOAD;
   2390         }
   2391         if (always & PHYMOD_TS_LDCTL_SYNCOUT_LOAD) {
   2392             val_lo |= SOC_PORT_PHY_TIMESYNC_SYNCOUT_ALWAYS_LOAD;
   2393         }
   2394         if (once & PHYMOD_TS_LDCTL_NCO_DIVIDER_LOAD) {
   2395             val_lo |= SOC_PORT_PHY_TIMESYNC_NCO_DIVIDER_LOAD;
   2396         }
   2397         if (always & PHYMOD_TS_LDCTL_NCO_DIVIDER_LOAD) {
   2398             val_lo |= SOC_PORT_PHY_TIMESYNC_NCO_DIVIDER_ALWAYS_LOAD;
   2399         }
   2400         if (once & PHYMOD_TS_LDCTL_LOCAL_TIME_LOAD) {
   2401             val_lo |= SOC_PORT_PHY_TIMESYNC_LOCAL_TIME_LOAD;
   2402         }
   2403         if (always & PHYMOD_TS_LDCTL_LOCAL_TIME_LOAD) {
   2404             val_lo |= SOC_PORT_PHY_TIMESYNC_LOCAL_TIME_ALWAYS_LOAD;
   2405         }
   2406         if (once & PHYMOD_TS_LDCTL_NCO_ADDEND_LOAD) {
   2407             val_lo |= SOC_PORT_PHY_TIMESYNC_NCO_ADDEND_LOAD;
   2408         }
   2409         if (always & PHYMOD_TS_LDCTL_NCO_ADDEND_LOAD) {
   2410             val_lo |= SOC_PORT_PHY_TIMESYNC_NCO_ADDEND_ALWAYS_LOAD;
   2411         }
   2412         if (once & PHYMOD_TS_LDCTL_DPLL_LOOP_FILTER_LOAD) {
   2413             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_LOOP_FILTER_LOAD;
   2414         }
   2415         if (always & PHYMOD_TS_LDCTL_DPLL_LOOP_FILTER_LOAD) {
   2416             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_LOOP_FILTER_ALWAYS_LOAD;
   2417         }
   2418         if (once & PHYMOD_TS_LDCTL_DPLL_REF_PHASE_LOAD) {
   2419             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_LOAD;
   2420         }
   2421         if (always & PHYMOD_TS_LDCTL_DPLL_REF_PHASE_LOAD) {
   2422             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_ALWAYS_LOAD;
   2423         }
   2424         if (once & PHYMOD_TS_LDCTL_DPLL_REF_PHASE_DELTA_LOAD) {
   2425             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_DELTA_LOAD;
   2426         }
   2427         if (always & PHYMOD_TS_LDCTL_DPLL_REF_PHASE_DELTA_LOAD) {
   2428             val_lo |=
   2429                 SOC_PORT_PHY_TIMESYNC_DPLL_REF_PHASE_DELTA_ALWAYS_LOAD;
   2430         }
   2431         if (once & PHYMOD_TS_LDCTL_DPLL_K3_LOAD) {
   2432             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K3_LOAD;
   2433         }
   2434         if (always & PHYMOD_TS_LDCTL_DPLL_K3_LOAD) {
   2435             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K3_ALWAYS_LOAD;
   2436         }
   2437         if (once & PHYMOD_TS_LDCTL_DPLL_K2_LOAD) {
   2438             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K2_LOAD;
   2439         }
   2440         if (always & PHYMOD_TS_LDCTL_DPLL_K2_LOAD) {
   2441             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K2_ALWAYS_LOAD;
   2442         }
   2443         if (once & PHYMOD_TS_LDCTL_DPLL_K1_LOAD) {
   2444             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K1_LOAD;
   2445         }
   2446         if (always & PHYMOD_TS_LDCTL_DPLL_K1_LOAD) {
   2447             val_lo |= SOC_PORT_PHY_TIMESYNC_DPLL_K1_ALWAYS_LOAD;
   2448         }
   2449         COMPILER_64_SET((*value), 0, val_lo);
   2450 
   2451         break;
   2452     case SOC_PORT_CONTROL_PHY_TIMESYNC_INTERRUPT:
   2453         value0 = 0;
   2454 
   2455         PORTMOD_IF_ERROR_RETURN(
   2456             phymod_phy_intr_status_get(phy_access, &intr_status));
   2457         if (intr_status) {
   2458             value0 |= SOC_PORT_PHY_TIMESYNC_TIMESTAMP_INTERRUPT;
   2459         }
   2460 
   2461         PORTMOD_IF_ERROR_RETURN(
   2462             phymod_phy_intr_status_get(phy_access, &intr_status));
   2463         if (intr_status) {
   2464             value0 |= SOC_PORT_PHY_TIMESYNC_FRAMESYNC_INTERRUPT;
   2465         }
   2466 
   2467         COMPILER_64_SET((*value), 0, (uint32) value0);
   2468         break;
   2469     case SOC_PORT_CONTROL_PHY_TIMESYNC_INTERRUPT_MASK:
   2470         value0 = 0;
   2471 
   2472         PORTMOD_IF_ERROR_RETURN(
   2473             phymod_phy_intr_enable_get(phy_access, &intr_status));
   2474         if (intr_status) {
   2475             value0 |= SOC_PORT_PHY_TIMESYNC_TIMESTAMP_INTERRUPT_MASK;
   2476         }
   2477 
   2478         PORTMOD_IF_ERROR_RETURN(
   2479             phymod_phy_intr_enable_get(phy_access, &intr_status));
   2480         if (intr_status) {
   2481             value0 |= SOC_PORT_PHY_TIMESYNC_FRAMESYNC_INTERRUPT_MASK;
   2482         }
   2483 
   2484         COMPILER_64_SET((*value), 0, (uint32) value0);
   2485         break;
   2486     case SOC_PORT_CONTROL_PHY_TIMESYNC_TX_TIMESTAMP_OFFSET:
   2487         PORTMOD_IF_ERROR_RETURN(
   2488             phymod_timesync_tx_timestamp_offset_get(phy_access, &val_lo));
   2489         COMPILER_64_SET((*value), 0, val_lo);
   2490 
   2491         break;
   2492     case SOC_PORT_CONTROL_PHY_TIMESYNC_RX_TIMESTAMP_OFFSET:
   2493         PORTMOD_IF_ERROR_RETURN(
   2494             phymod_timesync_rx_timestamp_offset_get(phy_access, &val_lo));
   2495         COMPILER_64_SET((*value), 0, val_lo);
   2496         break;
   2497     case SOC_PORT_CONTROL_PHY_TIMESYNC_ONE_STEP_ENABLE:
   2498         PHYMOD_TIMESYNC_ENABLE_F_ONE_STEP_PIPELINE_SET(flags);
   2499         PORTMOD_IF_ERROR_RETURN(
   2500             phymod_timesync_enable_get(phy_access, flags, &val_lo));
   2501         COMPILER_64_SET((*value), 0, val_lo);
   2502         break;
   2503     default:
   2504        return SOC_E_UNAVAIL;
   2505     }
   2506     return SOC_E_NONE;
   2507 }
   2508 
   2509 STATIC
   2510 int _portmod_common_ext_phy_addr_get(int unit, soc_port_t port, uint32 *xphy_id)
   2511 {
   2512     phymod_phy_access_t phy_access[1+MAX_PHYN];
   2513     int nof_phys = 0;
   2514     portmod_access_get_params_t params;
   2515     int is_most_ext;
   2516 
   2517     *xphy_id = PORTMOD_XPHY_ID_INVALID;
   2518 
   2519     SOC_IF_ERROR_RETURN
   2520         (portmod_access_get_params_t_init(unit, &params));
   2521     params.phyn = 0;
   2522     SOC_IF_ERROR_RETURN
   2523         (portmod_port_phy_lane_access_get(unit, port,
   2524                                 &params, (1+MAX_PHYN), phy_access, &nof_phys, &is_most_ext));
   2525     if(is_most_ext)
   2526     {
   2527         return SOC_E_NONE;
   2528     }
   2529     params.phyn = 1;
   2530     SOC_IF_ERROR_RETURN
   2531         (portmod_port_phy_lane_access_get(unit, port,
   2532                                 &params, (1+MAX_PHYN), phy_access, &nof_phys, NULL));
   2533 
   2534     *xphy_id = phy_access[0].access.addr;
   2535 
   2536     return SOC_E_NONE;
   2537 }
   2538 
   2539 int portmod_common_ext_phy_fw_bcst(int unit, pbmp_t *pbmp)
   2540 {
   2541     phymod_core_status_t      core_status;
   2542     phymod_firmware_load_method_t fw_load_method;
   2543     phymod_core_access_t core_access;
   2544     int is_initialized;
   2545     int  force_fw_load, is_legacy_present;
   2546     uint32 primary_core_num;
   2547 
   2548     phymod_core_init_config_t core_config;
   2549 
   2550     int     rv=0, dev_type, mdio_bus;
   2551     uint32  xphy_id, is_identify = 0;
   2552     uint8   ext_phy_bcst_done[PM_MDIO_BUS_COUNT][phymodDispatchTypeCount];
   2553     soc_port_t port ;
   2554     pbmp_t new_pbmp ;
   2555 
   2556     sal_memset(ext_phy_bcst_done, 0, sizeof(ext_phy_bcst_done));
   2557 
   2558     for(dev_type = 0; dev_type < phymodDispatchTypeCount; dev_type++) {
   2559         for(mdio_bus =0; mdio_bus < PM_MDIO_BUS_COUNT; mdio_bus++) {
   2560 
   2561             /*set up new pbm of the same type in one mdio bus */
   2562             SOC_PBMP_CLEAR(new_pbmp);
   2563             SOC_IF_ERROR_RETURN(phymod_core_init_config_t_init(&core_config));
   2564             PBMP_ITER(*pbmp, port){
   2565                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id);
   2566                 if (rv != SOC_E_NONE) continue;
   2567 
   2568                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2569                     continue;
   2570                 }
   2571 
   2572                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2573                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2574 
   2575                 rv = portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method);
   2576                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2577 
   2578                 if (fw_load_method != phymodFirmwareLoadMethodInternal)
   2579                     continue;
   2580 
   2581                 /* coverity[returned_value] */
   2582                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2583                 /*skip if it is legacy PHY*/
   2584                 rv = portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_present);
   2585                 if ((rv != SOC_E_NONE) || (is_legacy_present)) continue;
   2586 
   2587                 /* check if this is bcast capable */
   2588                 SOC_IF_ERROR_RETURN(phymod_core_identify(&core_access, 0, &is_identify));
   2589 
   2590                 /* if not broadcast capable - continue */
   2591                 if (!(is_identify & 0x80000000)) continue;
   2592 
   2593                 if((dev_type == core_access.type) &&
   2594                     (mdio_bus == PHY_ID_BUS_NUM(core_access.access.addr))){
   2595                     SOC_PBMP_PORT_ADD(new_pbmp, port);
   2596                 }
   2597             }
   2598 
   2599             /*step1: reset core for firmware load if the external phy need*/
   2600 
   2601             PBMP_ITER(new_pbmp, port){
   2602                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id) ;
   2603                 if (rv != SOC_E_NONE) continue;
   2604 
   2605                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2606                     continue;
   2607                 }
   2608 
   2609                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2610                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2611                 /* skip if it is not sesto. */
   2612                 if ( (core_access.type != phymodDispatchTypeSesto) 
   2613                      && (core_access.type != phymodDispatchTypeDino)) {
   2614                     continue;
   2615                 }
   2616 
   2617                 SOC_IF_ERROR_RETURN(portmod_xphy_core_config_get(unit, xphy_id, &core_config));
   2618                 core_config.flags = 0;
   2619                 SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   2620                 SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   2621                 SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   2622 
   2623                 if(is_initialized & PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD)
   2624                     continue;
   2625                 PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_SET(&core_config);
   2626                 if (force_fw_load == phymodFirmwareLoadForce) {
   2627                     PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config);
   2628                 }
   2629                 else if (force_fw_load == phymodFirmwareLoadAuto) {
   2630                     PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config);
   2631                 }
   2632 
   2633                 core_config.firmware_load_method = fw_load_method;
   2634 
   2635                 core_status.pmd_active = 0;
   2636                 SOC_IF_ERROR_RETURN(phymod_core_init(&core_access,
   2637                                              &core_config, &core_status));
   2638                 is_initialized |= PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD;
   2639 
   2640                 SOC_IF_ERROR_RETURN(portmod_xphy_core_config_set(unit, xphy_id, &core_config));
   2641                 SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2642             }
   2643 
   2644             /*step2:enable broadcast*/
   2645             PBMP_ITER(new_pbmp, port){
   2646                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id) ;
   2647                 if (rv != SOC_E_NONE) continue;
   2648 
   2649                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2650                     continue;
   2651                 }
   2652 
   2653                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2654                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2655 
   2656                 SOC_IF_ERROR_RETURN(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   2657                 if (primary_core_num == core_access.access.addr) {
   2658                     SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   2659                     if(is_initialized & PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD)
   2660                         continue;
   2661                     SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   2662                     SOC_IF_ERROR_RETURN(portmod_xphy_core_config_get(unit, xphy_id, &core_config));
   2663                     SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   2664 
   2665                     core_config.firmware_load_method = fw_load_method;
   2666                     core_config.flags = 0;
   2667                     PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_SET(&core_config);
   2668                     if (force_fw_load == phymodFirmwareLoadForce) {
   2669                         PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config);
   2670                     }
   2671                     else if (force_fw_load == phymodFirmwareLoadAuto) {
   2672                         PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config);
   2673                     }
   2674 
   2675                     core_status.pmd_active = 0;
   2676                     SOC_IF_ERROR_RETURN(phymod_core_init(&core_access,
   2677                         &core_config, &core_status));
   2678                     is_initialized |= PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD;
   2679 
   2680                     SOC_IF_ERROR_RETURN(portmod_xphy_core_config_set(unit, xphy_id, &core_config));
   2681                     SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2682                 }
   2683 
   2684             }
   2685 
   2686             /*step3:load firmware broadcast*/
   2687             PBMP_ITER(new_pbmp, port){
   2688                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id) ;
   2689                 if (rv != SOC_E_NONE) continue;
   2690 
   2691                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2692                     continue;
   2693                 }
   2694 
   2695                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2696                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2697 
   2698                 SOC_IF_ERROR_RETURN(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   2699                 SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   2700 
   2701                 if (primary_core_num == core_access.access.addr) {
   2702                     if(is_initialized & PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD)
   2703                         continue;
   2704 
   2705                     if(!ext_phy_bcst_done[mdio_bus][dev_type]){
   2706                         /* Do the broadcast*/
   2707                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_get(unit, xphy_id, &core_config));
   2708                         SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   2709                         SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   2710 
   2711                         core_config.firmware_load_method = fw_load_method;
   2712                         core_config.flags = 0;
   2713                         PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_SET(&core_config);
   2714                         if (force_fw_load == phymodFirmwareLoadForce) {
   2715                             PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config);
   2716                         }
   2717                         else if (force_fw_load == phymodFirmwareLoadAuto) {
   2718                             PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config);
   2719                         }
   2720 
   2721                         core_status.pmd_active = 0;
   2722                         SOC_IF_ERROR_RETURN(phymod_core_init(&core_access,
   2723                                                              &core_config, &core_status));
   2724                         ext_phy_bcst_done[mdio_bus][dev_type] = 1;
   2725                         is_initialized |= PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD;
   2726                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_set(unit, xphy_id, &core_config));
   2727                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2728                     }else {
   2729                         /* if the download is already done, mark it as fw load executed. */
   2730                         is_initialized |= PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD;
   2731                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2732                         break ;
   2733                     }
   2734                 }
   2735             }
   2736 
   2737             /*step4: resume and verify*/
   2738             PBMP_ITER(new_pbmp, port){
   2739                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id) ;
   2740                 if (rv != SOC_E_NONE) continue;
   2741 
   2742                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2743                     continue;
   2744                 }
   2745 
   2746                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2747                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2748 
   2749                 if (ext_phy_bcst_done[mdio_bus][dev_type]) {
   2750                     SOC_IF_ERROR_RETURN(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   2751 
   2752                     if (primary_core_num == core_access.access.addr) {
   2753                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   2754                         if((is_initialized & PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD)&&
   2755                             (is_initialized & PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY))
   2756                         {
   2757                             continue;
   2758                         }
   2759 
   2760                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_get(unit, xphy_id, &core_config));
   2761                         SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   2762                         SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   2763 
   2764                         core_config.firmware_load_method = fw_load_method;
   2765                         core_config.flags = 0;
   2766                         /* verify firmware download and resume init */
   2767                         PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_CLR(&core_config);
   2768                         PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_SET(&core_config);
   2769                         PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_SET(&core_config);
   2770 
   2771                         if (force_fw_load == phymodFirmwareLoadForce) {
   2772                             PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config);
   2773                         }
   2774                         else if (force_fw_load == phymodFirmwareLoadAuto) {
   2775                             PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config);
   2776                         }
   2777 
   2778                         SOC_IF_ERROR_RETURN(phymod_core_init(&core_access,
   2779                                                      &core_config, &core_status));
   2780                         is_initialized |= PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD;
   2781                         is_initialized |= PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
   2782 
   2783                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_set(unit, xphy_id, &core_config));
   2784                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2785                     }
   2786                  }
   2787             }
   2788 
   2789             /*step5: firmware load end*/
   2790             PBMP_ITER(new_pbmp, port){
   2791                 rv = _portmod_common_ext_phy_addr_get(unit, port, &xphy_id) ;
   2792                 if (rv != SOC_E_NONE) continue;
   2793 
   2794                 if (xphy_id == PORTMOD_XPHY_ID_INVALID) {
   2795                     continue;
   2796                 }
   2797 
   2798                 rv = portmod_xphy_core_access_get(unit, xphy_id, &core_access, &is_legacy_present);
   2799                 if (rv == SOC_E_PARAM) continue;  /* no external phy exists */
   2800 
   2801                 if (ext_phy_bcst_done[mdio_bus][dev_type]) {
   2802 
   2803                     SOC_IF_ERROR_RETURN(portmod_xphy_primary_core_num_get(unit, xphy_id, &primary_core_num));
   2804 
   2805                     if (primary_core_num == core_access.access.addr) {
   2806                         /* finish up the configuration */
   2807                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_get(unit, xphy_id, &is_initialized));
   2808                         if(is_initialized & PHYMOD_CORE_INIT_F_FW_LOAD_END)
   2809                             continue;
   2810 
   2811                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_get(unit, xphy_id, &core_config));
   2812                         SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, xphy_id, &force_fw_load));
   2813                         SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, xphy_id, &fw_load_method));
   2814 
   2815                         core_config.firmware_load_method = fw_load_method;
   2816                         core_config.flags = 0;
   2817                         PHYMOD_CORE_INIT_F_FW_LOAD_END_SET(&core_config);
   2818                         if (force_fw_load == phymodFirmwareLoadForce) {
   2819                             PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config);
   2820                         }
   2821                         else if (force_fw_load == phymodFirmwareLoadAuto) {
   2822                             PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config);
   2823                         }
   2824 
   2825                         SOC_IF_ERROR_RETURN(phymod_core_init(&core_access,
   2826                                                      &core_config, &core_status));
   2827                         is_initialized |= PHYMOD_CORE_INIT_F_FW_LOAD_END;
   2828                         SOC_IF_ERROR_RETURN(portmod_xphy_core_config_set(unit, xphy_id, &core_config));
   2829                         SOC_IF_ERROR_RETURN(portmod_xphy_is_initialized_set(unit, xphy_id, is_initialized));
   2830                     }
   2831                  }
   2832             }
   2833         }
   2834     }
   2835     return (SOC_E_NONE);
   2836 
   2837 }
   2838 
   2839 /*!
   2840  * portmod_port_phy_drv_name_get
   2841  *
   2842  * @brief Get the phy driver name attached to the port
   2843  *
   2844  * @param [in]  unit     - unit id
   2845  * @param [in]  port     - port num
   2846  * @param [out] name     - phy driver name.
   2847  * @param [in]  len      - max length of the name buffer.
   2848  */
   2849 int portmod_port_phy_drv_name_get(int unit, int port, char *name, int len)
   2850 {
   2851     int is_ext_legacy_phy = 0;
   2852     phymod_core_access_t core_acc;
   2853     phymod_core_info_t core_info;
   2854     char *pname = NULL, namelen = 0;
   2855     int nof_cores = 0;
   2856 
   2857     SOC_IF_ERROR_RETURN(
   2858        portmod_port_is_legacy_ext_phy_present(unit, port, &is_ext_legacy_phy));
   2859 
   2860     if (is_ext_legacy_phy) {
   2861         SOC_IF_ERROR_RETURN(
   2862             portmod_port_legacy_phy_drv_name_get(unit, port, name, len));
   2863     } else {
   2864         phymod_core_access_t_init(&core_acc);
   2865         phymod_core_info_t_init(&core_info);
   2866 
   2867         SOC_IF_ERROR_RETURN(
   2868             portmod_port_main_core_access_get(unit, port, -1, &core_acc,
   2869                                               &nof_cores));
   2870         if (nof_cores == 0) {
   2871             /*coverity[buffer_size]*/
   2872             strncpy(name, "<nophy>", strlen("<nophy>"));
   2873             return SOC_E_NONE;
   2874         }
   2875         SOC_IF_ERROR_RETURN(
   2876             phymod_core_info_get(&core_acc, &core_info));
   2877             /*
   2878              * get the phy name string from the mapping. The format is
   2879              * phymodCoreVersion"PhyName", only extract Phy Name from
   2880              * the string. The Phy name is also appended with the version
   2881              * version string as the last 2 characters. Skip it.
   2882              */
   2883         pname =
   2884            phymod_core_version_t_mapping[core_info.core_version].key;
   2885         namelen = (len < (strlen(pname) - 2))? (len - 1) : strlen(pname) - 2;
   2886         strncpy(name, pname, namelen);
   2887         *(name + namelen) = '\0';
   2888     }
   2889     return (SOC_E_NONE);
   2890 }
   2891 
   2892 /*!
   2893  * portmod_common_default_interface_get
   2894  *
   2895  * @brief Get default interface type based on port speed, number of lanes, and medium
   2896  *
   2897  * @param [inout] interface_config     - interface config, must contain following info: port speed, number of lanes and medium
   2898  */
   2899 int portmod_common_default_interface_get(portmod_port_interface_config_t* interface_config)
   2900 {
   2901     int is_higig;
   2902     int fiber_pref;
   2903 
   2904     is_higig =  ((interface_config->encap_mode == SOC_ENCAP_HIGIG2) ||
   2905                  (interface_config->encap_mode == SOC_ENCAP_HIGIG)  ||
   2906                  PHYMOD_INTF_MODES_HIGIG_GET(interface_config)) ? 1 : 0;
   2907     fiber_pref = PHYMOD_INTF_MODES_FIBER_GET(interface_config);
   2908 
   2909     if (interface_config->port_num_lanes == 1) {
   2910         if (interface_config->speed > 12000) {
   2911             if (is_higig) {
   2912                 interface_config->interface = SOC_PORT_IF_CR;
   2913             } else {
   2914                 interface_config->interface = fiber_pref ?
   2915                     SOC_PORT_IF_SR : SOC_PORT_IF_CR;
   2916             }
   2917         } else if (interface_config->speed >= 10000) {
   2918             if (is_higig) {
   2919                 interface_config->interface = SOC_PORT_IF_XFI;
   2920             } else {
   2921                 interface_config->interface = fiber_pref ?
   2922                     SOC_PORT_IF_SFI : SOC_PORT_IF_XFI;
   2923             }
   2924         } else if (interface_config->speed == 5000) {
   2925             interface_config->interface = SOC_PORT_IF_GMII;
   2926         } else {
   2927             interface_config->interface = fiber_pref ?
   2928                 SOC_PORT_IF_GMII : SOC_PORT_IF_SGMII;
   2929         }
   2930     } else if (interface_config->port_num_lanes == 2) {
   2931         if (interface_config->speed >= 40000) {
   2932             if (is_higig){
   2933                 interface_config->interface = SOC_PORT_IF_CR2;
   2934             } else {
   2935                 interface_config->interface =  fiber_pref ?
   2936                     SOC_PORT_IF_SR2 : SOC_PORT_IF_KR2;
   2937             }
   2938         } else if (interface_config->speed >=20000) {
   2939             if (is_higig) {
   2940                 interface_config->interface = SOC_PORT_IF_CR2;
   2941             } else {
   2942                 interface_config->interface = fiber_pref ?
   2943                     SOC_PORT_IF_SR2 : SOC_PORT_IF_CR2;
   2944             }
   2945         } else {
   2946             /* 10G default interface type */
   2947             interface_config->interface = SOC_PORT_IF_RXAUI;
   2948         }
   2949     } else if (interface_config->port_num_lanes == 3) {
   2950         /* Add the interface later (if valid )*/
   2951     } else if (interface_config->port_num_lanes == 4) {
   2952         if (interface_config->speed >= 100000) {
   2953             if (is_higig){
   2954                 interface_config->interface = SOC_PORT_IF_CR4;
   2955             } else{
   2956                 interface_config->interface =  fiber_pref ?
   2957                     SOC_PORT_IF_SR4 : SOC_PORT_IF_CAUI4;
   2958             }
   2959         } else if (interface_config->speed >= 50000) {
   2960             if (is_higig){
   2961                 interface_config->interface = SOC_PORT_IF_CR4;
   2962             } else{
   2963                 interface_config->interface = SOC_PORT_IF_KR4;
   2964             }
   2965         } else if (interface_config->speed >= 40000) {
   2966             if (is_higig){
   2967                 interface_config->interface = SOC_PORT_IF_CR4;
   2968             } else{
   2969                 interface_config->interface =  fiber_pref ?
   2970                     SOC_PORT_IF_SR4 : SOC_PORT_IF_XLAUI;
   2971             }
   2972         } else if (interface_config->speed >= 20000) {
   2973             if (is_higig){
   2974                 interface_config->interface = SOC_PORT_IF_XGMII;
   2975             } else{
   2976                 interface_config->interface =  fiber_pref ?
   2977                     SOC_PORT_IF_SR4 : SOC_PORT_IF_CR4;
   2978             }
   2979         } else if (interface_config->speed >= 10000) {
   2980             if (is_higig){
   2981                 interface_config->interface = SOC_PORT_IF_XGMII;
   2982             } else{
   2983                 interface_config->interface = SOC_PORT_IF_XAUI;
   2984             }
   2985            
   2986         }
   2987     } else if (interface_config->port_num_lanes == 10) {  /* 100G */
   2988             interface_config->interface = fiber_pref ?
   2989                  SOC_PORT_IF_SR10 : SOC_PORT_IF_CAUI;
   2990     } else if (interface_config->port_num_lanes == 12) {  /* 120G */
   2991             interface_config->interface = SOC_PORT_IF_CAUI;
   2992     } else {
   2993         /* Do Nothing - let it be default */
   2994     }
   2995     
   2996     return SOC_E_NONE;
   2997 }
   2998 
   2999 STATIC
   3000 int _portmod_common_phymod_identify(const phymod_dispatch_type_t* type_list, const phymod_access_t* access,
   3001                                     phymod_dispatch_type_t* type, int* is_probed)
   3002 {
   3003     phymod_core_access_t core;
   3004     uint32_t is_identified = 0;
   3005     uint32_t core_id = 0;
   3006     int rv = PHYMOD_E_NONE, i = 0;
   3007 
   3008     phymod_core_access_t_init(&core);
   3009     sal_memcpy(&core.access, access, sizeof(core.access));
   3010 
   3011     *is_probed = 0;
   3012     while (type_list[i] != phymodDispatchTypeInvalid) {
   3013         core.type = type_list[i];
   3014 
   3015         rv = phymod_core_identify(&core, core_id, &is_identified);
   3016         if (rv == PHYMOD_E_NONE && is_identified) {
   3017             *type = type_list[i];
   3018             *is_probed = 1;
   3019             break;
   3020         }
   3021 
   3022         i++;
   3023     }
   3024 
   3025     return PHYMOD_E_NONE;
   3026 }
   3027 
   3028 int portmod_common_serdes_probe(const phymod_dispatch_type_t* type_list, phymod_core_access_t* core_access, int* probe)
   3029 {
   3030     int is_probed = 0;
   3031     soc_error_t rv = SOC_E_NONE;
   3032     SOC_INIT_FUNC_DEFS;
   3033 
   3034     *probe = 0;
   3035     if ((core_access->type == phymodDispatchTypeInvalid) ||
   3036         (core_access->type == phymodDispatchTypeCount)) {
   3037         rv = _portmod_common_phymod_identify(type_list, &(core_access->access), &(core_access->type), &is_probed);
   3038         if (SOC_FAILURE(rv)) {
   3039             /* restore the old value */
   3040             core_access->type = phymodDispatchTypeInvalid;
   3041             _SOC_IF_ERR_EXIT(rv);
   3042         }
   3043 
   3044         if (is_probed) {
   3045             *probe = 1;
   3046         }
   3047     }
   3048 
   3049 exit:
   3050     SOC_FUNC_RETURN;
   3051 }
   3052 
   3053 phymod_dispatch_type_t portmod_ext_phy_list[] =
   3054 {
   3055 #ifdef PHYMOD_PHY8806X_SUPPORT
   3056     phymodDispatchTypePhy8806x,
   3057 #endif /*PHYMOD_PHY8806X_SUPPORT  */
   3058 #ifdef PHYMOD_FURIA_SUPPORT
   3059     phymodDispatchTypeFuria,
   3060 #endif /*PHYMOD_FURIA_SUPPORT  */
   3061 #ifdef PHYMOD_SESTO_SUPPORT
   3062     phymodDispatchTypeSesto,
   3063 #endif /*PHYMOD_SESTO_SUPPORT  */
   3064 #ifdef PHYMOD_QUADRA28_SUPPORT
   3065     phymodDispatchTypeQuadra28,
   3066 #endif /*PHYMOD_QUADRA28_SUPPORT  */
   3067 #ifdef PHYMOD_HURACAN_SUPPORT
   3068     phymodDispatchTypeHuracan,
   3069 #endif /*PHYMOD_HURACAN_SUPPORT  */
   3070 #ifdef PHYMOD_MADURA_SUPPORT
   3071     phymodDispatchTypeMadura,
   3072 #endif /*PHYMOD_MADURA_SUPPORT  */
   3073 #ifdef PHYMOD_FURIA_SUPPORT
   3074     phymodDispatchTypeFuria_82212,
   3075 #endif /*PHYMOD_FURIA_SUPPORT  */
   3076 #ifdef PHYMOD_DINO_SUPPORT
   3077     phymodDispatchTypeDino,
   3078 #endif /*PHYMOD_DINO_SUPPORT  */
   3079     phymodDispatchTypeInvalid
   3080 };
   3081 
   3082 /*
   3083  * Function:
   3084  *      portmod_common_ext_phy_probe
   3085  * Purpose:
   3086  *      Probe for external PHY attached to the port and return probing result.
   3087  *      First, the Phymod EXT PHY driver list is searched.
   3088  *      Then, if PHY dirver isn't found in Phymod list, the legacy PHY driver list will be searched.
   3089  * Parameters:
   3090  *      unit - SOC Unit #.
   3091  *      port - Port number.
   3092  *      core_access -Phymod core information.
   3093  *      probe -(OUT) Probe result: (1)-Found EXT PHY driver, (0)-Not found.
   3094  * Returns:
   3095  *      SOC_E_XXX
   3096  */
   3097 int portmod_common_ext_phy_probe(int unit, int port, phymod_core_access_t* core_access, int* probe)
   3098 {
   3099     int is_probed = 0, xphy_id;
   3100     soc_error_t rv = SOC_E_NONE;
   3101     SOC_INIT_FUNC_DEFS;
   3102 
   3103     *probe = 0;
   3104     if ((core_access->type == phymodDispatchTypeInvalid) ||
   3105         (core_access->type == phymodDispatchTypeCount)) {
   3106         rv = _portmod_common_phymod_identify(portmod_ext_phy_list, &(core_access->access), &(core_access->type), &is_probed);
   3107         if (SOC_FAILURE(rv)) {
   3108             /* restore the old value */
   3109             core_access->type = phymodDispatchTypeInvalid;
   3110             _SOC_IF_ERR_EXIT(rv);
   3111         }
   3112 
   3113         if (!is_probed) {
   3114             /* Reset type */
   3115             core_access->type = phymodDispatchTypeInvalid;
   3116             if (portmod_port_legacy_phy_probe(unit, port)) {
   3117                 xphy_id = core_access->access.addr;
   3118                 _SOC_IF_ERR_EXIT(portmod_xphy_is_legacy_phy_set(unit, xphy_id, 1));
   3119                 *probe = 1;
   3120             }
   3121         }
   3122         else {
   3123             *probe = 1;
   3124         }
   3125     }
   3126 
   3127 exit:
   3128     SOC_FUNC_RETURN;
   3129 }
   3130 
   3131 /*!
   3132  * Function:
   3133  *      portmod_pm_capability_get
   3134  * Purpose:
   3135  *      Get PortMacro specific capabilites.
   3136  * Parameters:
   3137  *      unit - SOC Unit #.
   3138  *      pm_type - Port macro type.
   3139  *      pm_cap -(OUT) PM specific capabilities.
   3140  * Returns:
   3141  *      SOC_E_XXX
   3142  */
   3143 int portmod_pm_capability_get(int unit,
   3144                               portmod_dispatch_type_t pm_type,
   3145                               portmod_pm_capability_t* pm_cap)
   3146 {
   3147     SOC_INIT_FUNC_DEFS;
   3148 
   3149     if(pm_cap == NULL){
   3150         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("pm_cap NULL paramaeter")));
   3151     }
   3152 
   3153     switch (pm_type) {
   3154 #ifdef PORTMOD_PM8X50_SUPPORT
   3155         case portmodDispatchTypePm8x50:
   3156             pm_cap->type = pm_type;
   3157             portmod_pm8x50_capability_t_init(unit,
   3158                                              &pm_cap->pm_capability.pm8x50_cap);
   3159             pm_cap->pm_capability.pm8x50_cap.vcos[0] = portmodVCO20P625G;
   3160             pm_cap->pm_capability.pm8x50_cap.vcos[1] = portmodVCO25P781G;
   3161             pm_cap->pm_capability.pm8x50_cap.vcos[2] = portmodVCO26P562G;
   3162             break;
   3163 #endif /*PORTMOD_PM8X50_SUPPORT  */
   3164         default:
   3165             return SOC_E_UNAVAIL;
   3166     }
   3167 
   3168 exit:
   3169     SOC_FUNC_RETURN;
   3170 }
   3171 
   3172 #ifdef FW_BCAST_DOWNLOAD
   3173 static int _portmod_pm_id_find(const int* pm_array, int array_len, int pm_id)
   3174 {
   3175     int i;
   3176 
   3177     for (i=0; i<array_len; i++) {
   3178         if (pm_array[i] == pm_id) {
   3179             return 1;
   3180         }
   3181     }
   3182 
   3183     return 0;
   3184 }
   3185 
   3186 /*
   3187  * This function is used to execute SerDes broadcast on all PMs
   3188  * which belongs to the same broadcast ring
   3189  */
   3190 static int _portmod_sbus_ring_bcast(int unit,
   3191                                     int* pm_array,
   3192                                     int array_len,
   3193                                     int bcast_id,
   3194                                     int last_pm,
   3195                                     int crc_enable)
   3196 {
   3197     pm_info_t pm_info;
   3198     portmod_sbus_bcast_config_t bcast_cfg;
   3199     int i;
   3200 
   3201     bcast_cfg.bcast_id = bcast_id;
   3202 
   3203     /* step 1: call RESET_CORE_FOR_FW_LOAD per core */
   3204     bcast_cfg.flag = PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD;
   3205     for (i=0; i<array_len; i++) {
   3206         portmod_pm_info_from_pm_id_get(unit, pm_array[i], &pm_info);
   3207         bcast_cfg.chain_last = (pm_array[i]==last_pm ? 1 : 0);
   3208 
   3209         portmod_fw_bcast(unit, pm_info, &bcast_cfg);
   3210     }
   3211 
   3212     /* step 2: call UNTIL_FW_LOAD per core */
   3213     bcast_cfg.flag = PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD;
   3214     for (i=0; i<array_len; i++) {
   3215         portmod_pm_info_from_pm_id_get(unit, pm_array[i], &pm_info);
   3216         bcast_cfg.chain_last = (pm_array[i]==last_pm ? 1 : 0);
   3217 
   3218         portmod_fw_bcast(unit, pm_info, &bcast_cfg);
   3219     }
   3220 
   3221     /* step 3: download ucode per ring */
   3222     bcast_cfg.flag = PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD;
   3223     portmod_pm_info_from_pm_id_get(unit, pm_array[0], &pm_info);
   3224     bcast_cfg.chain_last = (pm_array[0]==last_pm ? 1 : 0);
   3225 
   3226     portmod_fw_bcast(unit, pm_info, &bcast_cfg);
   3227 
   3228     /* step 4: call RESUME_AFTER_FW_LOAD per core */
   3229     bcast_cfg.flag = PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD;
   3230     for (i=0; i<array_len; i++) {
   3231         portmod_pm_info_from_pm_id_get(unit, pm_array[i], &pm_info);
   3232         bcast_cfg.chain_last = (pm_array[i]==last_pm ? 1 : 0);
   3233 
   3234         portmod_fw_bcast(unit, pm_info, &bcast_cfg);
   3235     }
   3236 
   3237     /* step 5: call FW_LOAD_END per core */
   3238     bcast_cfg.flag = PHYMOD_CORE_INIT_F_FW_LOAD_END;
   3239     if (crc_enable) {
   3240         bcast_cfg.flag |= PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
   3241     }
   3242     for (i=0; i<array_len; i++) {
   3243         portmod_pm_info_from_pm_id_get(unit, pm_array[i], &pm_info);
   3244         bcast_cfg.chain_last = (pm_array[i]==last_pm ? 1 : 0);
   3245 
   3246         portmod_fw_bcast(unit, pm_info, &bcast_cfg);
   3247     }
   3248 
   3249     return SOC_E_NONE;
   3250 }
   3251 
   3252 #define PORTMOD_SBUS_BCAST_PM_MAX_NUM 32
   3253 
   3254 /*
   3255  * This function is SerDes broadcast entry
   3256  * It's called between INIT_PASS1 and INIT_PASS2
   3257  */
   3258 int portmod_common_serdes_fw_bcst(int unit, pbmp_t pbmp, int crc_enable)
   3259 {
   3260     soc_port_t port;
   3261     int pm_array[PORTMOD_SBUS_BCAST_PM_MAX_NUM], pm_num, ring_bcast_id, ring_last_pm;
   3262     int pm_id, port_bcast_id, port_pos, rv, last_pos;
   3263 
   3264     if ((SOC_PORTCTRL_FUNCTIONS(unit) == NULL)
   3265         || (SOC_PORTCTRL_FUNCTIONS(unit)->soc_portctrl_sbus_ring_info_get == NULL)) {
   3266         return SOC_E_UNAVAIL;
   3267     }
   3268 
   3269     do {
   3270         pm_num = 0;
   3271         ring_bcast_id = -1;
   3272         ring_last_pm = 0;
   3273         last_pos = -1;
   3274 
   3275         /*
   3276          * find all PMs belongs to the same broadcast ring and put them into a PM list
   3277          */
   3278         PBMP_ITER(pbmp, port) {
   3279             rv= SOC_PORTCTRL_FUNCTIONS(unit)->soc_portctrl_sbus_ring_info_get(unit, port, &port_bcast_id, &port_pos);
   3280             if (SOC_FAILURE(rv)) {
   3281                 /* this port doesn't exist in any broadcast ring */
   3282                 SOC_PBMP_PORT_REMOVE(pbmp, port);
   3283                 continue;
   3284             }
   3285 
   3286             if (ring_bcast_id != -1 && port_bcast_id != ring_bcast_id) {
   3287                 /* this port doesn't belong to current broadcast ring */
   3288                 continue;
   3289             }
   3290 
   3291             if (ring_bcast_id == -1) {
   3292                 /* this port is the first element of current broadcast ring */
   3293                 ring_bcast_id = port_bcast_id;
   3294             }
   3295 
   3296             SOC_PBMP_PORT_REMOVE(pbmp, port);
   3297 
   3298             portmod_port_pm_id_get(unit, port, &pm_id);
   3299 
   3300             if (_portmod_pm_id_find(pm_array, pm_num, pm_id)) {
   3301                 /* this port has been already put into broadcast ring */
   3302                 continue;
   3303             }
   3304 
   3305             pm_array[pm_num] = pm_id;
   3306             if (port_pos > last_pos) {
   3307                 last_pos = port_pos;
   3308                 ring_last_pm = pm_id;
   3309             }
   3310             pm_num++;
   3311         }
   3312 
   3313         /* broadcast on PM list */
   3314         if (pm_num > 0) {
   3315             _portmod_sbus_ring_bcast(unit, pm_array, pm_num, ring_bcast_id, ring_last_pm, crc_enable);
   3316         }
   3317     } while (SOC_PBMP_NOT_NULL(pbmp));
   3318 
   3319     return SOC_E_NONE;
   3320 }
   3321 #endif
   3322 
   3323 #undef _ERR_MSG_MODULE_NAME