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

tscf_gen3.c (121858B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <phymod/phymod.h>
     11 #include <phymod/phymod_system.h>
     12 #include <phymod/phymod_util.h>
     13 #include <phymod/phymod_dispatch.h>
     14 #include <phymod/chip/falcon_dpll.h>
     15 #include <phymod/chip/tscf_gen3.h>
     16 #include <phymod/chip/bcmi_tscf_gen3_xgxs_defs.h>
     17 #include "tscf_gen3/tier1/tefmod_gen3.h"
     18 #include "tscf_gen3/tier1/tefmod_gen3_enum_defines.h"
     19 #include "tscf_gen3/tier1/tefmod_gen3_sc_lkup_table.h"
     20 #include "falcon_dpll/tier1/falcon2_monterey_interface.h"
     21 #include "falcon_dpll/tier1/falcon2_monterey_debug_functions.h"
     22 #include "falcon_dpll/tier1/falcon_api_uc_common.h"
     23 #include "falcon_dpll/tier1/falcon_dpll_cfg_seq.h"
     24 
     25 
     26 #define TSCF_GEN3_ID0                 	0x600d
     27 #define TSCF_GEN3_ID1                 	0x8770
     28 #define TSC4F_GEN3_MODEL              	0x24
     29 #define TSCF_GEN3_TECH_PROC           	0x3
     30 #define TSCF_GEN3_NOF_LANES_IN_CORE     4
     31 #define TSCF_GEN3_LANE_SWAP_LANE_MASK   3
     32 #define TSCF_GEN3_NOF_DFES              6
     33 #define TSCF_GEN3_PHY_ALL_LANES         0xf
     34 
     35 #define TSCF_GEN3_PMD_CRC_UCODE_VERIFY  1
     36 
     37 /* uController's firmware */
     38 extern unsigned char falcon_dpll_ucode[];
     39 extern unsigned short falcon_dpll_ucode_ver;
     40 extern unsigned short falcon_dpll_ucode_crc;
     41 extern unsigned short falcon_dpll_ucode_len;
     42 
     43 
     44 #define TSCF_GEN3_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \
     45     do{\
     46         PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\
     47         (_phy_access)->type           = (_core_access)->type; \
     48         (_phy_access)->port_loc       = (_core_access)->port_loc; \
     49         (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \
     50         (_phy_access)->access.lane_mask = TSCF_GEN3_PHY_ALL_LANES; \
     51     }while(0)
     52 
     53 STATIC
     54 int _tscf_gen3_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
     55 {
     56     struct falcon2_monterey_uc_lane_config_st serdes_firmware_config;
     57     phymod_phy_access_t phy_copy;
     58     int start_lane, num_lane, i;
     59     uint32_t is_warm_boot;
     60 
     61     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
     62     PHYMOD_IF_ERR_RETURN
     63         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
     64     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
     65 
     66     for (i = 0; i < num_lane; i++) {
     67         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
     68             continue;
     69         }
     70         phy_copy.access.lane_mask = 1 << (start_lane + i);
     71         serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS;
     72         serdes_firmware_config.field.an_enabled        = fw_config.AnEnabled;
     73         serdes_firmware_config.field.dfe_on            = fw_config.DfeOn;
     74         serdes_firmware_config.field.dfe_lp_mode       = fw_config.LpDfeOn;
     75         serdes_firmware_config.field.force_brdfe_on    = fw_config.ForceBrDfe;
     76         serdes_firmware_config.field.media_type        = fw_config.MediaType;
     77         serdes_firmware_config.field.unreliable_los    = fw_config.UnreliableLos;
     78         serdes_firmware_config.field.scrambling_dis    = fw_config.ScramblingDisable;
     79         serdes_firmware_config.field.cl72_auto_polarity_en   = fw_config.Cl72AutoPolEn;
     80         serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO;
     81         /*serdes_firmware_config.field.en_short_chn_osx1 = fw_config.short_chn;*/
     82 
     83         PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot));
     84 
     85         if(!is_warm_boot) {
     86             PHYMOD_IF_ERR_RETURN (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0));
     87             PHYMOD_IF_ERR_RETURN(falcon2_monterey_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config));
     88             PHYMOD_IF_ERR_RETURN (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1));
     89 
     90         }
     91     }
     92 
     93     return PHYMOD_E_NONE;
     94 }
     95 
     96 int tscf_gen3_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
     97 {
     98     int ioerr = 0;
     99     const phymod_access_t *pm_acc = &core->access;
    100     PHYID2r_t id2;
    101     PHYID3r_t id3;
    102     MAIN0_SERDESIDr_t serdes_id;
    103     uint32_t model;
    104 
    105     *is_identified = 0;
    106 
    107     if (core_id == 0){
    108         ioerr += READ_PHYID2r(pm_acc, &id2);
    109         ioerr += READ_PHYID3r(pm_acc, &id3);
    110     } else {
    111         PHYID2r_SET(id2, ((core_id >> 16) & 0xffff));
    112         PHYID3r_SET(id3, core_id & 0xffff);
    113     }
    114 
    115     if (PHYID2r_REGID1f_GET(id2) == TSCF_GEN3_ID0 &&
    116        (PHYID3r_REGID2f_GET(id3) == TSCF_GEN3_ID1)) {
    117         /* PHY IDs match - now check SERDES ID model number */
    118         ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdes_id);
    119         model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdes_id);
    120         if (model == TSC4F_GEN3_MODEL)  {
    121             if (MAIN0_SERDESIDr_TECH_PROCf_GET(serdes_id) == TSCF_GEN3_TECH_PROC) {
    122                 *is_identified = 1;
    123             }
    124         }
    125     }
    126 
    127     return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE;
    128 }
    129 
    130 int tscf_gen3_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info)
    131 {        
    132     uint32_t serdes_id = TSC4F_GEN3_MODEL; 
    133     char core_name[15] = "TscfGen3";
    134     PHYID2r_t id2;
    135     PHYID3r_t id3;
    136     const phymod_access_t *pm_acc = &core->access;
    137 
    138      PHYMOD_IF_ERR_RETURN
    139         (tefmod_gen3_revid_read(&core->access, &serdes_id));
    140     PHYMOD_IF_ERR_RETURN
    141         (phymod_core_name_get(core, serdes_id, core_name, info));
    142     info->serdes_id = serdes_id;
    143     info->core_version = phymodCoreVersionTscfGen3;
    144 
    145     PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2));
    146     PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3));
    147 
    148     info->phy_id0 = (uint16_t) id2.v[0];
    149     info->phy_id1 = (uint16_t) id3.v[0];
    150 
    151     return PHYMOD_E_NONE;
    152 }
    153 
    154 /* pcs_or_pmd = 1 => do the PCS lane swap
    155    pcs_or_pmd = 0 => do the PMD lane swap */
    156 static int _tscf_gen3_core_lane_map_part_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map, int pcs_or_pmd)
    157 {
    158     uint32_t lane, pcs_tx_swap = 0, pcs_rx_swap = 0;
    159     uint8_t pmd_tx_addr[4], pmd_rx_addr[4];
    160 
    161     if (lane_map->num_of_lanes != TSCF_GEN3_NOF_LANES_IN_CORE){
    162         return PHYMOD_E_CONFIG;
    163     }
    164     for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++){
    165         if ((lane_map->lane_map_tx[lane] >= TSCF_GEN3_NOF_LANES_IN_CORE)||
    166              (lane_map->lane_map_rx[lane] >= TSCF_GEN3_NOF_LANES_IN_CORE)){
    167             return PHYMOD_E_CONFIG;
    168         }
    169         /* Encode each lane as four bits */
    170         pcs_tx_swap += lane_map->lane_map_tx[lane]<<(lane*4);
    171         pcs_rx_swap += lane_map->lane_map_rx[lane]<<(lane*4);
    172     }
    173     /* PMD lane addr is based on PCS logical to physical mapping */
    174     for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++){
    175         pmd_tx_addr[((pcs_tx_swap >> (lane*4)) & 0xf)] = lane;
    176         pmd_rx_addr[((pcs_rx_swap >> (lane*4)) & 0xf)] = lane;
    177     }
    178 
    179     if(pcs_or_pmd) {
    180         PHYMOD_IF_ERR_RETURN
    181             (tefmod_gen3_pcs_tx_lane_swap(&core->access, pcs_tx_swap));
    182         PHYMOD_IF_ERR_RETURN
    183             (tefmod_gen3_pcs_rx_lane_swap(&core->access, pcs_rx_swap));
    184     } else {
    185         PHYMOD_IF_ERR_RETURN
    186             (falcon2_monterey_map_lanes(&core->access, TSCF_GEN3_NOF_LANES_IN_CORE, pmd_tx_addr, pmd_rx_addr));
    187     }
    188 
    189     return PHYMOD_E_NONE;
    190 }
    191 
    192 int tscf_gen3_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    193 {
    194    PHYMOD_IF_ERR_RETURN
    195        (_tscf_gen3_core_lane_map_part_set(core, lane_map, 1));
    196    PHYMOD_IF_ERR_RETURN
    197        (_tscf_gen3_core_lane_map_part_set(core, lane_map, 0));
    198 
    199     return PHYMOD_E_NONE;
    200 }
    201 
    202 int tscf_gen3_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
    203 {        
    204     uint32_t pcs_tx_swap = 0 , pcs_rx_swap = 0, lane;
    205 
    206     PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_tx_lane_swap_get(&core->access, &pcs_tx_swap));
    207     PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_rx_lane_swap_get(&core->access, &pcs_rx_swap));
    208 
    209     for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE ; lane++){
    210         /* Decode each lane from four bits */
    211         lane_map->lane_map_tx[lane] = (pcs_tx_swap>>(lane*4)) & TSCF_GEN3_LANE_SWAP_LANE_MASK;
    212         lane_map->lane_map_rx[lane] = (pcs_rx_swap>>(lane*4)) & TSCF_GEN3_LANE_SWAP_LANE_MASK;
    213     }
    214     lane_map->num_of_lanes = TSCF_GEN3_NOF_LANES_IN_CORE;
    215  
    216     return PHYMOD_E_NONE;
    217 }
    218 
    219 
    220 int tscf_gen3_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
    221 {        
    222     
    223     return PHYMOD_E_UNAVAIL;
    224     
    225 }
    226 
    227 int tscf_gen3_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
    228 {        
    229     
    230     return PHYMOD_E_UNAVAIL;
    231 
    232 }
    233 
    234 int tscf_gen3_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info)
    235 {        
    236     
    237     return PHYMOD_E_NONE;
    238     
    239 }
    240 
    241 STATIC
    242 int _tscf_gen3_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader) 
    243 {
    244     /* coverity[assignment:FALSE] */
    245     load_method = phymodFirmwareLoadMethodInternal;
    246     /* coverity[const:FALSE] */
    247     /* coverity[dead_error_condition:FALSE] */
    248     switch(load_method){
    249     case phymodFirmwareLoadMethodInternal:
    250         PHYMOD_IF_ERR_RETURN(falcon2_monterey_ucode_mdio_load(&core->access, falcon_dpll_ucode, falcon_dpll_ucode_len));
    251         break;
    252     case phymodFirmwareLoadMethodExternal:
    253         PHYMOD_NULL_CHECK(fw_loader);
    254         PHYMOD_IF_ERR_RETURN(falcon2_monterey_ucode_init(&core->access));
    255         PHYMOD_IF_ERR_RETURN
    256             (falcon2_monterey_pram_firmware_enable(&core->access, 1, 0));
    257         PHYMOD_IF_ERR_RETURN(fw_loader(core, falcon_dpll_ucode_len, falcon_dpll_ucode));
    258         PHYMOD_IF_ERR_RETURN
    259             (falcon2_monterey_pram_firmware_enable(&core->access, 0, 0));
    260         break;
    261     /* coverity[DEADCODE:FALSE] */
    262     case phymodFirmwareLoadMethodNone:
    263         break;
    264     /* coverity[dead_event_begin:FALSE] */
    265     default:
    266         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method));
    267     }
    268 
    269     return PHYMOD_E_NONE;
    270 }
    271 
    272 int tscf_gen3_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config)
    273 {        
    274     struct falcon2_monterey_uc_core_config_st serdes_firmware_core_config;   
    275 
    276     PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config));
    277     serdes_firmware_core_config.field.core_cfg_from_pcs = fw_core_config.CoreConfigFromPCS;
    278     serdes_firmware_core_config.field.vco_rate = fw_core_config.VcoRate;
    279     serdes_firmware_core_config.field.disable_write_pll_iqp = fw_core_config.disable_write_pll_iqp;
    280     PHYMOD_IF_ERR_RETURN(falcon2_monterey_set_uc_core_config(&phy->access, serdes_firmware_core_config));
    281 
    282     return PHYMOD_E_NONE;
    283 }
    284 
    285 int tscf_gen3_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config)
    286 {        
    287     struct falcon2_monterey_uc_core_config_st serdes_firmware_core_config;    
    288 
    289     PHYMOD_MEMSET(fw_core_config, 0, sizeof(*fw_core_config));
    290     PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_core_config(&phy->access, &serdes_firmware_core_config));
    291     fw_core_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs;
    292     fw_core_config->VcoRate = serdes_firmware_core_config.field.vco_rate;
    293     fw_core_config->disable_write_pll_iqp = serdes_firmware_core_config.field.disable_write_pll_iqp;
    294         
    295     return PHYMOD_E_NONE;
    296 }
    297 
    298 int tscf_gen3_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config)
    299 {        
    300     phymod_phy_access_t phy_copy; 
    301     int start_lane, num_lane, i;
    302              
    303     PHYMOD_IF_ERR_RETURN
    304         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    305     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    306 
    307     /* Hold the per lane soft reset bit */
    308     for (i = 0; i < num_lane; i++) {
    309         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    310             continue;
    311         }
    312         phy_copy.access.lane_mask = 1 << (start_lane + i);
    313         PHYMOD_IF_ERR_RETURN
    314             (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0));
    315     }
    316 
    317     PHYMOD_IF_ERR_RETURN
    318          (_tscf_gen3_phy_firmware_lane_config_set(phy, fw_lane_config));
    319 
    320     /* Release the per lane soft reset bit */
    321     for (i = 0; i < num_lane; i++) {
    322         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    323             continue;
    324         }
    325         phy_copy.access.lane_mask = 1 << (start_lane + i);
    326         PHYMOD_IF_ERR_RETURN
    327             (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1));
    328     }
    329 
    330     /* Toggle the pcs data path reset */
    331     PHYMOD_IF_ERR_RETURN
    332         (tefmod_gen3_trigger_speed_change(&phy->access));
    333 
    334     return PHYMOD_E_NONE;
    335 }
    336 
    337 int tscf_gen3_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config)
    338 {        
    339     struct falcon2_monterey_uc_lane_config_st serdes_firmware_config;
    340     phymod_phy_access_t phy_copy;
    341     int start_lane, num_lane;
    342 
    343     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    344     PHYMOD_IF_ERR_RETURN
    345         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    346 
    347     phy_copy.access.lane_mask = 1 << start_lane ;
    348 
    349     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    350     PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_lane_cfg(&phy_copy.access, &serdes_firmware_config));
    351     PHYMOD_MEMSET(fw_lane_config, 0, sizeof(*fw_lane_config));
    352     fw_lane_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs;
    353     fw_lane_config->AnEnabled         = serdes_firmware_config.field.an_enabled;
    354     fw_lane_config->DfeOn             = serdes_firmware_config.field.dfe_on;
    355     fw_lane_config->LpDfeOn           = serdes_firmware_config.field.dfe_lp_mode;
    356     fw_lane_config->ForceBrDfe        = serdes_firmware_config.field.force_brdfe_on;
    357     fw_lane_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis;
    358     fw_lane_config->UnreliableLos     = serdes_firmware_config.field.unreliable_los;
    359     fw_lane_config->MediaType         = serdes_firmware_config.field.media_type;
    360     fw_lane_config->Cl72AutoPolEn     = serdes_firmware_config.field.cl72_auto_polarity_en;
    361     fw_lane_config->Cl72RestTO        = serdes_firmware_config.field.cl72_restart_timeout_en;
    362         
    363     return PHYMOD_E_NONE;
    364 }
    365 
    366 int tscf_gen3_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
    367 {        
    368     
    369     return PHYMOD_E_UNAVAIL;
    370     
    371 }
    372 
    373 int tscf_gen3_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout)
    374 {        
    375     
    376     return PHYMOD_E_NONE;
    377     
    378 }
    379 
    380 int tscf_gen3_phy_rx_restart(const phymod_phy_access_t* phy)
    381 {        
    382     
    383     PHYMOD_IF_ERR_RETURN(falcon2_monterey_rx_restart(&phy->access, 1));
    384 
    385     return PHYMOD_E_NONE;
    386 }
    387 
    388 int tscf_gen3_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    389 {        
    390     PHYMOD_IF_ERR_RETURN
    391         (tefmod_gen3_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity));
    392 
    393     return PHYMOD_E_NONE;
    394 }
    395 
    396 int tscf_gen3_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    397 {        
    398     PHYMOD_IF_ERR_RETURN
    399         (tefmod_gen3_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity));
    400         
    401     return PHYMOD_E_NONE;
    402 }
    403 
    404 int tscf_gen3_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    405 {
    406     PHYMOD_IF_ERR_RETURN
    407         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre));
    408     PHYMOD_IF_ERR_RETURN
    409         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main));
    410     PHYMOD_IF_ERR_RETURN
    411         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post));
    412     PHYMOD_IF_ERR_RETURN
    413         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2));
    414     PHYMOD_IF_ERR_RETURN
    415         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3));
    416     PHYMOD_IF_ERR_RETURN
    417         (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_AMP,  (int8_t)tx->amp));
    418     if((tx->drivermode != -1) &&
    419        (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) {
    420         PHYMOD_IF_ERR_RETURN
    421             (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE,  (int8_t)tx->drivermode));
    422     }
    423 
    424     return PHYMOD_E_NONE;
    425 
    426 }
    427 
    428 int tscf_gen3_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    429 {
    430     int8_t value = 0;
    431 
    432     PHYMOD_IF_ERR_RETURN
    433         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_PRE, &value));
    434     tx->pre = value;
    435     PHYMOD_IF_ERR_RETURN
    436         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_MAIN, &value));
    437     tx->main = value;
    438     PHYMOD_IF_ERR_RETURN
    439         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST1, &value));
    440     tx->post = value;
    441     PHYMOD_IF_ERR_RETURN
    442         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST2, &value));
    443     tx->post2 = value;
    444     PHYMOD_IF_ERR_RETURN
    445         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST3, &value));
    446     tx->post3 = value;
    447     PHYMOD_IF_ERR_RETURN
    448         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_AMP, &value));
    449     tx->amp = value;
    450     PHYMOD_IF_ERR_RETURN
    451         (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &value));
    452     tx->drivermode = value;
    453 
    454     return PHYMOD_E_NONE;
    455 }
    456 
    457 
    458 int tscf_gen3_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override)
    459 {        
    460     PHYMOD_IF_ERR_RETURN
    461         (falcon2_monterey_tx_pi_freq_override(&phy->access,
    462                                     tx_override->phase_interpolator.enable,
    463                                     tx_override->phase_interpolator.value));
    464  
    465     return PHYMOD_E_NONE;
    466     
    467 }
    468 
    469 int tscf_gen3_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override)
    470 {        
    471     int16_t pi_value;
    472 
    473     PHYMOD_IF_ERR_RETURN
    474         (falcon2_monterey_tx_pi_control_get(&phy->access, &pi_value));
    475     tx_override->phase_interpolator.value = (int32_t) pi_value;
    476 
    477  return PHYMOD_E_NONE;
    478     
    479 }
    480 
    481 int tscf_gen3_phy_txpi_config_set(const phymod_phy_access_t* phy, const phymod_txpi_config_t* config)
    482 {
    483     phymod_phy_access_t phy_copy;
    484 
    485     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    486 
    487     PHYMOD_IF_ERR_RETURN
    488          (falcon2_monterey_tx_pi_enable_set(&phy_copy.access, config->enable));
    489 
    490     PHYMOD_IF_ERR_RETURN
    491          (falcon2_monterey_tx_pi_ext_pd_select_set(&phy_copy.access, config->mode == PHYMOD_TXPI_EXT_PD_MODE ? 1 : 0));
    492 
    493     return PHYMOD_E_NONE;
    494 }
    495 
    496 int tscf_gen3_phy_txpi_config_get(const phymod_phy_access_t* phy, phymod_txpi_config_t* config)
    497 {
    498     phymod_phy_access_t phy_copy;
    499     uint32_t ext_pd;
    500 
    501     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    502 
    503     PHYMOD_IF_ERR_RETURN
    504          (falcon2_monterey_tx_pi_enable_get(&phy_copy.access, &config->enable));
    505 
    506     PHYMOD_IF_ERR_RETURN
    507          (falcon2_monterey_tx_pi_ext_pd_select_get(&phy_copy.access, &ext_pd));
    508 
    509     config->mode = ext_pd ? PHYMOD_TXPI_EXT_PD_MODE : PHYMOD_TXPI_NORMAL_MODE;
    510 
    511     return PHYMOD_E_NONE;
    512 }
    513 
    514 int tscf_gen3_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    515 {        
    516     uint32_t i;
    517     uint8_t uc_lane_stopped;
    518     phymod_phy_access_t pm_phy_copy;
    519     int start_lane, num_lane, k;
    520 
    521     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    522     /* Program the tx fir taps and driver current based on the input */
    523     PHYMOD_IF_ERR_RETURN
    524         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    525 
    526     /* Check params */
    527     if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF_GEN3_NOF_DFES)){
    528         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps));
    529     }
    530 
    531     for (k = 0; k < num_lane; k++) {
    532         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + k)) {
    533             continue;
    534         }
    535         pm_phy_copy.access.lane_mask = 1 << (start_lane + k);
    536 
    537         /* Check if Micro is stopped on a lane */
    538         PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_uc_lane_status(&pm_phy_copy.access, &uc_lane_stopped));
    539         if (!uc_lane_stopped) {
    540             PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_rx_adaptation(&pm_phy_copy.access, 1));
    541         }
    542         /* vga set */
    543         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_VGA, rx->vga.value));
    544         /* dfe set */
    545         for (i = 0 ; i < rx->num_of_dfe_taps ; i++){
    546             switch (i) {
    547                 case 0:
    548                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE1, rx->dfe[i].value));
    549                     break;
    550                 case 1:
    551                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE2, rx->dfe[i].value));
    552                     break;
    553                 case 2:
    554                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE3, rx->dfe[i].value));
    555                     break;
    556                 case 3:
    557                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE4, rx->dfe[i].value));
    558                     break;
    559                 case 4:
    560                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE5, rx->dfe[i].value));
    561                     break;
    562                 case 5:
    563                         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE6, rx->dfe[i].value));
    564                     break;
    565                 default:
    566                     return PHYMOD_E_PARAM;
    567             }
    568         }
    569 
    570         /*peaking filter set*/
    571         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF, rx->peaking_filter.value));
    572 
    573         /* low freq peak filter */
    574         PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF2, (int8_t)rx->low_freq_peaking_filter.value));
    575     }
    576 
    577     return PHYMOD_E_NONE;
    578 }
    579 
    580 int tscf_gen3_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    581 {        
    582     int8_t tmpData;
    583 
    584     PHYMOD_IF_ERR_RETURN
    585         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_VGA,  &tmpData));
    586     rx->vga.value = tmpData;
    587     PHYMOD_IF_ERR_RETURN
    588         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE1,  &tmpData));
    589     rx->dfe[0].value = tmpData;
    590     PHYMOD_IF_ERR_RETURN
    591         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE2,  &tmpData));
    592     rx->dfe[1].value = tmpData;
    593     PHYMOD_IF_ERR_RETURN
    594         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE3,  &tmpData));
    595     rx->dfe[2].value = tmpData;
    596     PHYMOD_IF_ERR_RETURN
    597         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE4,  &tmpData));
    598     rx->dfe[3].value = tmpData;
    599     PHYMOD_IF_ERR_RETURN
    600         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE5,  &tmpData));
    601     rx->dfe[4].value = tmpData;
    602     PHYMOD_IF_ERR_RETURN
    603         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE6,  &tmpData));
    604     rx->dfe[5].value = tmpData;
    605     PHYMOD_IF_ERR_RETURN
    606         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_PF,  &tmpData));
    607     rx->peaking_filter.value = tmpData;
    608     PHYMOD_IF_ERR_RETURN
    609         (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_PF2,  &tmpData));
    610     rx->low_freq_peaking_filter.value = tmpData;
    611 
    612     rx->num_of_dfe_taps = 6;
    613     rx->dfe[0].enable = 1;
    614     rx->dfe[1].enable = 1;
    615     rx->dfe[2].enable = 1;
    616     rx->dfe[3].enable = 1;
    617     rx->dfe[4].enable = 1;
    618     rx->dfe[5].enable = 1;
    619     rx->vga.enable = 1;
    620     rx->low_freq_peaking_filter.enable = 1;
    621     rx->peaking_filter.enable = 1;
    622 
    623     return PHYMOD_E_NONE;
    624 }
    625 
    626 
    627 int tscf_gen3_phy_rx_adaptation_resume(const phymod_phy_access_t* phy)
    628 {        
    629     uint8_t uc_lane_stopped;
    630 
    631     PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_uc_lane_status(&phy->access, &uc_lane_stopped));
    632     if (uc_lane_stopped) {
    633         PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_rx_adaptation(&phy->access, 0));
    634     }
    635         
    636     return PHYMOD_E_NONE;
    637 }
    638 
    639 int tscf_gen3_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    640 {        
    641 
    642     return PHYMOD_E_NONE;
    643     
    644 }
    645 
    646 int tscf_gen3_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    647 {        
    648     
    649     return PHYMOD_E_NONE;
    650     
    651 }
    652 
    653 
    654 int tscf_gen3_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
    655 {        
    656     phymod_phy_access_t pm_phy_copy;
    657     int start_lane, num_lane, i;
    658 
    659     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    660     PHYMOD_IF_ERR_RETURN
    661         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    662     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) {
    663         for (i = 0; i < num_lane; i++) {
    664             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    665                 continue;
    666             }
    667             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    668             PHYMOD_IF_ERR_RETURN(tefmod_gen3_port_enable_set(&pm_phy_copy.access, 0));
    669         }
    670     }
    671     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) {
    672         for (i = 0; i < num_lane; i++) {
    673             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    674                 continue;
    675             }
    676             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    677             PHYMOD_IF_ERR_RETURN(tefmod_gen3_port_enable_set(&pm_phy_copy.access, 1));
    678             PHYMOD_IF_ERR_RETURN(tefmod_gen3_power_control(&phy->access, 0, 0));
    679         }
    680     }
    681     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) {
    682         /* Disable tx on the PMD side */
    683         PHYMOD_IF_ERR_RETURN(falcon2_monterey_tx_disable(&phy->access, 1));
    684     }
    685     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) {
    686         /* Enable tx on the PMD side */
    687         PHYMOD_IF_ERR_RETURN(falcon2_monterey_tx_disable(&phy->access, 0));
    688     }
    689     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) {
    690         /* Force PMD signal detect value */
    691         PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&phy->access, 1));
    692     }
    693     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) {
    694         /* Remove PMD signal detect value */
    695         PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&phy->access, 0));
    696     }
    697 
    698     return PHYMOD_E_NONE;
    699 }
    700 
    701 int tscf_gen3_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
    702 {        
    703     int enable;
    704     uint32_t lb_enable;
    705     phymod_phy_access_t pm_phy_copy;
    706     int start_lane, num_lane;
    707 
    708     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    709     PHYMOD_IF_ERR_RETURN
    710         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    711 
    712     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    713 
    714     PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_get(&pm_phy_copy.access, &enable));
    715 
    716     /* Check if PMD loopback is on */
    717     if (enable) {
    718         PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    719         if (lb_enable) enable = 0;
    720     }
    721 
    722     power->rx = (enable == 1)? phymodPowerOff: phymodPowerOn;
    723     /* Commented the following line. Because if in PMD loopback mode, we squelch the
    724            xmit, and we should still see the correct port status */
    725     /* PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_get(&pm_phy_copy.access, &enable)); */
    726     power->tx = (enable == 1)? phymodPowerOff: phymodPowerOn;
    727 
    728  
    729     return PHYMOD_E_NONE;
    730     
    731 }
    732 
    733 int tscf_gen3_phy_hg2_codec_control_set(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t hg2_codec)
    734 {        
    735     tefmod_gen3_hg2_codec_t local_copy;
    736 
    737     switch (hg2_codec) {
    738         case phymodBcmHG2CodecOff: 
    739             local_copy = TEFMOD_HG2_CODEC_OFF;
    740             break;
    741         case phymodBcmHG2CodecOnWith8ByteIPG:  
    742             local_copy = TEFMOD_HG2_CODEC_ON_8BYTE_IPG;
    743             break;
    744         case phymodBcmHG2CodecOnWith9ByteIPG:  
    745             local_copy = TEFMOD_HG2_CODEC_ON_9BYTE_IPG;
    746             break;
    747         default: 
    748             local_copy = TEFMOD_HG2_CODEC_OFF;
    749             break;
    750     }
    751     PHYMOD_IF_ERR_RETURN(tefmod_gen3_hg2_codec_set(&phy->access, local_copy));
    752         
    753     return PHYMOD_E_NONE;
    754 }
    755 
    756 int tscf_gen3_phy_hg2_codec_control_get(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t* hg2_codec)
    757 {        
    758     tefmod_gen3_hg2_codec_t local_copy;
    759 
    760     PHYMOD_IF_ERR_RETURN(tefmod_gen3_hg2_codec_get(&phy->access, &local_copy));
    761 
    762     switch (local_copy) {
    763         case TEFMOD_HG2_CODEC_OFF: 
    764             *hg2_codec = phymodBcmHG2CodecOff;
    765             break;
    766         case TEFMOD_HG2_CODEC_ON_8BYTE_IPG:  
    767             *hg2_codec = phymodBcmHG2CodecOnWith8ByteIPG;
    768             break;
    769         case TEFMOD_HG2_CODEC_ON_9BYTE_IPG:  
    770             *hg2_codec = phymodBcmHG2CodecOnWith9ByteIPG;
    771             break;
    772         default: 
    773             *hg2_codec = phymodBcmHG2CodecOff;
    774             break;
    775     }
    776 
    777     return PHYMOD_E_NONE;
    778 }
    779 
    780 int tscf_gen3_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    781 {        
    782     phymod_firmware_lane_config_t fw_lane_config;
    783 
    784     PHYMOD_IF_ERR_RETURN (tscf_gen3_phy_firmware_lane_config_get(phy, &fw_lane_config));
    785 
    786     switch (tx_control) {
    787     case phymodTxTrafficDisable:
    788         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_DISABLE));
    789         break;
    790     case phymodTxTrafficEnable:
    791         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_ENABLE));
    792         break;
    793     case phymodTxReset:
    794         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_RESET));
    795         break;
    796     case phymodTxSquelchOn:
    797         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_set(&phy->access, 1));
    798         break;
    799     case phymodTxSquelchOff:
    800         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_set(&phy->access, 0));
    801         break;
    802     case phymodTxElectricalIdleEnable:
    803         if (fw_lane_config.LaneConfigFromPCS == 0) {
    804             PHYMOD_IF_ERR_RETURN(falcon2_monterey_electrical_idle_set(&phy->access, 1));
    805         }else{
    806             return PHYMOD_E_UNAVAIL; 
    807         }
    808         break;
    809     case phymodTxElectricalIdleDisable:
    810         if (fw_lane_config.LaneConfigFromPCS == 0) {
    811             PHYMOD_IF_ERR_RETURN(falcon2_monterey_electrical_idle_set(&phy->access, 0));
    812         }else{
    813             return PHYMOD_E_UNAVAIL;
    814         }
    815         break;
    816     default:
    817         break;
    818     }
    819         
    820     return PHYMOD_E_NONE;
    821 }
    822 
    823 int tscf_gen3_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    824 {        
    825     int enable, reset, tx_lane;
    826     uint32_t lb_enable;
    827     phymod_phy_access_t pm_phy_copy;
    828     int start_lane, num_lane;
    829 
    830     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    831     PHYMOD_IF_ERR_RETURN
    832         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    833 
    834     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    835 
    836     PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_get(&pm_phy_copy.access, &enable));
    837 
    838     /* Check if PMD loopback is on */
    839     if (enable) {
    840         PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    841         if (lb_enable) enable = 0;
    842     }
    843     if (enable) {
    844         *tx_control = phymodTxSquelchOn;
    845     } else {
    846         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane));
    847         if (!reset) {
    848             *tx_control = phymodTxReset;
    849         } else if (!tx_lane) {
    850             *tx_control = phymodTxTrafficDisable;
    851         } else {
    852             *tx_control = phymodTxTrafficEnable;
    853         }
    854     }
    855         
    856     return PHYMOD_E_NONE;
    857 }
    858 
    859 
    860 int tscf_gen3_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    861 {        
    862      phymod_phy_access_t pm_phy_copy;
    863     int start_lane, num_lane, i;
    864 
    865     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    866     PHYMOD_IF_ERR_RETURN
    867         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    868 
    869     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    870 
    871     switch (rx_control) {
    872     case phymodRxReset:
    873         PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_set(&phy->access, 1));
    874         break;
    875     case phymodRxSquelchOn:
    876         for (i = 0; i < num_lane; i++) {
    877             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    878                 continue;
    879             }
    880             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    881             PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&pm_phy_copy.access, 1));
    882         }
    883         break;
    884     case phymodRxSquelchOff:
    885         for (i = 0; i < num_lane; i++) {
    886             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    887                 continue;
    888             }
    889             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    890             PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&pm_phy_copy.access, 0));
    891         }
    892         break;
    893     default:
    894         break;
    895     }
    896  
    897     return PHYMOD_E_NONE;
    898 }
    899 
    900 int tscf_gen3_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    901 {        
    902     int enable, reset;
    903     uint32_t lb_enable;
    904     phymod_phy_access_t pm_phy_copy;
    905     int start_lane, num_lane;
    906 
    907     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    908     PHYMOD_IF_ERR_RETURN
    909         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    910 
    911     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    912 
    913     PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_get(&pm_phy_copy.access, &enable));
    914     /* Check if PMD loopback is on */
    915     if (enable) {
    916         PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    917         if (lb_enable) enable = 0;
    918     }
    919     if (enable) {
    920         *rx_control = phymodRxSquelchOn;
    921     } else {
    922         PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_get(&pm_phy_copy.access, &reset));
    923         if (reset == 0) {
    924             *rx_control = phymodRxReset;
    925         } else {
    926             *rx_control = phymodRxSquelchOff;
    927         }
    928     }
    929         
    930     return PHYMOD_E_NONE;
    931 }
    932 
    933 
    934 int tscf_gen3_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    935 {        
    936     int fec_en;
    937     tefmod_gen3_fec_type_t fec_type;
    938 
    939     /* first check FEC type */
    940     if (PHYMOD_FEC_CL91_GET(enable)) {
    941         fec_type = TEFMOD_CL91;
    942     } else if (PHYMOD_FEC_CL108_GET(enable)) {
    943         fec_type = TEFMOD_CL108;
    944     } else {
    945         fec_type = TEFMOD_CL74;
    946     }
    947 
    948     /* check FEC on/off */
    949     fec_en  = enable & TEFMOD_PHY_CONTROL_FEC_MASK;
    950     PHYMOD_IF_ERR_RETURN(
    951       tefmod_gen3_FEC_control(&phy->access, fec_type, fec_en, 0));
    952 
    953     return PHYMOD_E_NONE;
    954 }
    955 
    956 int tscf_gen3_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    957 {        
    958     int fec_en;
    959     tefmod_gen3_fec_type_t fec_type;
    960 
    961     /* first check FEC type */
    962     if (PHYMOD_FEC_CL91_GET(*enable)) {
    963         fec_type = TEFMOD_CL91;
    964     } else if (PHYMOD_FEC_CL108_GET(*enable)) {
    965         fec_type = TEFMOD_CL108;
    966     } else {
    967         fec_type = TEFMOD_CL74;
    968     }
    969 
    970     PHYMOD_IF_ERR_RETURN(
    971       tefmod_gen3_FEC_get(&phy->access, fec_type, &fec_en));
    972     PHYMOD_DEBUG_VERBOSE(("FEC enable state :: %x :: fec_type :: %x\n", fec_en, fec_type));
    973     *enable = (uint32_t) fec_en;
    974         
    975     return PHYMOD_E_NONE;
    976 }
    977 
    978 int tscf_gen3_phy_autoneg_oui_set(const phymod_phy_access_t* phy, phymod_autoneg_oui_t an_oui)
    979 {        
    980     tefmod_gen3_an_oui_t oui;
    981 
    982     oui.oui                    = an_oui.oui;
    983     oui.oui_override_hpam_adv  = an_oui.oui_override_hpam_adv;
    984     oui.oui_override_hpam_det  = an_oui.oui_override_hpam_det;
    985     oui.oui_override_bam73_adv = an_oui.oui_override_bam73_adv;
    986     oui.oui_override_bam73_det = an_oui.oui_override_bam73_det;
    987 
    988     PHYMOD_IF_ERR_RETURN(tefmod_gen3_an_oui_set(&phy->access, oui));
    989         
    990     return PHYMOD_E_NONE;
    991 }
    992 
    993 int tscf_gen3_phy_autoneg_oui_get(const phymod_phy_access_t* phy, phymod_autoneg_oui_t* an_oui)
    994 {        
    995     tefmod_gen3_an_oui_t oui;
    996 
    997     PHYMOD_IF_ERR_RETURN(tefmod_gen3_an_oui_get(&phy->access, &oui));
    998     an_oui->oui_override_hpam_adv  = oui.oui_override_hpam_adv;
    999     an_oui->oui_override_hpam_det  = oui.oui_override_hpam_det;
   1000     an_oui->oui_override_bam73_adv = oui.oui_override_bam73_adv;
   1001     an_oui->oui_override_bam73_det = oui.oui_override_bam73_det;
   1002 
   1003     return PHYMOD_E_NONE;
   1004 }
   1005 
   1006 int tscf_gen3_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable)
   1007 {        
   1008     uint32_t lpi_bypass;
   1009     int rv = PHYMOD_E_NONE;
   1010     lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable);
   1011     enable &= 0x1;
   1012     if (lpi_bypass) {
   1013         rv = tefmod_gen3_eee_control_set(&phy->access,enable);
   1014     } else {
   1015         return PHYMOD_E_UNAVAIL;
   1016     }
   1017 
   1018     return rv;
   1019 }
   1020 
   1021 int tscf_gen3_phy_eee_get(const phymod_phy_access_t* phy, uint32_t* enable)
   1022 {        
   1023     if (PHYMOD_LPI_BYPASS_GET(*enable)) {
   1024         PHYMOD_IF_ERR_RETURN(tefmod_gen3_eee_control_get(&phy->access, enable));
   1025         PHYMOD_LPI_BYPASS_SET(*enable);
   1026     } else {
   1027         return PHYMOD_E_UNAVAIL;
   1028     }
   1029 
   1030     return PHYMOD_E_NONE;
   1031 }
   1032 
   1033 int tscf_gen3_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
   1034 {
   1035     int16_t new_os_mode = -1;
   1036     int16_t os_mode;
   1037     int start_lane, num_lane, lane;
   1038     uint32_t vco_rate;
   1039     uint32_t new_pll_div;
   1040     uint32_t cur_pll0_div = 0;
   1041     uint32_t cur_pll1_div = 0;
   1042     uint8_t cur_pll_select = 0;
   1043     int new_pll_set = 0;
   1044     int pll_index_update = 0;
   1045     int pll_index = 0;
   1046     phymod_phy_access_t pm_phy_copy;
   1047     tefmod_gen3_spd_intfc_type_t spd_intf = TEFMOD_SPD_ILLEGAL;
   1048     phymod_firmware_lane_config_t firmware_lane_config;
   1049     phymod_firmware_core_config_t firmware_core_config;
   1050 
   1051     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1052     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   1053     PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config));
   1054     PHYMOD_IF_ERR_RETURN
   1055         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1056 
   1057     /* Hold PCS lane reset */
   1058     tefmod_gen3_disable_set(&phy->access);
   1059 
   1060     /* Assert the ln dp reset */
   1061     for (lane = 0; lane < num_lane; lane++) {
   1062         if(!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane+lane)) {
   1063             continue;
   1064         }
   1065         pm_phy_copy.access.lane_mask = (1 << (start_lane + lane));
   1066         PHYMOD_IF_ERR_RETURN
   1067             (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1068     }
   1069 
   1070     /* Remove pmd_tx_disable_pin_dis, it may be asserted because of ILKN*/
   1071     if (config->interface_type != phymodInterfaceBypass) {
   1072         for (lane = 0; lane < num_lane; lane++) {
   1073             if(!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane+lane)) {
   1074                 continue;
   1075             }
   1076             pm_phy_copy.access.lane_mask = (1 << (start_lane + lane));
   1077             PHYMOD_IF_ERR_RETURN
   1078                 (falcon2_monterey_pmd_tx_disable_pin_dis_set(&pm_phy_copy.access, 0));
   1079         }
   1080     }
   1081 
   1082     pm_phy_copy.access.lane_mask = 0x1;
   1083     PHYMOD_IF_ERR_RETURN
   1084         (tscf_gen3_phy_firmware_core_config_get(&pm_phy_copy, &firmware_core_config));
   1085 
   1086     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1087     PHYMOD_IF_ERR_RETURN
   1088         (tscf_gen3_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   1089 
   1090     /* AutoNeg and core config from pcs are off */
   1091     firmware_core_config.CoreConfigFromPCS = 0;
   1092     firmware_lane_config.AnEnabled = 0;
   1093     firmware_lane_config.LaneConfigFromPCS = 0;
   1094     firmware_lane_config.DfeOn = 1;
   1095     firmware_lane_config.LpDfeOn = 0;
   1096     firmware_lane_config.Cl72RestTO = 1;
   1097     firmware_lane_config.Cl72AutoPolEn = 0;
   1098     firmware_lane_config.ScramblingDisable = 0;
   1099 
   1100     if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1101         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1102     } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1103         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1104     } else {
   1105         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1106     }
   1107 
   1108     if ((config->data_rate == 1000)||(config->data_rate == 2500)) {
   1109        firmware_lane_config.DfeOn = 0;
   1110     }
   1111 
   1112     /* Select port configuration mode */
   1113     PHYMOD_IF_ERR_RETURN
   1114         (tefmod_gen3_port_mode_select(&phy->access)); 
   1115 
   1116     /* Lookup speed ID table */
   1117     if (config->interface_type == phymodInterface1000X) {
   1118         if (config->data_rate == 2500){
   1119             spd_intf = TEFMOD_SPD_2P5G_KX1;
   1120         } else {
   1121             if (config->pll_divider_req == 165) {
   1122                 spd_intf = TEFMOD_SPD_1G_25G;
   1123             } else {
   1124                 spd_intf = TEFMOD_SPD_1G_20G;
   1125             }
   1126         }
   1127     } else if (config->interface_type == phymodInterfaceSGMII) {
   1128         if (config->data_rate == 2500){
   1129             spd_intf = TEFMOD_SPD_2P5G_KX1;
   1130         } else {
   1131             if (config->pll_divider_req == 165) {
   1132                 spd_intf = TEFMOD_SPD_1G_25G;
   1133             } else {
   1134                 spd_intf = TEFMOD_SPD_1G_20G;
   1135             }
   1136         }
   1137     } else if ((config->interface_type == phymodInterfaceBypass) ||
   1138                  (num_lane == 1)) {
   1139         switch (config->data_rate) {
   1140             case 5000:
   1141                 spd_intf = TEFMOD_SPD_5G_KR1;
   1142                 firmware_lane_config.DfeOn = 0;
   1143                 break;
   1144             case 10000:
   1145             case 12000:
   1146                 spd_intf = TEFMOD_SPD_10000_XFI;
   1147                 if (config->interface_type != phymodInterfaceBypass) {
   1148                     if (!PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1149                         firmware_lane_config.DfeOn = 0;
   1150                     }
   1151                 }
   1152                 break;
   1153             case 11000:
   1154                 spd_intf = TEFMOD_SPD_10600_XFI_HG;
   1155                 if (config->interface_type != phymodInterfaceBypass) {
   1156                     if (!PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1157                         firmware_lane_config.DfeOn = 0;
   1158                     }
   1159                 }
   1160                 break;
   1161             case 20000:
   1162                 spd_intf = TEFMOD_SPD_20000_XFI;
   1163                 break;
   1164             case 21000:
   1165             case 21200:
   1166                 spd_intf = TEFMOD_SPD_21200_XFI_HG;
   1167                 break;
   1168             case 25000:
   1169                 spd_intf = TEFMOD_SPD_25000_XFI;
   1170                 break;
   1171             case 27000:
   1172                 spd_intf = TEFMOD_SPD_26500_XFI_HG;
   1173                 firmware_lane_config.DfeOn = 1;
   1174                 firmware_lane_config.LpDfeOn = 0;
   1175                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1176                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1177                 } else {
   1178                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1179                 }
   1180                 break;
   1181             default:
   1182             /* If the interface is pcs bypass mode and check the speed */
   1183             if (config->interface_type == phymodInterfaceBypass) {
   1184                 /* Disable DFE for lower speed */
   1185                 if (config->data_rate < 10000) {
   1186                     firmware_lane_config.DfeOn = 0;
   1187                 }
   1188             } else {
   1189                 spd_intf = TEFMOD_SPD_10000_XFI;
   1190                 firmware_lane_config.DfeOn = 0;
   1191             }
   1192             break;
   1193         }
   1194     } else if ((config->interface_type == phymodInterfaceKR2) ||
   1195                (config->interface_type == phymodInterfaceCR2) ||
   1196                (config->interface_type == phymodInterfaceXLAUI2) ||
   1197                (config->interface_type == phymodInterfaceRXAUI) ||
   1198                (config->interface_type == phymodInterfaceX2) ||
   1199                (num_lane == 2)) {
   1200         switch (config->data_rate) {
   1201             case 20000:
   1202                 spd_intf = TEFMOD_SPD_20G_MLD_X2;
   1203                 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1204                    firmware_lane_config.DfeOn = 0;
   1205                    firmware_lane_config.LpDfeOn = 0;
   1206                 }
   1207                 if (PHYMOD_INTF_MODES_FIBER_GET(config) && !(PHYMOD_INTF_MODES_HIGIG_GET(config))) {
   1208                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1209                 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1210                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1211                 } else {
   1212                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1213                 }
   1214                 break;
   1215             case 21000:
   1216             case 21200:
   1217                 firmware_lane_config.DfeOn = 0;
   1218                 firmware_lane_config.LpDfeOn = 0;
   1219                 spd_intf = TEFMOD_SPD_21G_MLD_HG_X2;
   1220                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1221                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1222                 } else {
   1223                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1224                 }
   1225                 break;
   1226             case 40000:
   1227                 spd_intf = TEFMOD_SPD_40G_MLD_X2;
   1228                 if (config->interface_type == phymodInterfaceXLAUI2) {
   1229                     firmware_lane_config.DfeOn = 0;
   1230                     firmware_lane_config.LpDfeOn = 0;
   1231                 } else {
   1232                     firmware_lane_config.DfeOn = 1;
   1233                     firmware_lane_config.LpDfeOn = 1;
   1234                 }
   1235                 if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1236                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1237                 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1238                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1239                 } else {
   1240                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1241                 }
   1242                 break;
   1243             case 42000:
   1244                 spd_intf = TEFMOD_SPD_42G_MLD_HG_X2;
   1245                 firmware_lane_config.DfeOn = 1;
   1246                 firmware_lane_config.LpDfeOn = 1;
   1247                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1248                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1249                 } else {
   1250                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1251                 }
   1252                 break;
   1253             case 50000:
   1254                 spd_intf = TEFMOD_SPD_50G_MLD_X2;
   1255                 break;
   1256             case 53000:
   1257                 spd_intf = TEFMOD_SPD_53G_MLD_HG_X2;
   1258                 break;
   1259             default:
   1260                 spd_intf = TEFMOD_SPD_20G_MLD_X2;
   1261                 break;
   1262         }
   1263     } else if (num_lane == 4) {
   1264         switch (config->data_rate) {
   1265             case 10000:
   1266                 spd_intf = TEFMOD_SPD_2P5G_KX1;
   1267                 firmware_lane_config.DfeOn = 0;
   1268                 firmware_lane_config.LpDfeOn = 0;
   1269                 firmware_lane_config.ScramblingDisable = 1;
   1270                 break;
   1271             case 40000:
   1272                 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1273                     spd_intf = TEFMOD_SPD_42G_MLD_HG_X4;
   1274                     firmware_lane_config.DfeOn = 1;
   1275                     firmware_lane_config.LpDfeOn = 1;
   1276                 } else if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1277                     spd_intf = TEFMOD_SPD_40G_MLD_X4;
   1278                     firmware_lane_config.DfeOn = 0;
   1279                     firmware_lane_config.LpDfeOn = 0;
   1280                 } else {
   1281                     if (config->interface_type == phymodInterfaceXLAUI) {
   1282                         spd_intf = TEFMOD_SPD_40G_MLD_X4;
   1283                         firmware_lane_config.DfeOn = 0;
   1284                         firmware_lane_config.LpDfeOn = 0;
   1285                     } else {
   1286                         spd_intf = TEFMOD_SPD_40G_MLD_X4;
   1287                         firmware_lane_config.DfeOn = 1;
   1288                         firmware_lane_config.LpDfeOn = 1;
   1289                     }
   1290                 }
   1291                 break;
   1292             case 42000:
   1293                 spd_intf = TEFMOD_SPD_42G_MLD_HG_X4;
   1294                 firmware_lane_config.DfeOn = 1;
   1295                 firmware_lane_config.LpDfeOn = 1;
   1296                 break;
   1297             case 48000:
   1298                 spd_intf = TEFMOD_SPD_40G_MLD_X4;
   1299                 firmware_lane_config.DfeOn = 0;
   1300                 firmware_lane_config.LpDfeOn = 0;
   1301                 break;
   1302             case 50000:
   1303                 spd_intf = TEFMOD_SPD_50G_MLD_X4;
   1304                 break;
   1305             case 53000:
   1306                 spd_intf = TEFMOD_SPD_53G_MLD_HG_X4;
   1307                 break;
   1308             case 100000:
   1309                 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1310                     spd_intf = TEFMOD_SPD_106G_MLD_HG_X4;
   1311                     firmware_lane_config.DfeOn = 1;
   1312                     firmware_lane_config.LpDfeOn = 0;
   1313                     if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1314                         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1315                     } else {
   1316                         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1317                     }
   1318                 } else {
   1319                     spd_intf = TEFMOD_SPD_100G_MLD_X4;
   1320                     if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1321                         firmware_lane_config.DfeOn = 0;
   1322                         firmware_lane_config.LpDfeOn = 0;
   1323                         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1324                     } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1325                         firmware_lane_config.DfeOn = 1;
   1326                         firmware_lane_config.LpDfeOn = 0;
   1327                         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1328                     } else {
   1329                         firmware_lane_config.DfeOn = 1;
   1330                         firmware_lane_config.LpDfeOn = 0;
   1331                         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1332                     }
   1333                     if (config->interface_type == phymodInterfaceCAUI4 || config->interface_type == phymodInterfaceCAUI) {
   1334                         firmware_lane_config.DfeOn = 1;
   1335                         firmware_lane_config.LpDfeOn = 1;
   1336                         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1337                     }
   1338                 }
   1339                 break;
   1340             case 106000:
   1341                 spd_intf = TEFMOD_SPD_106G_MLD_HG_X4;
   1342                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1343                     firmware_lane_config.DfeOn = 1;
   1344                     firmware_lane_config.LpDfeOn = 0;
   1345                     firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1346                 } else {
   1347                     firmware_lane_config.DfeOn = 1;
   1348                     firmware_lane_config.LpDfeOn = 0;
   1349                     firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1350                 }
   1351                 break;
   1352             default:
   1353                 spd_intf = TEFMOD_SPD_40G_MLD_X4;
   1354                 firmware_lane_config.DfeOn = 0;
   1355                 break;
   1356         }
   1357     } else {
   1358         PHYMOD_DEBUG_ERROR(("Incorrect speed config\n" ));
   1359         return PHYMOD_E_CONFIG;
   1360     }
   1361 
   1362     /* Get current PLL0 and PLL1 */
   1363     PHYMOD_IF_ERR_RETURN
   1364         (tefmod_gen3_pll_div_get(&pm_phy_copy.access, &cur_pll0_div, &cur_pll1_div));
   1365 
   1366     /* Get PLL_select */
   1367     PHYMOD_IF_ERR_RETURN
   1368         (falcon2_monterey_pll_select_get(&pm_phy_copy.access, &cur_pll_select));
   1369 
   1370     /* Get required PLL_DIV */ 
   1371     if (config->interface_type == phymodInterfaceBypass){
   1372         PHYMOD_IF_ERR_RETURN
   1373             (falcon2_monterey_get_vco(config, &vco_rate, &new_pll_div, &new_os_mode));
   1374     } else {
   1375         PHYMOD_IF_ERR_RETURN
   1376             (tefmod_gen3_pll_div_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div));
   1377     }
   1378 
   1379     /* If flag SINGLE_PLL_ONLY set
   1380      * One PLL:   PLL1_DIV = 132(20G)/165(25G) 
   1381      * Otherwise,
   1382      * Dual PLL:
   1383      *  - IEEE mode:  PLL0_DIV = 132(20G), PLL1_DIV = 165(25G)
   1384      *  - HIGIG mode: PLL0_DIV = 140(21G)/ 175(27G), PLL1_DIV = 165(25G)
   1385      */
   1386     /* Only PLL1 is used for ETH port of mixed mode */
   1387     if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) {
   1388         if ((new_pll_div == phymod_TSCF_PLL_DIV132) || (new_pll_div == phymod_TSCF_PLL_DIV165)){
   1389             if (new_pll_div != cur_pll1_div) {
   1390                 if (!(flags & PHYMOD_INTF_F_DONT_TURN_OFF_PLL)){
   1391                     new_pll_set = 1;
   1392                 } else {
   1393                      PHYMOD_DEBUG_ERROR(("DONT TURN OFF PLL flag is set\n" ));
   1394                      return PHYMOD_E_CONFIG;
   1395                 }
   1396             }
   1397             pll_index_update = 1;
   1398             pll_index = 1;
   1399         } else {
   1400             PHYMOD_DEBUG_ERROR(("Pll %d One PLL mode doesn't support \n", new_pll_div));
   1401             return PHYMOD_E_CONFIG;
   1402         }
   1403     } else { /* HIGIG MODE */
   1404         if (PHYMOD_INTF_MODES_HIGIG_GET(config)){
   1405             /* For 10G, 20G, 40G(4 lanes) Higig2, pll_div is phymod_TSCF_PLL_DIV132 */
   1406             if ((config->data_rate == 10000) && (num_lane == 1)) {
   1407                 new_pll_set = 0;
   1408                 pll_index_update = 1;
   1409                 pll_index = 0;
   1410             } else if ((config->data_rate == 20000) && (num_lane == 2)) {
   1411                 new_pll_set = 0;
   1412                 pll_index_update = 1;
   1413                 pll_index = 0;
   1414             } else if ((config->data_rate == 40000) && (num_lane == 4)) {
   1415                 new_pll_set = 0;
   1416                 pll_index_update = 1;
   1417                 pll_index = 0;
   1418                 new_pll_div = phymod_TSCF_PLL_DIV132;
   1419             }
   1420             if ((pll_index_update == 1) && (new_pll_div != cur_pll0_div)) {
   1421                 new_pll_set = 1;
   1422             }
   1423             if ((new_pll_div == phymod_TSCF_PLL_DIV140) || (new_pll_div == phymod_TSCF_PLL_DIV175)) {
   1424                 if (new_pll_div != cur_pll0_div){
   1425                     if (!(flags & PHYMOD_INTF_F_DONT_TURN_OFF_PLL)){
   1426                         new_pll_set = 1;
   1427                         pll_index_update = 1;
   1428                         pll_index = 0;
   1429                     } else {
   1430                         PHYMOD_DEBUG_ERROR(("DONT TURN OFF PLL flag is set\n" ));
   1431                         return PHYMOD_E_CONFIG;
   1432                     }
   1433                 }
   1434                 pll_index_update = 1;
   1435                 pll_index = 0;
   1436             }
   1437         } else {  /* IEEE MODE */
   1438             if ((new_pll_div == phymod_TSCF_PLL_DIV132) || (new_pll_div == phymod_TSCF_PLL_DIV165)){
   1439                 if ((new_pll_div == cur_pll0_div) && (cur_pll_select != 0)){
   1440                     pll_index_update = 1;
   1441                     pll_index = 0;
   1442                 }
   1443                 if ((new_pll_div == cur_pll1_div) && (cur_pll_select != 1)){
   1444                      pll_index_update = 1;
   1445                      pll_index = 1;
   1446                 }
   1447                 /* Set PLL select as 1 when speed 1G with VCO 25.78125 */
   1448                 if ((config->data_rate == 1000) && (config->pll_divider_req == 165)) {
   1449                     pll_index_update = 1;
   1450                     pll_index = 1;
   1451                 }
   1452             }
   1453         }
   1454     }
   1455 
   1456 
   1457     /* Set os mode */
   1458     if (new_os_mode >=0){
   1459         os_mode = new_os_mode | 0x80000000;
   1460     } else {
   1461         os_mode = 0;
   1462     }
   1463     PHYMOD_IF_ERR_RETURN
   1464         (tefmod_gen3_pmd_os_mode_set(&phy->access, spd_intf, config->ref_clock, os_mode));   
   1465 
   1466     if (new_pll_set) {
   1467         /* Only PLL1 is used for ETH port of mixed mode */
   1468         if (flags != PHYMOD_INTF_F_SINGLE_PLL_ONLY) {
   1469             pm_phy_copy.access.pll_idx = 0;
   1470             PHYMOD_IF_ERR_RETURN
   1471                 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 0));
   1472         }
   1473 
   1474         /* Update PLL1 for ETH port of mixed mode, otherwise leave PLL1 at 25G */
   1475         if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) {
   1476             pm_phy_copy.access.pll_idx = 1;
   1477             PHYMOD_IF_ERR_RETURN
   1478                 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 0));
   1479         }
   1480         /* PLL0 config */
   1481         if (flags != PHYMOD_INTF_F_SINGLE_PLL_ONLY) {
   1482             pm_phy_copy.access.pll_idx = 0;
   1483             PHYMOD_IF_ERR_RETURN
   1484                 (tefmod_gen3_configure_pll(&pm_phy_copy.access, new_pll_div, config->ref_clock));
   1485             PHYMOD_IF_ERR_RETURN
   1486                 (tefmod_gen3_pll_to_vco_rate(&pm_phy_copy.access, new_pll_div, config->ref_clock, &vco_rate));
   1487             firmware_core_config.VcoRate = MHZ_TO_VCO_RATE(vco_rate);
   1488 
   1489             /* Update firmware core config */
   1490             PHYMOD_IF_ERR_RETURN
   1491                 (tscf_gen3_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config));
   1492             PHYMOD_IF_ERR_RETURN
   1493                 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 1));
   1494         }
   1495 
   1496         if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) {
   1497             pm_phy_copy.access.pll_idx = 1;
   1498             PHYMOD_IF_ERR_RETURN
   1499                 (tefmod_gen3_configure_pll(&pm_phy_copy.access, new_pll_div, config->ref_clock));
   1500             PHYMOD_IF_ERR_RETURN
   1501                 (tefmod_gen3_pll_to_vco_rate(&pm_phy_copy.access, new_pll_div, config->ref_clock, &vco_rate));
   1502             firmware_core_config.VcoRate = MHZ_TO_VCO_RATE(vco_rate);
   1503 
   1504             /* Update firmware core config */
   1505             PHYMOD_IF_ERR_RETURN
   1506                 (tscf_gen3_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config));
   1507             PHYMOD_IF_ERR_RETURN
   1508                 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 1));
   1509         }
   1510 
   1511         PHYMOD_IF_ERR_RETURN
   1512             (tefmod_gen3_master_port_num_set(&phy->access, start_lane));
   1513         PHYMOD_IF_ERR_RETURN
   1514             (tefmod_gen3_pll_reset_enable_set(&phy->access, 1));
   1515     }
   1516 
   1517      /* Select pll index for the port */
   1518     if (pll_index_update) {
   1519         for (lane = 0; lane < num_lane; lane++) {
   1520             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) {
   1521                 continue;
   1522             }
   1523             pm_phy_copy.access.lane_mask = 0x1 << (start_lane + lane);
   1524             PHYMOD_IF_ERR_RETURN
   1525                 (tefmod_gen3_pll_select_set(&pm_phy_copy.access, pll_index));
   1526         }
   1527     }
   1528     if(config->interface_type != phymodInterfaceBypass) {
   1529         PHYMOD_IF_ERR_RETURN
   1530           (tefmod_gen3_set_spd_intf(&phy->access, spd_intf));
   1531     }
   1532 
   1533     /* Update firmware lane config */
   1534     for (lane = 0; lane < num_lane; lane++) {
   1535         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) {
   1536             continue;
   1537         }
   1538         pm_phy_copy.access.lane_mask = 0x1 << (start_lane + lane);
   1539         PHYMOD_IF_ERR_RETURN
   1540              (_tscf_gen3_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   1541     }
   1542 
   1543     /* Release the ln dp reset */
   1544     for (lane = 0; lane < num_lane; lane++) {
   1545         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) {
   1546             continue;
   1547         }
   1548         pm_phy_copy.access.lane_mask = 1 << (start_lane + lane);
   1549         PHYMOD_IF_ERR_RETURN
   1550             (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1551     }
   1552 
   1553     return PHYMOD_E_NONE;
   1554 }
   1555 
   1556 STATIC
   1557 int _tscf_gen3_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id, phymod_phy_inf_config_t* config)
   1558 {
   1559     int ilkn_set = 0;
   1560     uint32_t pll_div, pll0_div, pll1_div; 
   1561     uint8_t pll_select;
   1562     int osr_mode;
   1563     int div_osr_value;
   1564     uint32_t vco_rate;
   1565 
   1566     PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_ilkn_chk(&phy->access, &ilkn_set));
   1567     PHYMOD_IF_ERR_RETURN
   1568         (tefmod_gen3_pll_div_get(&phy->access, &pll0_div, &pll1_div)); 
   1569     PHYMOD_IF_ERR_RETURN
   1570         (falcon2_monterey_pll_select_get(&phy->access, &pll_select));
   1571     pll_div = (pll_select == 1)? pll1_div : pll0_div;
   1572 
   1573     if(ilkn_set) {
   1574         config->interface_type = phymodInterfaceBypass;
   1575         PHYMOD_IF_ERR_RETURN
   1576             (falcon2_monterey_osr_mode_get(&phy->access, &osr_mode));
   1577         PHYMOD_IF_ERR_RETURN
   1578             (tefmod_gen3_pll_to_vco_rate(&phy->access, pll_div, config->ref_clock, &vco_rate));    
   1579 
   1580         div_osr_value = 1 << osr_mode;
   1581         config->data_rate = vco_rate/div_osr_value;
   1582     } else {
   1583         switch (speed_id) {
   1584         case 0x0:
   1585             config->data_rate = 10000;
   1586             config->interface_type = phymodInterfaceCR;
   1587             break;
   1588         case 0x1:
   1589             config->data_rate = 10000;
   1590             config->interface_type = phymodInterfaceKR;
   1591             break;
   1592         case 0x2:
   1593             config->data_rate = 10000;
   1594             config->interface_type = phymodInterfaceKR;
   1595             break;
   1596         case 0x4:
   1597             config->data_rate = 11000;
   1598             config->interface_type = phymodInterfaceCR;
   1599             break;
   1600         case 0x5:
   1601             config->data_rate = 11000;
   1602             config->interface_type = phymodInterfaceKR;
   1603             break;
   1604         case 0x6:
   1605             config->data_rate = 11000;
   1606             config->interface_type = phymodInterfaceKR;
   1607             break;
   1608         case 0x8:
   1609             config->data_rate = 20000;
   1610             config->interface_type = phymodInterfaceCR;
   1611             break;
   1612         case 0x9:
   1613             config->data_rate = 20000;
   1614             config->interface_type = phymodInterfaceKR;
   1615             break;
   1616         case 0xa:
   1617             config->data_rate = 20000;
   1618             config->interface_type = phymodInterfaceKR;
   1619             break;
   1620         case 0xc:
   1621             config->data_rate = 21000;
   1622             config->interface_type = phymodInterfaceCR;
   1623             break;
   1624         case 0xd:
   1625             config->data_rate = 21000;
   1626             config->interface_type = phymodInterfaceKR;
   1627             break;
   1628         case 0xe:
   1629             config->data_rate = 21000;
   1630             config->interface_type = phymodInterfaceKR;
   1631             break;
   1632         case 0x10:
   1633             config->data_rate = 25000;
   1634             config->interface_type = phymodInterfaceCR;
   1635             break;
   1636         case 0x11:
   1637             config->data_rate = 25000;
   1638             config->interface_type = phymodInterfaceKR;
   1639             break;
   1640         case 0x12:
   1641             config->data_rate = 25000;
   1642             config->interface_type = phymodInterfaceKR;
   1643             break;
   1644         case 0x15:
   1645             config->data_rate = 27000;
   1646             config->interface_type = phymodInterfaceKR;
   1647             break;
   1648         case 0x16:
   1649             config->data_rate = 27000;
   1650             config->interface_type = phymodInterfaceKR;
   1651             break;
   1652         case 0x18:
   1653             config->data_rate = 20000;
   1654             config->interface_type = phymodInterfaceCR2;
   1655             break;
   1656         case 0x19:
   1657             config->data_rate = 20000;
   1658             config->interface_type = phymodInterfaceKR2;
   1659             break;
   1660         case 0x1a:
   1661             config->data_rate = 20000;
   1662             config->interface_type = phymodInterfaceKR2;
   1663             break;
   1664         case 0x1c:
   1665             config->data_rate = 21000;
   1666             config->interface_type = phymodInterfaceCR2;
   1667             break;
   1668         case 0x1d:
   1669             config->data_rate = 21000;
   1670             config->interface_type = phymodInterfaceKR2;
   1671             break;
   1672         case 0x1e:
   1673             config->data_rate = 21000;
   1674             config->interface_type = phymodInterfaceKR2;
   1675             break;
   1676         case 0x20:
   1677             config->data_rate = 40000;
   1678             config->interface_type = phymodInterfaceCR2;
   1679             break;
   1680         case 0x21:
   1681             config->data_rate = 40000;
   1682             config->interface_type = phymodInterfaceKR2;
   1683             break;
   1684         case 0x22:
   1685             config->data_rate = 40000;
   1686             config->interface_type = phymodInterfaceKR2;
   1687             break;
   1688         case 0x24:
   1689             config->data_rate = 42000;
   1690             config->interface_type = phymodInterfaceCR2;
   1691             break;
   1692         case 0x25:
   1693             config->data_rate = 42000;
   1694             config->interface_type = phymodInterfaceKR2;
   1695             break;
   1696         case 0x26:
   1697             config->data_rate = 42000;
   1698             config->interface_type = phymodInterfaceKR2;
   1699             break;
   1700         case 0x28:
   1701             config->data_rate = 40000;
   1702             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1703                 (pll_div == phymod_TSCF_PLL_DIV140)) {
   1704                 config->data_rate =42000;
   1705             }
   1706             config->interface_type = phymodInterfaceCR4;
   1707             break;
   1708         case 0x29:
   1709             config->data_rate = 40000;
   1710             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1711                 (pll_div == phymod_TSCF_PLL_DIV140)) {
   1712                 config->data_rate =42000;
   1713             }
   1714             config->interface_type = phymodInterfaceKR4;
   1715             break;
   1716         case 0x2a:
   1717             config->data_rate = 40000;
   1718             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1719                 (pll_div == phymod_TSCF_PLL_DIV140)) {
   1720                 config->data_rate =42000;
   1721             }
   1722             config->interface_type = phymodInterfaceKR4;
   1723             break;
   1724         case 0x2c:
   1725             config->data_rate = 42000;
   1726             config->interface_type = phymodInterfaceCR4;
   1727             break;
   1728         case 0x2d:
   1729             config->data_rate = 42000;
   1730             config->interface_type = phymodInterfaceKR4;
   1731             break;
   1732         case 0x2e:
   1733             config->data_rate = 42000;
   1734             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1735                 (pll_div == phymod_TSCF_PLL_DIV132)) {
   1736                 config->data_rate =40000;
   1737             }
   1738             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1739                 (pll_div == phymod_TSCF_PLL_DIV165)) {
   1740                 config->data_rate =40000;
   1741             }
   1742             config->interface_type = phymodInterfaceKR4;
   1743             break;
   1744         case 0x30:
   1745             config->data_rate = 50000;
   1746             config->interface_type = phymodInterfaceCR2;
   1747             break;
   1748         case 0x31:
   1749             config->data_rate = 50000;
   1750             config->interface_type = phymodInterfaceKR2;
   1751             break;
   1752         case 0x32:
   1753             config->data_rate = 50000;
   1754             config->interface_type = phymodInterfaceKR2;
   1755             break;
   1756         case 0x34:
   1757             config->data_rate = 53000;
   1758             config->interface_type = phymodInterfaceCR2;
   1759             break;
   1760         case 0x35:
   1761             config->data_rate = 53000;
   1762             config->interface_type = phymodInterfaceKR2;
   1763             break;
   1764         case 0x36:
   1765             config->data_rate = 53000;
   1766             config->interface_type = phymodInterfaceKR2;
   1767             break;
   1768         case 0x38:
   1769             config->data_rate = 50000;
   1770             config->interface_type = phymodInterfaceCR4;
   1771             break;
   1772         case 0x39:
   1773             config->data_rate = 50000;
   1774             config->interface_type = phymodInterfaceKR4;
   1775             break;
   1776         case 0x3a:
   1777             config->data_rate = 50000;
   1778             config->interface_type = phymodInterfaceKR4;
   1779             break;
   1780         case 0x3c:
   1781             config->data_rate = 53000;
   1782             config->interface_type = phymodInterfaceCR4;
   1783             break;
   1784         case 0x3d:
   1785             config->data_rate = 53000;
   1786             config->interface_type = phymodInterfaceKR4;
   1787             break;
   1788         case 0x3e:
   1789             config->data_rate = 53000;
   1790             config->interface_type = phymodInterfaceKR4;
   1791             break;
   1792         case 0x40:
   1793             config->data_rate = 100000;
   1794             config->interface_type = phymodInterfaceCR4;
   1795             break;
   1796         case 0x41:
   1797             config->data_rate = 100000;
   1798             config->interface_type = phymodInterfaceKR4;
   1799             break;
   1800         case 0x42:
   1801             config->data_rate = 100000;
   1802             config->interface_type = phymodInterfaceKR4;
   1803             break;
   1804         case 0x44:
   1805             config->data_rate = 106000;
   1806             if (pll_div == phymod_TSCF_PLL_DIV165) {
   1807                 config->data_rate = 100000;
   1808             }
   1809             config->interface_type = phymodInterfaceCR4;
   1810             break;
   1811         case 0x45:
   1812             config->data_rate = 106000;
   1813             if (pll_div == phymod_TSCF_PLL_DIV165) {
   1814                 config->data_rate = 100000;
   1815             }
   1816             config->interface_type = phymodInterfaceKR4;
   1817             break;
   1818         case 0x46:
   1819             config->data_rate = 106000;
   1820             if (pll_div == phymod_TSCF_PLL_DIV165) {
   1821                 config->data_rate = 100000;
   1822             }
   1823             config->interface_type = phymodInterfaceKR4;
   1824             break;
   1825         case 0x48:
   1826             config->data_rate = 20000;
   1827             config->interface_type = phymodInterfaceKR2;
   1828             break;
   1829         case 0x50:
   1830             config->data_rate = 25000;
   1831             config->interface_type = phymodInterfaceKR2;
   1832             break;
   1833         case 0x58:
   1834             config->data_rate = 1000;
   1835             config->interface_type = phymodInterfaceSGMII;
   1836             break;
   1837         case 0x60:
   1838             config->data_rate = 1000;
   1839             config->interface_type = phymodInterfaceSGMII;
   1840             break;
   1841         case 0x62:
   1842             config->data_rate = 2500;
   1843             config->interface_type = phymodInterfaceSGMII;
   1844             break;
   1845         case 0x63:
   1846             config->data_rate = 5000;
   1847             config->interface_type = phymodInterfaceKR;
   1848             break;
   1849         case 0x70:
   1850             config->data_rate = 25000;
   1851             config->interface_type = phymodInterfaceCR;
   1852             break;
   1853         case 0x71:
   1854             config->data_rate = 25000;
   1855             config->interface_type = phymodInterfaceCR;
   1856             break;
   1857         case 0x72:
   1858             config->data_rate = 25000;
   1859             config->interface_type = phymodInterfaceKR;
   1860             break;
   1861         case 0x73:
   1862             config->data_rate = 25000;
   1863             config->interface_type = phymodInterfaceKR;
   1864             break;
   1865         default:
   1866             config->data_rate = 10000;
   1867             config->interface_type = phymodInterfaceKR;
   1868             break;
   1869         }
   1870     }
   1871 
   1872     return PHYMOD_E_NONE;
   1873 }
   1874 
   1875 int tscf_gen3_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config)
   1876 {        
   1877     int speed_id;
   1878     phymod_firmware_lane_config_t firmware_lane_config;
   1879     phymod_phy_access_t pm_phy_copy;
   1880     int start_lane, num_lane;
   1881     phymod_autoneg_control_t an_control;
   1882     int an_done = 0;
   1883     an_control.flags = 0;
   1884 
   1885     config->ref_clock = ref_clock;
   1886     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1887 
   1888     PHYMOD_IF_ERR_RETURN
   1889         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1890     PHYMOD_IF_ERR_RETURN
   1891         (tefmod_gen3_speed_id_get(&phy->access, &speed_id));
   1892     PHYMOD_IF_ERR_RETURN
   1893         (_tscf_gen3_speed_id_interface_config_get(phy, speed_id, config));
   1894     /* Read the current media type */
   1895     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1896     PHYMOD_IF_ERR_RETURN
   1897         (tscf_gen3_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   1898     if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) {
   1899         PHYMOD_INTF_MODES_FIBER_SET(config);
   1900     } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   1901         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1902         PHYMOD_INTF_MODES_COPPER_SET(config);
   1903     } else {
   1904         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1905         PHYMOD_INTF_MODES_BACKPLANE_SET(config);
   1906     }
   1907     /* Next need to check for 40G 4 lanes mode, it's for XLAUI or KR4 */
   1908     if ((config->data_rate == 40000) && (!(firmware_lane_config.DfeOn)) &&
   1909          (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) {
   1910         if (num_lane == 2) {
   1911             config->interface_type = phymodInterfaceXLAUI2;
   1912         } else {
   1913             config->interface_type = phymodInterfaceXLAUI;
   1914         }
   1915     }
   1916     PHYMOD_IF_ERR_RETURN
   1917         (tscf_gen3_phy_autoneg_get(phy, &an_control, (uint32_t *) &an_done));
   1918 
   1919     /* Next need to check if we are CAUI4 100G mode */
   1920     if (!(an_control.enable && an_done)) {
   1921         if ((config->data_rate == 100000) && (firmware_lane_config.LpDfeOn) &&
   1922             (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) {
   1923              config->interface_type = phymodInterfaceCAUI4;
   1924         }
   1925     }
   1926 
   1927     switch (config->interface_type) {
   1928     case phymodInterfaceSGMII:
   1929         if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1930             config->interface_type = phymodInterface1000X;
   1931         } else {
   1932             config->interface_type = phymodInterfaceSGMII;
   1933         }
   1934 
   1935         /*
   1936          * Speed ID 0x58 and 0x60 are interpreted as phymodInterfaceSGMII
   1937          * by _tscf_gen3_speed_id_interface_config_get(). This is correct when
   1938          * the port is in forced speed mode. However, when AN is enabled
   1939          * and completed the interface type cannot be SGMII because TSCF
   1940          * does not support CL37 & CL37bam. The correct interface type in
   1941          * this scenario should be phymodInterfaceKX.
   1942          */
   1943         if (an_control.enable && an_done) {
   1944             config->interface_type = phymodInterfaceKX;
   1945         }
   1946         break;
   1947     case phymodInterfaceXFI:
   1948         if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1949             config->interface_type = phymodInterfaceCR;
   1950         } else {
   1951             config->interface_type = phymodInterfaceXFI;
   1952         }
   1953         break;
   1954     case phymodInterfaceKR2:
   1955         if (!an_control.enable) {
   1956             if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1957                 config->interface_type = phymodInterfaceSR2;
   1958             } else {
   1959                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1960                     config->interface_type = phymodInterfaceCR2;
   1961                 } else {
   1962                     config->interface_type = phymodInterfaceKR2;
   1963                 }
   1964             }
   1965         }
   1966         break;
   1967     case phymodInterfaceKR4:
   1968         if (!an_control.enable) {
   1969             if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1970                 config->interface_type = phymodInterfaceSR4;
   1971                 /*if (pCfg->speed_config.line_interface == TSCF_IF_LR4) {
   1972                     config->interface_type = phymodInterfaceLR4;
   1973                 }*/
   1974             } else {
   1975                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1976                     config->interface_type = phymodInterfaceCR4;
   1977                 } else {
   1978                     config->interface_type = phymodInterfaceKR4;
   1979                 }
   1980             }
   1981         }
   1982         break;
   1983     case phymodInterfaceKR:
   1984     {
   1985         if (!an_control.enable) {
   1986             if(config->data_rate == 10000) {
   1987                 if (/*PHY_EXTERNAL_MODE(unit, port) ||*/ !PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1988                     if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1989                         config->interface_type = phymodInterfaceCR;
   1990                     } else {
   1991                         config->interface_type = phymodInterfaceXFI;
   1992                     }
   1993                 } else {
   1994                     config->interface_type = phymodInterfaceSFI;
   1995                 }
   1996             } else{
   1997                 if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1998                     config->interface_type = phymodInterfaceSR;
   1999                 } else {
   2000                     if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2001                         config->interface_type = phymodInterfaceCR;
   2002                     } else {
   2003                         config->interface_type = phymodInterfaceKR;
   2004                     }
   2005                 }
   2006             }
   2007         } else {
   2008             config->interface_type = phymodInterfaceKR;
   2009         }
   2010          break;
   2011     }
   2012 
   2013     default:
   2014         break;
   2015     }
   2016 
   2017     return PHYMOD_E_NONE;
   2018 }
   2019 
   2020 int tscf_gen3_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
   2021 {        
   2022     struct falcon2_monterey_uc_lane_config_st serdes_firmware_config;
   2023     PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
   2024 
   2025     if(serdes_firmware_config.field.dfe_on == 0) {
   2026       PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72/CL93 with no DFE\n"));
   2027       return PHYMOD_E_CONFIG;
   2028     }
   2029 
   2030     PHYMOD_IF_ERR_RETURN
   2031         (tefmod_gen3_clause72_control(&phy->access, cl72_en));
   2032 
   2033     return PHYMOD_E_NONE;
   2034     
   2035 }
   2036 
   2037 int tscf_gen3_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
   2038 {        
   2039     PHYMOD_IF_ERR_RETURN
   2040         (falcon2_monterey_clause72_control_get(&phy->access, cl72_en));
   2041 
   2042     return PHYMOD_E_NONE;
   2043     
   2044 }
   2045 
   2046 
   2047 int tscf_gen3_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
   2048 {        
   2049     uint32_t local_status; 
   2050     PHYMOD_IF_ERR_RETURN
   2051         (falcon2_monterey_pmd_cl72_receiver_status(&phy->access, &local_status));
   2052     status->locked = local_status;
   2053 
   2054     return PHYMOD_E_NONE;
   2055 }
   2056 
   2057 
   2058 int tscf_gen3_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability)
   2059 {        
   2060     tefmod_gen3_an_adv_ability_t value;
   2061     int start_lane, num_lane;
   2062     phymod_phy_access_t phy_copy;
   2063 
   2064     PHYMOD_IF_ERR_RETURN
   2065         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2066 
   2067     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2068     phy_copy.access.lane_mask = 0x1 << start_lane;
   2069 
   2070     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2071 
   2072     value.an_cl72 = an_ability->an_cl72;
   2073     if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) {
   2074         value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD;
   2075     } else {
   2076         if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)){
   2077             value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD;
   2078         }
   2079        if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec)){
   2080             value.an_fec |= TEFMOD_FEC_CL91_SUPRTD_REQSTD;
   2081        }
   2082     }
   2083 
   2084     /* value.an_fec = an_ability->an_fec; */
   2085     value.an_hg2 = an_ability->an_hg2;
   2086 
   2087     /* next check pause */
   2088     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) {
   2089         value.an_pause = TEFMOD_SYMM_PAUSE;
   2090     }
   2091     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   2092         value.an_pause = TEFMOD_ASYM_PAUSE;
   2093     }
   2094     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   2095         value.an_pause = TEFMOD_ASYM_SYMM_PAUSE;
   2096     }
   2097     /* check cl73 ability */
   2098     if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)){
   2099         value.an_base_speed |= 1 << TEFMOD_CL73_1GBASE_KX;
   2100     }
   2101     if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)){
   2102         value.an_base_speed |= 1 << TEFMOD_CL73_10GBASE_KR1;
   2103     }
   2104     if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)){
   2105         value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_KR4;
   2106     }
   2107     if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)){
   2108         value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_CR4;
   2109     }
   2110     if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) {
   2111         value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_KR4;
   2112     }
   2113     if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) {
   2114         value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_CR4;
   2115     }
   2116     if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap)){
   2117         value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CR1;
   2118     }
   2119     if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap)){
   2120         value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KR1;
   2121     }
   2122     if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap)){
   2123         value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CRS1;
   2124     }
   2125     if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap)){
   2126        value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KRS1;
   2127     }
   2128     if (PHYMOD_AN_CAP_2P5G_X_GET(an_ability->an_cap)){
   2129        value.an_base_speed |= 1 << TEFMOD_CL73_2P5GBASE_KX1;
   2130     }
   2131     if (PHYMOD_AN_CAP_5G_KR1_GET(an_ability->an_cap)){
   2132        value.an_base_speed |= 1 << TEFMOD_CL73_5GBASE_KR1;
   2133     }
   2134 
   2135     /* check cl73 bam ability */
   2136     if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)){
   2137         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_KR2;
   2138     }
   2139     if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)){
   2140         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_CR2;
   2141     }
   2142     if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap)){
   2143         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_KR2;
   2144     }
   2145     if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap)){
   2146         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_CR2;
   2147     }
   2148     if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap)){
   2149         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR2;
   2150     }
   2151     if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap)){
   2152         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR2;
   2153     }
   2154     if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap)){
   2155         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR4;
   2156     }
   2157     if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap)){
   2158         value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR4;
   2159     }
   2160     if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap)){
   2161         value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_KR1;
   2162     }
   2163     if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap)){
   2164         value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_CR1;
   2165     }
   2166     if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap)){
   2167         value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_KR1;
   2168     }
   2169     if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap)){
   2170         value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_CR1;
   2171     }
   2172     PHYMOD_IF_ERR_RETURN
   2173         (tefmod_gen3_autoneg_ability_set(&phy_copy.access, &value));
   2174  
   2175     return PHYMOD_E_NONE;
   2176 }
   2177 
   2178 int tscf_gen3_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
   2179 {        
   2180     tefmod_gen3_an_adv_ability_t value;
   2181     phymod_phy_access_t phy_copy;
   2182     int start_lane, num_lane;
   2183 
   2184     PHYMOD_IF_ERR_RETURN
   2185         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2186     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2187     phy_copy.access.lane_mask = 0x1 << start_lane;
   2188     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2189     
   2190     /* Place your code here */
   2191 
   2192     PHYMOD_IF_ERR_RETURN
   2193         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2194     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2195     phy_copy.access.lane_mask = 0x1 << start_lane;
   2196     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2197     
   2198     PHYMOD_IF_ERR_RETURN
   2199         (tefmod_gen3_autoneg_ability_get(&phy_copy.access, &value));
   2200     an_ability_get_type->an_cl72 = value.an_cl72;
   2201 
   2202     an_ability_get_type->an_fec = 0;
   2203     if (value.an_fec == TEFMOD_FEC_NOT_SUPRTD) {
   2204  
   2205     } else if (value.an_fec == TEFMOD_FEC_SUPRTD_NOT_REQSTD) {
   2206         PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec);
   2207     } else {
   2208         if (value.an_fec & TEFMOD_FEC_CL74_SUPRTD_REQSTD) {
   2209             PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   2210         }
   2211         if (value.an_fec & TEFMOD_FEC_CL91_SUPRTD_REQSTD) {
   2212             PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec);
   2213         }
   2214     }
   2215 
   2216     if (value.an_pause == TEFMOD_ASYM_PAUSE) {
   2217         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2218     } else if (value.an_pause == TEFMOD_SYMM_PAUSE) {
   2219         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2220     } else if (value.an_pause == TEFMOD_ASYM_SYMM_PAUSE) {
   2221         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2222         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2223     }
   2224 
   2225     /* first check cl73 base  ability */
   2226     if (value.an_base_speed &  1 << TEFMOD_CL73_100GBASE_CR4) {
   2227         PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap);
   2228     }
   2229     if (value.an_base_speed & 1 << TEFMOD_CL73_100GBASE_KR4) {
   2230         PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap);
   2231     }
   2232     if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_CR4) {
   2233         PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   2234     }
   2235     if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_KR4) {
   2236         PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   2237     }
   2238     if (value.an_base_speed & 1 << TEFMOD_CL73_10GBASE_KR1) {
   2239         PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   2240     }
   2241     if (value.an_base_speed & 1 << TEFMOD_CL73_1GBASE_KX) {
   2242         PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   2243     }
   2244     if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KR1) {
   2245         PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap);
   2246     }
   2247     if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CR1) {
   2248         PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap);
   2249     }
   2250     if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KRS1) {
   2251         PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap);
   2252     }
   2253     if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CRS1) {
   2254         PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap);
   2255     }
   2256     if (value.an_base_speed & 1 << TEFMOD_CL73_2P5GBASE_KX1) {
   2257         PHYMOD_AN_CAP_2P5G_X_SET(an_ability_get_type->an_cap);
   2258     }
   2259     if (value.an_base_speed & 1 << TEFMOD_CL73_5GBASE_KR1) {
   2260         PHYMOD_AN_CAP_5G_KR1_SET(an_ability_get_type->an_cap);
   2261     }
   2262 
   2263     /* next check cl73 bam ability */
   2264     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_KR2){
   2265         PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2266     }
   2267     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_CR2){
   2268         PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2269     }
   2270     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_KR2){
   2271         PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2272     }
   2273     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_CR2){
   2274         PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2275     }
   2276     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR2){
   2277         PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2278     }
   2279     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR2){
   2280         PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2281     }
   2282     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR4){
   2283         PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap);
   2284     }
   2285     if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR4){
   2286         PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap);
   2287     }
   2288     if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_KR1){
   2289         PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2290     }
   2291     if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_CR1){
   2292         PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2293     }
   2294     if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_KR1){
   2295         PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2296     }
   2297     if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_CR1) {
   2298         PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2299     }    
   2300 
   2301     return PHYMOD_E_NONE;
   2302 }
   2303 
   2304 int tscf_gen3_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
   2305 {        
   2306 
   2307     uint16_t baseP0, baseP1, baseP2, nextP3, nextP4;
   2308     int an_fec;
   2309 
   2310     PHYMOD_IF_ERR_RETURN
   2311        (tefmod_gen3_autoneg_lp_status_get(&phy->access, &baseP0, &baseP1, &baseP2, &nextP3, &nextP4));
   2312 
   2313     if((baseP1 >> 5) & 1) {  /* D0 */
   2314       PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   2315     }
   2316     if((baseP1 >> 7) & 1) {  /* D2 */
   2317       PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   2318     }
   2319     if((baseP1 >> 8) & 1) {  /* D3 */
   2320       PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   2321     }
   2322     if((baseP1 >> 9) & 1) {  /* D4 */
   2323       PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   2324     }
   2325     if((baseP1 >> 12) & 1) {  /* D7 */
   2326       PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap);
   2327     }
   2328     if((baseP1 >> 13) & 1) {  /* D8 */
   2329       PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap);
   2330     }
   2331 
   2332     if((baseP1 >> 14) & 1) {
   2333       PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap);
   2334       PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap);
   2335     }
   2336     if((baseP1 >> 15) & 1) {
   2337       PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap);
   2338       PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap);
   2339     }
   2340 
   2341     an_fec = (baseP2 >> 14) & 3; /* D47:D46 */
   2342 
   2343         an_ability_get_type->an_fec = 0;
   2344     if (an_fec == 0x0) {
   2345 
   2346     } else if (an_fec == 0x1) {
   2347         PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec);
   2348     } else {
   2349         if (an_fec == 0x3) {
   2350             PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   2351         }
   2352     }
   2353 
   2354     an_fec = (baseP2 >> 12) & 3; /* D45:D44 */
   2355     if (an_fec & 0x1) {
   2356         PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec);
   2357     }
   2358     if (an_fec & 0x2) {
   2359         PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   2360     }
   2361 
   2362     if((baseP0 >> 10) & 1) {   /* C0 */
   2363       PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2364     }
   2365     if((baseP0 >> 11) & 1) {    /* C1 */
   2366       PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2367     }
   2368 
   2369     if((nextP3 >> 0) & 1) {
   2370       PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2371     }
   2372     if((nextP3 >> 1) & 1) {
   2373       PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2374     }
   2375     if((nextP3 >> 2) & 1) {
   2376       PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2377     }
   2378     if((nextP3 >> 3) & 1) {
   2379       PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2380     }
   2381     if((nextP3 >> 4) & 1) {
   2382       PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2383     }
   2384     if((nextP3 >> 5) & 1) {
   2385       PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2386     }
   2387     if((nextP3 >> 6) & 1) {
   2388       PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2389     }
   2390     if((nextP3 >> 7) & 1) {
   2391       PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2392     }
   2393     if((nextP3 >> 8) & 1) {
   2394       PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2395     }
   2396     if((nextP3 >> 9) & 1) {
   2397       PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2398     }
   2399     if((nextP4 >> 0) & 1) {
   2400       PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap);
   2401     }
   2402     if((nextP4 >> 1) & 1) {
   2403       PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap);
   2404     }
   2405 
   2406     return PHYMOD_E_NONE;
   2407 }
   2408 
   2409 int tscf_gen3_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
   2410 {        
   2411     int num_lane_adv_encoded;
   2412     int start_lane, num_lane;
   2413     int i, an_enable_bitmap, single_port_mode = 0;
   2414     int do_lane_config_set, do_core_config_set;
   2415     phymod_firmware_lane_config_t firmware_lane_config;
   2416     phymod_firmware_core_config_t firmware_core_config_tmp;
   2417     tefmod_gen3_an_control_t an_control;
   2418     phymod_phy_access_t phy_copy;
   2419     tefmod_gen3_an_adv_ability_t value;
   2420 
   2421     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   2422     PHYMOD_MEMSET(&firmware_core_config_tmp, 0x0, sizeof(firmware_core_config_tmp));
   2423 
   2424     PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control));
   2425     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2426 
   2427     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2428     PHYMOD_IF_ERR_RETURN
   2429         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2430     PHYMOD_IF_ERR_RETURN
   2431         (tefmod_gen3_autoneg_ability_get(&phy->access, &value));
   2432 
   2433     if (value.an_hg2){
   2434         single_port_mode = 1;
   2435     }
   2436 
   2437     switch (an->num_lane_adv) {
   2438         case 1:
   2439             num_lane_adv_encoded = 0;
   2440             break;
   2441         case 2:
   2442             num_lane_adv_encoded = 1;
   2443             break;
   2444         case 4:
   2445             num_lane_adv_encoded = 2;
   2446             break;
   2447         case 10:
   2448             num_lane_adv_encoded = 3;
   2449             break;
   2450         default:
   2451             return PHYMOD_E_PARAM;
   2452     }
   2453 
   2454     /* Check if cl72 is allowed to change */
   2455     if (PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_GET(an)) {
   2456         an_control.cl72_config_allowed = 1;
   2457     } else {
   2458         an_control.cl72_config_allowed = 0;
   2459     }
   2460 
   2461     if(PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) {
   2462         an_control.pd_kx_en = 1;
   2463     } else {
   2464         an_control.pd_kx_en = 0;
   2465     }
   2466     if(PHYMOD_AN_F_SET_CL73_PDET_2P5G_KX_ENABLE_GET(an)) {
   2467         an_control.pd_2P5G_kx_en = 1;
   2468     } else {
   2469         an_control.pd_2P5G_kx_en = 0;
   2470     } 
   2471 
   2472     an_control.num_lane_adv = num_lane_adv_encoded;
   2473     an_control.enable       = an->enable;
   2474     an_control.an_property_type = 0x0;   /* for now disable */
   2475     switch (an->an_mode) {
   2476     case phymod_AN_MODE_CL73:
   2477         an_control.an_type = TEFMOD_AN_MODE_CL73;
   2478         break;
   2479     case phymod_AN_MODE_CL73BAM:
   2480         an_control.an_type = TEFMOD_AN_MODE_CL73BAM;
   2481         break;
   2482     case phymod_AN_MODE_MSA:
   2483         an_control.an_type = TEFMOD_AN_MODE_MSA;
   2484         break;
   2485     case phymod_AN_MODE_CL73_MSA:
   2486         an_control.an_type = TEFMOD_AN_MODE_CL73_MSA;
   2487         break;
   2488     case phymod_AN_MODE_HPAM:
   2489         an_control.an_type = TEFMOD_AN_MODE_HPAM;
   2490         break;
   2491     default:
   2492         an_control.an_type = TEFMOD_AN_MODE_CL73;
   2493         break;
   2494     }
   2495 
   2496     PHYMOD_IF_ERR_RETURN(tefmod_gen3_disable_set(&phy->access));
   2497 
   2498     if (single_port_mode) {
   2499         PHYMOD_IF_ERR_RETURN
   2500             (tefmod_gen3_set_an_single_port_mode(&phy->access, an->enable));
   2501     }
   2502 
   2503     if(an->enable) {
   2504         PHYMOD_IF_ERR_RETURN(tefmod_gen3_set_an_port_mode(&phy->access, num_lane, start_lane));
   2505     }
   2506 
   2507     /* Check if any other lane has An on */
   2508     an_enable_bitmap = 0;
   2509     phy_copy.access.lane_mask = 0x1 << start_lane;
   2510     if (!an->enable) {
   2511         for (i = 0; i < 4; i++ ) {
   2512             phy_copy.access.lane_mask = 0x1 << i;
   2513             if (phy_copy.access.lane_mask & phy->access.lane_mask)  continue;
   2514             PHYMOD_IF_ERR_RETURN
   2515                 (tscf_gen3_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   2516             if (firmware_lane_config.AnEnabled) {
   2517                 an_enable_bitmap |= 1 << i;
   2518             }
   2519         }
   2520 
   2521     }
   2522 
   2523     phy_copy.access.lane_mask = 0x1 << start_lane;
   2524 
   2525     /* make sure the firmware config is set to an eenabled */
   2526     PHYMOD_IF_ERR_RETURN
   2527         (tscf_gen3_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   2528     /* make sure the firmware config is set to an eenabled */
   2529     PHYMOD_IF_ERR_RETURN
   2530         (tscf_gen3_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp));
   2531     do_lane_config_set = 0;
   2532     do_core_config_set = 0;
   2533 
   2534     if (an->enable) {
   2535         if(firmware_lane_config.AnEnabled != 1) {
   2536           firmware_lane_config.AnEnabled = 1;
   2537           do_lane_config_set = 1;
   2538         }
   2539         if(firmware_lane_config.LaneConfigFromPCS != 1) {
   2540           firmware_lane_config.LaneConfigFromPCS = 1;
   2541           do_lane_config_set = 1;
   2542         }
   2543         if(firmware_core_config_tmp.CoreConfigFromPCS != 1) {
   2544           firmware_core_config_tmp.CoreConfigFromPCS = 1;
   2545           do_core_config_set = 1;
   2546         }
   2547         firmware_lane_config.Cl72RestTO = 0;
   2548     } else {
   2549         if(firmware_lane_config.AnEnabled != 0) {
   2550           firmware_lane_config.AnEnabled = 0;
   2551           do_lane_config_set = 1;
   2552         }
   2553         if(firmware_lane_config.LaneConfigFromPCS != 0) {
   2554           firmware_lane_config.LaneConfigFromPCS = 0;
   2555           do_lane_config_set = 1;
   2556         }
   2557         if(firmware_core_config_tmp.CoreConfigFromPCS != 0) {
   2558             if (!an_enable_bitmap) {
   2559                 firmware_core_config_tmp.CoreConfigFromPCS = 0;
   2560                 do_core_config_set = 1;
   2561             }
   2562         }
   2563         firmware_lane_config.Cl72RestTO = 1;
   2564     }
   2565 
   2566     if(do_core_config_set && single_port_mode) {
   2567         PHYMOD_IF_ERR_RETURN
   2568             (falcon2_monterey_core_soft_reset_release(&phy_copy.access, 0));
   2569         PHYMOD_USLEEP(1000);
   2570 
   2571         PHYMOD_IF_ERR_RETURN
   2572             (tscf_gen3_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp));
   2573 
   2574         PHYMOD_IF_ERR_RETURN
   2575             (falcon2_monterey_core_soft_reset_release(&phy_copy.access, 1));
   2576     }
   2577 
   2578     if(do_lane_config_set) {
   2579         for (i = 0; i < num_lane; i++) {
   2580             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2581                 continue;
   2582             }
   2583             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2584             PHYMOD_IF_ERR_RETURN
   2585                 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0));
   2586         }
   2587 
   2588         PHYMOD_USLEEP(1000);
   2589         for (i = 0; i < num_lane; i++) {
   2590             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2591                 continue;
   2592             }
   2593             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2594             PHYMOD_IF_ERR_RETURN
   2595                 (_tscf_gen3_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config));
   2596         }
   2597         for (i = 0; i < num_lane; i++) {
   2598             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2599                 continue;
   2600             }
   2601             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2602             PHYMOD_IF_ERR_RETURN
   2603                 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1));
   2604         }
   2605     }
   2606 
   2607     phy_copy.access.lane_mask = 0x1 << start_lane;
   2608     if(an->enable && single_port_mode) {
   2609         PHYMOD_IF_ERR_RETURN
   2610             (tefmod_gen3_master_port_num_set(&phy_copy.access, start_lane));
   2611     }
   2612     PHYMOD_IF_ERR_RETURN
   2613         (tefmod_gen3_autoneg_control(&phy_copy.access, &an_control));
   2614 
   2615     if (!an->enable) {
   2616         PHYMOD_IF_ERR_RETURN(tefmod_gen3_enable_set(&phy->access));
   2617     }
   2618 
   2619     return PHYMOD_E_NONE;
   2620 }
   2621 
   2622 int tscf_gen3_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
   2623 {        
   2624     tefmod_gen3_an_control_t an_control;
   2625     phymod_phy_access_t phy_copy;
   2626     int start_lane, num_lane;
   2627     int an_complete = 0;
   2628 
   2629     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2630     PHYMOD_IF_ERR_RETURN
   2631         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2632     phy_copy.access.lane_mask = 0x1 << start_lane;
   2633 
   2634     PHYMOD_MEMSET(&an_control, 0x0,  sizeof(tefmod_gen3_an_control_t));
   2635     PHYMOD_IF_ERR_RETURN
   2636         (tefmod_gen3_autoneg_control_get(&phy_copy.access, &an_control, &an_complete));
   2637 
   2638     if (an_control.enable) {
   2639         an->enable = 1;
   2640         *an_done = an_complete;
   2641     } else {
   2642         an->enable = 0;
   2643     }
   2644 
   2645     if(an_control.pd_kx_en) {
   2646         PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an) ;
   2647     }
   2648     if(an_control.pd_2P5G_kx_en) {
   2649         PHYMOD_AN_F_SET_CL73_PDET_2P5G_KX_ENABLE_SET(an) ;
   2650     }
   2651 
   2652     switch (an_control.an_type) {
   2653     case TEFMOD_AN_MODE_CL73:
   2654         an->an_mode = phymod_AN_MODE_CL73;
   2655         break;
   2656     case TEFMOD_AN_MODE_CL73BAM:
   2657         an->an_mode = phymod_AN_MODE_CL73BAM;
   2658         break;
   2659     case TEFMOD_AN_MODE_MSA:
   2660         an->an_mode = phymod_AN_MODE_MSA;
   2661         break;
   2662     case TEFMOD_AN_MODE_CL73_MSA:
   2663         an->an_mode = phymod_AN_MODE_CL73_MSA;
   2664         break;
   2665     case TEFMOD_AN_MODE_HPAM:
   2666         an->an_mode = phymod_AN_MODE_HPAM;
   2667         break;
   2668     default:
   2669         an->an_mode = phymod_AN_MODE_NONE;
   2670         break;
   2671     }
   2672     
   2673     return PHYMOD_E_NONE;
   2674 }
   2675 
   2676 int tscf_gen3_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status)
   2677 {        
   2678 
   2679     int speed_id, an_en, an_done;
   2680     phymod_phy_inf_config_t config;
   2681     phymod_ref_clk_t ref_clock;
   2682     const phymod_access_t *pm_acc = &phy->access;
   2683 
   2684     PHYMOD_IF_ERR_RETURN
   2685        (tefmod_gen3_autoneg_status_get(&phy->access, &an_en, &an_done));
   2686 
   2687     PHYMOD_IF_ERR_RETURN
   2688        (tefmod_gen3_speed_id_get(&phy->access, &speed_id));
   2689 
   2690     PHYMOD_IF_ERR_RETURN
   2691        (tefmod_gen3_refclk_get(pm_acc, &ref_clock));
   2692 
   2693     config.ref_clock = ref_clock;
   2694     PHYMOD_IF_ERR_RETURN
   2695        (_tscf_gen3_speed_id_interface_config_get(phy, speed_id, &config));
   2696 
   2697     status->enabled   = an_en;
   2698     status->locked    = an_done;
   2699     status->data_rate = config.data_rate;
   2700     status->interface = config.interface_type;
   2701 
   2702     return PHYMOD_E_NONE;
   2703 }
   2704 
   2705 /* Core initialization
   2706  * 1. De-assert PMD core and PMD lane reset
   2707  * 2. Set heartbeat for comclk
   2708  * 3. Configure lane mapping
   2709  * 4. Micro code load and verify
   2710  * 4.1. Set uc_active = 1
   2711  * 4.2. De-assert micro reset
   2712  * 4.3. Poll for us_dsc_ready_for_cmd = 1 
   2713  * 5. Configure registers for each PLL core and power up each PLL 
   2714  * 6. Configure Core level micro RAM variables for each PLL core
   2715  * 7. Release core DP soft (core_dp_s_rstb) reset for each PLL core
   2716  */
   2717 STATIC
   2718 int _tscf_gen3_core_init_pass1(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   2719 {
   2720     int rv;
   2721     int lane;
   2722     phymod_phy_access_t phy_access;
   2723     phymod_core_access_t  core_copy;
   2724     uint32_t uc_enable = 0;
   2725 
   2726     TSCF_GEN3_CORE_TO_PHY_ACCESS(&phy_access, core);
   2727     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   2728     core_copy.access.lane_mask = 0x1;
   2729 
   2730     /* De-assert PMD core power and core data path reset */
   2731     PHYMOD_IF_ERR_RETURN
   2732         (tefmod_gen3_pmd_reset_seq(&core_copy.access, core_status->pmd_active));
   2733 
   2734     /* Release lane reset */
   2735     for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++) {
   2736         phy_access.access.lane_mask = 1 << lane;
   2737         PHYMOD_IF_ERR_RETURN
   2738             (tefmod_gen3_pmd_x4_reset(&phy_access.access));
   2739     }
   2740 
   2741     PHYMOD_IF_ERR_RETURN
   2742         (falcon2_monterey_uc_active_get(&phy_access.access, &uc_enable));
   2743     if (uc_enable) return PHYMOD_E_NONE;
   2744 
   2745     /* Set the heart beat, based on clock src. */
   2746     PHYMOD_IF_ERR_RETURN
   2747         (tefmod_gen3_refclk_set(&core_copy.access, init_config->interface.ref_clock));
   2748 
   2749     /* Configure lane mapping */
   2750     /* doing PMD lane swap */
   2751     PHYMOD_IF_ERR_RETURN
   2752         (_tscf_gen3_core_lane_map_part_set(&core_copy, &init_config->lane_map, 0));
   2753 
   2754     /*  Micro code load */
   2755     rv = _tscf_gen3_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader);
   2756     if (rv != PHYMOD_E_NONE) {
   2757         PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask));
   2758         PHYMOD_IF_ERR_RETURN(rv);
   2759     }
   2760 
   2761 #ifndef TSCF_GEN3_PMD_CRC_UCODE_VERIFY
   2762     if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   2763         int rv;
   2764         /* Read-back uCode from Program RAM and verify against ucode_image */
   2765         rv = falcon2_monterey_ucode_load_verify(&core_copy.access, (uint8_t *) &falcon_dpll_ucode, falcon_dpll_ucode_len);
   2766         if (rv != PHYMOD_E_NONE) {
   2767             PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask));
   2768             PHYMOD_IF_ERR_RETURN(rv);
   2769         }
   2770     }
   2771 #endif
   2772     /* pmd lane hard reset */
   2773     PHYMOD_IF_ERR_RETURN
   2774         (falcon2_monterey_pmd_ln_h_rstb_pkill_override(&core_copy.access, 0x1));
   2775 
   2776     /* Set uc_active = 1 */
   2777     PHYMOD_IF_ERR_RETURN
   2778         (falcon2_monterey_uc_active_set(&core_copy.access, 1));
   2779 
   2780     /* De-assert micro reset */
   2781     PHYMOD_IF_ERR_RETURN
   2782         (falcon2_monterey_uc_reset(&core_copy.access, 0));
   2783 
   2784     if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   2785 #ifdef TSCF_GEN3_PMD_CRC_UCODE_VERIFY
   2786         PHYMOD_IF_ERR_RETURN(
   2787             falcon2_monterey_start_ucode_crc_calc(&core_copy.access, falcon_dpll_ucode_len));
   2788 #endif
   2789     }
   2790 
   2791     return PHYMOD_E_NONE;
   2792 }
   2793 
   2794 STATIC
   2795 int _tscf_gen3_core_init_pass2(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   2796 {
   2797     phymod_phy_access_t phy_access, phy_access_copy;
   2798     phymod_core_access_t  core_copy;
   2799     phymod_firmware_core_config_t firmware_core_config_tmp;
   2800     uint32_t vco_rate;
   2801 
   2802     TSCF_GEN3_CORE_TO_PHY_ACCESS(&phy_access, core);
   2803     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   2804     core_copy.access.lane_mask = 0x1;
   2805 
   2806     phy_access_copy = phy_access;
   2807     phy_access_copy.access = core->access;
   2808     phy_access_copy.access.lane_mask = 0x1;
   2809     phy_access_copy.type = core->type;
   2810 
   2811     /* doing PCS lane swap */
   2812     PHYMOD_IF_ERR_RETURN
   2813         (_tscf_gen3_core_lane_map_part_set(&core_copy, &init_config->lane_map, 1));
   2814     if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   2815 #ifndef TSCF_GEN3_PMD_CRC_UCODE_VERIFY
   2816         /* poll the ready bit */
   2817         PHYMOD_IF_ERR_RETURN(
   2818             falcon2_monterey_poll_uc_dsc_ready_for_cmd_equals_1(&core_copy.access, 100));
   2819 #else
   2820         PHYMOD_IF_ERR_RETURN(
   2821             falcon2_monterey_check_ucode_crc(&core_copy.access, falcon_dpll_ucode_crc, 200));
   2822 #endif
   2823     }
   2824 
   2825     /* release pmd lane hard reset */
   2826     PHYMOD_IF_ERR_RETURN
   2827         (falcon2_monterey_pmd_ln_h_rstb_pkill_override(&phy_access_copy.access, 0x0));
   2828 
   2829     PHYMOD_IF_ERR_RETURN
   2830         (tefmod_gen3_autoneg_timer_init(&core_copy.access));
   2831 
   2832     PHYMOD_IF_ERR_RETURN
   2833         (tefmod_gen3_master_port_num_set(&core_copy.access, 0));
   2834 
   2835     phy_access_copy.access.lane_mask = 0x1;
   2836     /* Configure Core level RAM variables */
   2837     firmware_core_config_tmp = init_config->firmware_core_config;
   2838     firmware_core_config_tmp.CoreConfigFromPCS = 0;
   2839     /* set charge pump current */
   2840     if (init_config->afe_pll.afe_pll_change_default){
   2841         firmware_core_config_tmp.disable_write_pll_iqp = 1;
   2842     } else {
   2843         firmware_core_config_tmp.disable_write_pll_iqp = 0;
   2844     }
   2845 
   2846     /* reset core DP */
   2847     /* Only PLL1 is used for Eth port in mixed mode */
   2848     if (init_config->pll0_div_init_value){
   2849         core_copy.access.pll_idx = 0; 
   2850         PHYMOD_IF_ERR_RETURN
   2851             (falcon2_monterey_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll));
   2852         PHYMOD_IF_ERR_RETURN
   2853             (falcon2_monterey_core_soft_reset_release(&core_copy.access, 0));
   2854     }
   2855 
   2856     core_copy.access.pll_idx = 1; 
   2857     PHYMOD_IF_ERR_RETURN
   2858         (falcon2_monterey_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll));
   2859     PHYMOD_IF_ERR_RETURN
   2860         (falcon2_monterey_core_soft_reset_release(&core_copy.access, 0));
   2861 
   2862     /* PLL0 config */
   2863     /* Skip to program PLL0, Only PLL1 is used for Eth port in mixed mode */
   2864     if (init_config->pll0_div_init_value){
   2865         phy_access_copy.access.pll_idx = 0;
   2866         PHYMOD_IF_ERR_RETURN
   2867             (tefmod_gen3_configure_pll(&phy_access_copy.access, init_config->pll0_div_init_value, init_config->interface.ref_clock));
   2868         /* Get Core config variable VcoRate */
   2869         PHYMOD_IF_ERR_RETURN
   2870             (tefmod_gen3_pll_to_vco_rate(&phy_access_copy.access, init_config->pll0_div_init_value, init_config->interface.ref_clock, &vco_rate));
   2871         firmware_core_config_tmp.VcoRate = MHZ_TO_VCO_RATE(vco_rate);
   2872         /* Configure Core level RAM variables */
   2873         PHYMOD_IF_ERR_RETURN
   2874             (tscf_gen3_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp));
   2875     }
   2876 
   2877     /* PLL1 config */
   2878     phy_access_copy.access.pll_idx = 1;
   2879     PHYMOD_IF_ERR_RETURN
   2880         (tefmod_gen3_configure_pll(&phy_access_copy.access, init_config->pll1_div_init_value, init_config->interface.ref_clock));
   2881     /* Get Core config variable VcoRate */
   2882     PHYMOD_IF_ERR_RETURN
   2883         (tefmod_gen3_pll_to_vco_rate(&phy_access_copy.access, init_config->pll1_div_init_value, init_config->interface.ref_clock, &vco_rate));
   2884     firmware_core_config_tmp.VcoRate = MHZ_TO_VCO_RATE(vco_rate);
   2885     /* Configure Core level RAM variables */
   2886     PHYMOD_IF_ERR_RETURN
   2887         (tscf_gen3_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp));
   2888 
   2889     PHYMOD_IF_ERR_RETURN
   2890         (tefmod_gen3_cl74_chng_default (&core_copy.access));
   2891 
   2892     PHYMOD_IF_ERR_RETURN
   2893         (tefmod_gen3_cl91_ecc_clear(&core_copy.access));
   2894 
   2895     /* Release core DP soft reset */
   2896     if (init_config->pll0_div_init_value){
   2897         core_copy.access.pll_idx = 0;
   2898         PHYMOD_IF_ERR_RETURN
   2899             (falcon2_monterey_core_soft_reset_release(&core_copy.access, 1));
   2900     }
   2901 
   2902     core_copy.access.pll_idx = 1;
   2903     PHYMOD_IF_ERR_RETURN
   2904         (falcon2_monterey_core_soft_reset_release(&core_copy.access, 1));
   2905 
   2906    return PHYMOD_E_NONE;
   2907 }
   2908 
   2909 
   2910 int tscf_gen3_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   2911 {
   2912 
   2913     if ((!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   2914          !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   2915           PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   2916         PHYMOD_IF_ERR_RETURN
   2917             (_tscf_gen3_core_init_pass1(core, init_config, core_status));
   2918 
   2919         if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   2920             return PHYMOD_E_NONE;
   2921         }
   2922     }
   2923 
   2924     if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   2925           !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   2926           PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) {
   2927         PHYMOD_IF_ERR_RETURN
   2928             (_tscf_gen3_core_init_pass2(core, init_config, core_status));
   2929     }
   2930 
   2931     return PHYMOD_E_NONE;
   2932 }
   2933 
   2934 
   2935 int tscf_gen3_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* pll_multiplier)
   2936 {        
   2937     return PHYMOD_E_NONE;
   2938 }
   2939 
   2940 int tscf_gen3_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
   2941 {
   2942     const phymod_access_t *pm_acc = &phy->access;
   2943     phymod_phy_access_t pm_phy_copy;
   2944     int start_lane, num_lane, i;
   2945     /*int lane_bkup; */
   2946     phymod_polarity_t tmp_pol;
   2947     phymod_firmware_lane_config_t firmware_lane_config;
   2948 
   2949     PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol));
   2950     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   2951     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   2952 
   2953     PHYMOD_IF_ERR_RETURN
   2954         (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane));
   2955 
   2956     /* De-assert PMD lane reset  */
   2957     PHYMOD_IF_ERR_RETURN
   2958         (tefmod_gen3_pmd_x4_reset(pm_acc));
   2959 #if 0
   2960     lane_bkup = pm_phy_copy.access.lane_mask;
   2961     for (i = 0; i < num_lane; i++) {
   2962         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   2963         PHYMOD_IF_ERR_RETURN
   2964             (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 1));
   2965     }
   2966     pm_phy_copy.access.lane_mask = lane_bkup;
   2967 #endif
   2968     /* Clear all the lane config */
   2969     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   2970 
   2971     /* Program the rx/tx polarity */
   2972     for (i = 0; i < num_lane; i++) {
   2973         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2974         tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1;
   2975         tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1;
   2976         PHYMOD_IF_ERR_RETURN
   2977             (tscf_gen3_phy_polarity_set(&pm_phy_copy, &tmp_pol));
   2978     }
   2979     for (i = 0; i < num_lane; i++) {
   2980         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2981         /* set tx parameters */
   2982         PHYMOD_IF_ERR_RETURN
   2983             (tscf_gen3_phy_tx_set(&pm_phy_copy, &init_config->tx[i]));
   2984     }
   2985 
   2986     for (i = 0; i < num_lane; i++) {
   2987         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2988         PHYMOD_IF_ERR_RETURN
   2989              (_tscf_gen3_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   2990     }
   2991 #if 0
   2992     /* Next check if pcs-bypass mode  */
   2993     if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) {
   2994         PHYMOD_IF_ERR_RETURN
   2995             (falcon2_monterey_pmd_tx_disable_pin_dis_set(&phy->access, 1));
   2996         PHYMOD_IF_ERR_RETURN
   2997           (tefmod_gen3_init_pcs_ilkn(&phy->access));
   2998     }
   2999 #endif
   3000 
   3001     PHYMOD_IF_ERR_RETURN
   3002         (tefmod_gen3_port_mode_select(pm_acc));
   3003 
   3004     PHYMOD_IF_ERR_RETURN
   3005         (tefmod_gen3_rx_lane_control_set(pm_acc, 1));
   3006     PHYMOD_IF_ERR_RETURN
   3007         (tefmod_gen3_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE));
   3008 
   3009     PHYMOD_IF_ERR_RETURN
   3010         (tefmod_gen3_25g_rsfec_am_init(pm_acc));
   3011 
   3012     return PHYMOD_E_NONE;
   3013 }
   3014 
   3015 
   3016 int tscf_gen3_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
   3017 {
   3018     int i;
   3019     int start_lane, num_lane;
   3020     uint32_t cl72_en = 0; 
   3021     phymod_phy_access_t phy_copy;
   3022 
   3023     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3024 
   3025     /* Next figure out the lane num and start_lane based on the input */
   3026     PHYMOD_IF_ERR_RETURN
   3027         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3028 
   3029     switch (loopback) {
   3030     case phymodLoopbackGlobal :
   3031         PHYMOD_IF_ERR_RETURN
   3032             (tscf_gen3_phy_cl72_get(phy, &cl72_en));
   3033         if (cl72_en == 1) {
   3034              PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n",  phy_copy.access.addr, start_lane));
   3035              break;
   3036         }
   3037         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_loopback_control(&phy->access, enable, start_lane, num_lane));
   3038         break;
   3039 
   3040        case phymodLoopbackGlobalPMD :
   3041         PHYMOD_IF_ERR_RETURN
   3042             (tscf_gen3_phy_cl72_get(phy, &cl72_en));
   3043         if (cl72_en == 1) {
   3044              PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pmd gloop not supported with cl72 enabled\n",  phy_copy.access.addr, start_lane));
   3045              break;
   3046         }
   3047             for (i = 0; i < num_lane; i++) {
   3048             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3049             PHYMOD_IF_ERR_RETURN(falcon2_monterey_dig_lpbk(&phy_copy.access, (uint8_t) enable));
   3050             PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_force_signal_detect(&phy_copy.access, (int) enable));
   3051             PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_set(&phy->access, 1));
   3052         }
   3053         break;
   3054     case phymodLoopbackRemotePMD :
   3055         PHYMOD_IF_ERR_RETURN(falcon2_monterey_rmt_lpbk(&phy->access, (uint8_t)enable));
   3056         break;
   3057 
   3058     case phymodLoopbackRemotePCS :
   3059         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   3060                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   3061         break;
   3062     default :
   3063         break;
   3064     }
   3065 
   3066     return PHYMOD_E_NONE;
   3067 }
   3068 
   3069 int tscf_gen3_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   3070 {        
   3071     uint32_t enable_core;
   3072     int start_lane, num_lane;
   3073 
   3074     *enable = 0;
   3075 
   3076     /* next figure out the lane num and start_lane based on the input */
   3077     PHYMOD_IF_ERR_RETURN
   3078         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3079 
   3080     switch (loopback) {
   3081     case phymodLoopbackGlobal :
   3082         PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_loopback_get(&phy->access, &enable_core));
   3083         *enable = (enable_core >> start_lane) & 0x1;
   3084         break;
   3085 
   3086     case phymodLoopbackGlobalPMD :
   3087         PHYMOD_IF_ERR_RETURN(falcon2_monterey_tsc_dig_lpbk_get(&phy->access, enable));
   3088         break;
   3089     case phymodLoopbackRemotePMD :
   3090         PHYMOD_IF_ERR_RETURN(falcon2_monterey_tsc_rmt_lpbk_get(&phy->access, enable));
   3091         break;
   3092 
   3093     case phymodLoopbackRemotePCS :
   3094         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   3095                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   3096         break;
   3097     default :
   3098         break;
   3099     }
   3100  
   3101     return PHYMOD_E_NONE;
   3102 }
   3103 
   3104 
   3105 int tscf_gen3_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
   3106 {        
   3107     PHYMOD_IF_ERR_RETURN(tefmod_gen3_pmd_lock_get(&phy->access, rx_pmd_locked));  
   3108         
   3109     return PHYMOD_E_NONE;
   3110 }
   3111 
   3112 int tscf_gen3_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* value)
   3113 {        
   3114     uint32_t local_rx_signal_det;
   3115     int start_lane, num_lane, i;
   3116     *value = 1;
   3117 
   3118     PHYMOD_IF_ERR_RETURN
   3119         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3120 
   3121     for (i = 0; i < num_lane; i++) {
   3122         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   3123             continue;
   3124         }
   3125         PHYMOD_IF_ERR_RETURN
   3126             (falcon2_monterey_tsc_signal_detect(&phy->access, &local_rx_signal_det));
   3127         *value = *value & local_rx_signal_det;
   3128     }
   3129     
   3130     return PHYMOD_E_NONE;
   3131 }
   3132 
   3133 int tscf_gen3_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
   3134 {        
   3135     PHYMOD_IF_ERR_RETURN(tefmod_gen3_get_pcs_latched_link_status(&phy->access, link_status));
   3136         
   3137     return PHYMOD_E_NONE;
   3138 }
   3139 
   3140 
   3141 int tscf_gen3_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config)
   3142 {        
   3143     return PHYMOD_E_UNAVAIL;
   3144 }
   3145 
   3146 int tscf_gen3_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config)
   3147 {        
   3148     return PHYMOD_E_UNAVAIL;
   3149 }
   3150 
   3151 
   3152 int tscf_gen3_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val)
   3153 {        
   3154     phymod_phy_access_t phy_copy; 
   3155 
   3156     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3157     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val));
   3158 
   3159     return PHYMOD_E_NONE;
   3160 }
   3161 
   3162 
   3163 int tscf_gen3_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
   3164 {        
   3165     phymod_phy_access_t phy_copy;
   3166 
   3167     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3168     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val));
   3169 
   3170     return PHYMOD_E_NONE;
   3171 }
   3172 
   3173 
   3174 int tscf_gen3_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value)
   3175 {        
   3176     
   3177     return PHYMOD_E_NONE;
   3178     
   3179 }
   3180 
   3181 
   3182 int tscf_gen3_phy_rescal_set(const phymod_phy_access_t* phy, uint32_t enable, uint32_t value)
   3183 {        
   3184     PHYMOD_IF_ERR_RETURN(falcon2_monterey_rescal_val_set(&phy->access, enable, value));
   3185         
   3186     return PHYMOD_E_NONE;
   3187 }
   3188 
   3189 int tscf_gen3_phy_rescal_get(const phymod_phy_access_t* phy, uint32_t* value)
   3190 {        
   3191     PHYMOD_IF_ERR_RETURN(falcon2_monterey_rescal_val_get(&phy->access, value)); 
   3192 
   3193     return PHYMOD_E_NONE;
   3194 }
   3195 
   3196 /* Enable 1588 timestamping of packets within the TXP and RXP pipelines */
   3197 int tscf_gen3_timesync_enable_set(const phymod_phy_access_t* phy, uint32_t flags, uint32_t enable)
   3198 {
   3199     phymod_phy_access_t phy_copy;
   3200     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3201 
   3202     PHYMOD_IF_ERR_RETURN
   3203         (tefmod_gen3_1588_ts_enable_set(&phy_copy.access, enable));    
   3204 
   3205     return PHYMOD_E_NONE;
   3206 
   3207 }
   3208 
   3209 int tscf_gen3_timesync_enable_get(const phymod_phy_access_t* phy, uint32_t flags, uint32_t* enable)
   3210 {
   3211     phymod_phy_access_t phy_copy;
   3212     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3213 
   3214     PHYMOD_IF_ERR_RETURN
   3215         (tefmod_gen3_1588_ts_enable_get(&phy_copy.access, enable));
   3216 
   3217     return PHYMOD_E_NONE;
   3218 }
   3219 
   3220 /* Set timesync offset */
   3221 int tscf_gen3_timesync_offset_set(const phymod_core_access_t* core, uint32_t ts_offset)
   3222 {
   3223     phymod_core_access_t core_copy;
   3224     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   3225 
   3226     PHYMOD_IF_ERR_RETURN
   3227         (tefmod_gen3_1588_ts_offset_set(&core_copy.access, ts_offset));
   3228 
   3229 
   3230     return PHYMOD_E_NONE;
   3231 }
   3232 
   3233 
   3234 int tscf_gen3_timesync_adjust_set(const phymod_phy_access_t* phy, uint32_t ts_am_norm_mode)
   3235 {
   3236     phymod_phy_access_t phy_copy;
   3237     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 
   3238 
   3239     /* Set sfd_ts_en, crc_calc_mode, cl36_sop_adjust*/
   3240     PHYMOD_IF_ERR_RETURN
   3241         (tefmod_gen3_1588_pcs_control_set(&phy_copy.access));
   3242 
   3243     /* Set 1588 FCLK period */
   3244     PHYMOD_IF_ERR_RETURN
   3245         (tefmod_gen3_1588_fclk_set(&phy_copy.access));
   3246 
   3247     /* Set ui values */
   3248     PHYMOD_IF_ERR_RETURN
   3249         (tefmod_gen3_1588_ui_values_set(&phy_copy.access));
   3250 
   3251     /*Set RX/TX pmd fixed latency */
   3252     PHYMOD_IF_ERR_RETURN
   3253         (tefmod_gen3_1588_txrx_fixed_latency_set(&phy_copy.access));
   3254 
   3255     /* Program deskew adjustment for multi-lane ports */
   3256     if (ts_am_norm_mode != phymodTimesyncCompensationModeNone) {
   3257         PHYMOD_IF_ERR_RETURN
   3258             (tefmod_gen3_1588_rx_deskew_set(&phy_copy.access, ts_am_norm_mode));
   3259     }
   3260 
   3261     return PHYMOD_E_NONE;
   3262 }
   3263 
   3264 int tscf_gen3_timesync_tx_info_get(const phymod_phy_access_t* phy, phymod_ts_fifo_status_t* ts_tx_info)
   3265 {
   3266     phymod_phy_access_t phy_copy;
   3267     tefmod_gen3_ts_tx_info_t local_ts_tx_info;
   3268 
   3269     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3270     PHYMOD_MEMSET(&local_ts_tx_info, 0, sizeof(tefmod_gen3_ts_tx_info_t));
   3271 
   3272     PHYMOD_IF_ERR_RETURN(tefmod_gen3_1588_tx_info_get(&phy_copy.access, &local_ts_tx_info));
   3273 
   3274     ts_tx_info->ts_in_fifo_lo = ((uint32_t)(local_ts_tx_info.ts_val_hi << 16)) | ((uint32_t)local_ts_tx_info.ts_val_lo);
   3275     ts_tx_info->ts_in_fifo_hi = 0;
   3276     ts_tx_info->ts_seq_id = (uint32_t)local_ts_tx_info.ts_seq_id;
   3277     ts_tx_info->ts_sub_nanosec = (uint32_t)local_ts_tx_info.ts_sub_nanosec;
   3278 
   3279     return PHYMOD_E_NONE;
   3280 }
   3281 
   3282 int tscf_gen3_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm)
   3283 {
   3284     int start_lane, num_lane;
   3285     phymod_phy_access_t pm_phy_copy;
   3286 
   3287     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   3288 
   3289     PHYMOD_IF_ERR_RETURN
   3290         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3291 
   3292     pm_phy_copy.access.lane_mask = 1 << start_lane;
   3293     PHYMOD_IF_ERR_RETURN
   3294         (falcon2_monterey_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm));
   3295 
   3296     return PHYMOD_E_NONE;
   3297 }
   3298 
   3299 int tscf_gen3_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy,
   3300                                   phymod_synce_clk_ctrl_t cfg)
   3301 {
   3302     phymod_phy_access_t phy_copy;
   3303     int start_lane, num_lane;
   3304 
   3305     PHYMOD_IF_ERR_RETURN
   3306         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3307 
   3308     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3309     phy_copy.access.lane_mask = 0x1 << start_lane;
   3310 
   3311     PHYMOD_IF_ERR_RETURN
   3312         (tefmod_gen3_synce_stg0_mode_set(&phy_copy.access, cfg.stg0_mode));
   3313 
   3314     PHYMOD_IF_ERR_RETURN
   3315         (tefmod_gen3_synce_stg1_mode_set(&phy_copy.access, cfg.stg1_mode));
   3316 
   3317     PHYMOD_IF_ERR_RETURN
   3318         (tefmod_gen3_synce_clk_ctrl_set(&phy_copy.access, cfg.sdm_val));
   3319 
   3320     return PHYMOD_E_NONE;
   3321 }
   3322 
   3323 int tscf_gen3_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy,
   3324                                   phymod_synce_clk_ctrl_t *cfg)
   3325 {
   3326     PHYMOD_IF_ERR_RETURN
   3327         (tefmod_gen3_synce_stg0_mode_get(&phy->access, &(cfg->stg0_mode)));
   3328 
   3329     PHYMOD_IF_ERR_RETURN
   3330         (tefmod_gen3_synce_stg1_mode_get(&phy->access, &(cfg->stg1_mode)));
   3331 
   3332     PHYMOD_IF_ERR_RETURN
   3333         (tefmod_gen3_synce_clk_ctrl_get(&phy->access, &(cfg->sdm_val)));
   3334 
   3335     return PHYMOD_E_NONE;
   3336 }
   3337