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

tscf16.c (154101B)


      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 #ifndef _DV_TB_
     11  #define _SDK_TEFMOD16_ 1
     12 #endif
     13 
     14 #include <phymod/phymod.h>
     15 #include <phymod/phymod_system.h>
     16 #include <phymod/phymod_util.h>
     17 #include <phymod/chip/bcmi_tscf_16nm_xgxs_defs.h>
     18 #include <phymod/chip/falcon16.h>
     19 #include <phymod/chip/tscf16.h>
     20 #include "../../tscf16/tier1/tefmod16.h"
     21 #include "../../tscf16/tier1/tefmod16_enum_defines.h"
     22 #include "../../tscf16/tier1/tefmod16_device.h"
     23 #include "../../tscf16/tier1/tefmod16_sc_lkup_table.h"
     24 #include "../../tscf16/tier1/tf16PCSRegEnums.h"
     25 #include "../../falcon16/tier1/src/falcon16_cfg_seq.h"
     26 #include "../../falcon16/tier1/include/falcon16_tsc_common.h"
     27 #include "../../falcon16/tier1/include/falcon16_tsc_interface.h"
     28 #include "../../falcon16/tier1/include/falcon16_tsc_internal.h"
     29 #include "../../falcon16/tier1/include/falcon16_tsc_dependencies.h"
     30 #include "../../falcon16/tier1/include/falcon16_tsc_types.h"
     31 #include "../../falcon16/tier1/include/falcon16_tsc_config.h"
     32 #include "../../falcon16/tier1/include/common/srds_api_enum.h"
     33 #include "../../falcon16/tier1/include/falcon16_tsc_debug_functions.h"
     34 
     35 #define TSCF16_ID0                 0x600d
     36 #define TSCF16_ID1                 0x8770
     37 #define TSC4F_GEN2_MODEL           0x15
     38 #define TSCF16_TECH_PROC           0x4
     39 #define FALCON16_MODEL             0x1b
     40 #define TSCF16_NOF_LANES_IN_CORE   4
     41 #define TSCF16_LANE_SWAP_LANE_MASK 3
     42 #define TSCF16_NOF_DFES            6
     43 #define TSCF16_PHY_ALL_LANES       0xf
     44 
     45 #define TSCF16_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \
     46     do{\
     47         PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\
     48         (_phy_access)->type           = (_core_access)->type; \
     49         (_phy_access)->port_loc       = (_core_access)->port_loc; \
     50         (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \
     51         (_phy_access)->access.lane_mask = TSCF16_PHY_ALL_LANES; \
     52     }while(0)
     53 
     54 
     55 #define TSCF16_MAX_FIRMWARES (5)
     56 
     57 #define TSCF16_PMD_CRC_UCODE_VERIFY 1
     58 
     59 #define DEFAULT_OSR2P5_SET 1
     60 
     61 /* uController's firmware */
     62 extern unsigned char falcon16_ucode[];
     63 extern unsigned short falcon16_ucode_ver;
     64 extern unsigned short falcon16_ucode_crc;
     65 extern unsigned short falcon16_ucode_len;
     66 
     67 STATIC
     68 int _tscf16_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier)
     69 {
     70     switch (pll_div) {
     71     case FALCON16_TSC_PLL_DIV_80:
     72         *pll_multiplier = 80;
     73         break;
     74     case FALCON16_TSC_PLL_DIV_96:
     75         *pll_multiplier = 96;
     76         break;
     77     case FALCON16_TSC_PLL_DIV_100:
     78         *pll_multiplier = 100;
     79         break;
     80     case FALCON16_TSC_PLL_DIV_128:
     81         *pll_multiplier = 128;
     82         break;
     83     case FALCON16_TSC_PLL_DIV_132:
     84         *pll_multiplier = 132;
     85         break;
     86     case FALCON16_TSC_PLL_DIV_140:
     87         *pll_multiplier = 140;
     88         break;
     89     case FALCON16_TSC_PLL_DIV_160:
     90         *pll_multiplier = 160;
     91         break;
     92     case FALCON16_TSC_PLL_DIV_165:
     93         *pll_multiplier = 165;
     94         break;
     95     case FALCON16_TSC_PLL_DIV_168:
     96         *pll_multiplier = 168;
     97         break;
     98     case FALCON16_TSC_PLL_DIV_170:
     99         *pll_multiplier = 170;
    100         break;
    101     case FALCON16_TSC_PLL_DIV_175:
    102         *pll_multiplier = 175;
    103         break;
    104     case FALCON16_TSC_PLL_DIV_180:
    105         *pll_multiplier = 180;
    106         break;
    107     case FALCON16_TSC_PLL_DIV_184:
    108         *pll_multiplier = 184;
    109         break;
    110     case FALCON16_TSC_PLL_DIV_200:
    111         *pll_multiplier = 200;
    112         break;
    113     case FALCON16_TSC_PLL_DIV_224:
    114         *pll_multiplier = 224;
    115         break;
    116     case FALCON16_TSC_PLL_DIV_264:
    117         *pll_multiplier = 264;
    118         break;
    119     case FALCON16_TSC_PLL_DIV_120:
    120         *pll_multiplier = 120;
    121         break;
    122     case FALCON16_TSC_PLL_DIV_144:
    123         *pll_multiplier = 144;
    124         break;
    125     case FALCON16_TSC_PLL_DIV_198:
    126         *pll_multiplier = 198;
    127         break;
    128     default:
    129         *pll_multiplier = 165;
    130         break;
    131     }
    132 
    133     return PHYMOD_E_NONE;
    134 }
    135 
    136 STATIC
    137 int _tscf16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
    138 {
    139     struct falcon16_tsc_uc_lane_config_st serdes_firmware_config;
    140     phymod_phy_access_t phy_copy;
    141     int start_lane, num_lane, i;
    142     uint32_t rst_status;
    143     uint32_t is_warm_boot;
    144 
    145     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    146     PHYMOD_IF_ERR_RETURN
    147         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    148     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    149 
    150     for (i = 0; i < num_lane; i++) {
    151         phy_copy.access.lane_mask = 1 << (start_lane + i);
    152         serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS;
    153         serdes_firmware_config.field.an_enabled        = fw_config.AnEnabled;
    154         serdes_firmware_config.field.dfe_on            = fw_config.DfeOn;
    155         serdes_firmware_config.field.force_brdfe_on    = fw_config.ForceBrDfe;
    156         serdes_firmware_config.field.scrambling_dis    = fw_config.ScramblingDisable;
    157         serdes_firmware_config.field.unreliable_los    = fw_config.UnreliableLos;
    158         serdes_firmware_config.field.media_type        = fw_config.MediaType;
    159         serdes_firmware_config.field.dfe_lp_mode       = fw_config.LpDfeOn;
    160         serdes_firmware_config.field.cl72_auto_polarity_en   = fw_config.Cl72AutoPolEn;
    161         serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO;
    162 
    163         PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot));
    164 
    165         if (!is_warm_boot) {
    166             PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_read(&phy_copy.access, &rst_status));
    167             if (rst_status) PHYMOD_IF_ERR_RETURN (falcon16_lane_soft_reset_release(&phy_copy.access, 0));
    168             PHYMOD_IF_ERR_RETURN(falcon16_tsc_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config));
    169             if (rst_status) PHYMOD_IF_ERR_RETURN (falcon16_lane_soft_reset_release(&phy_copy.access, 1));
    170         }
    171     }
    172     return PHYMOD_E_NONE;
    173 }
    174 
    175 /*
    176  * Identify PHYID2 and PHYID3 Read From register 0x2 and 0x3 
    177  * param core core access information
    178  * param core_id predetermined core id 
    179  * param is_identified  if identification IDS match 
    180  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    181  */
    182 int tscf16_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
    183 {
    184     int ioerr = 0;
    185     const phymod_access_t *pm_acc = &core->access;
    186     PHYID2r_t id2;
    187     PHYID3r_t id3;
    188     MAIN0_SERDESIDr_t serdesid;
    189     /* DIG_REVID0r_t revid; */
    190     uint32_t model;
    191 
    192     *is_identified = 0;
    193 
    194     if (core_id == 0){
    195         ioerr += READ_PHYID2r(pm_acc, &id2);
    196         ioerr += READ_PHYID3r(pm_acc, &id3);
    197     }
    198     else{
    199         PHYID2r_SET(id2, ((core_id >> 16) & 0xffff));
    200         PHYID3r_SET(id3, core_id & 0xffff);
    201     }
    202 
    203     if (PHYID2r_REGID1f_GET(id2) == TSCF16_ID0 &&
    204        (PHYID3r_REGID2f_GET(id3) == TSCF16_ID1)) {
    205         /* PHY IDs match - now check PCS model */
    206         ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdesid);
    207         model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid);
    208         if (model == TSC4F_GEN2_MODEL)  {
    209             if (MAIN0_SERDESIDr_TECH_PROCf_GET(serdesid) == TSCF16_TECH_PROC) {
    210                 *is_identified = 1;
    211             }
    212         }
    213     }
    214 
    215     return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE;
    216 }
    217 
    218 /*
    219  * Retrive core information 
    220  * param core core access information
    221  * param info core information (core_version,serdes_id,PHYID2,PHYID3) 
    222  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    223  */
    224 int tscf16_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info)
    225 {
    226     uint32_t serdes_id;
    227     char core_name[15] = "Tscf16";
    228     PHYID2r_t id2;
    229     PHYID3r_t id3;
    230     const phymod_access_t *pm_acc = &core->access;
    231 
    232     PHYMOD_IF_ERR_RETURN
    233         (tefmod16_revid_read(&core->access, &serdes_id));
    234     PHYMOD_IF_ERR_RETURN
    235         (phymod_core_name_get(core, serdes_id, core_name, info));
    236     info->serdes_id = serdes_id;
    237             info->core_version = phymodCoreVersionTscf16;
    238 
    239     PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2));
    240     PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3));
    241 
    242     info->phy_id0 = (uint16_t) id2.v[0];
    243     info->phy_id1 = (uint16_t) id3.v[0];
    244         
    245     return PHYMOD_E_NONE;
    246 }
    247 
    248 /*
    249  * set lane swapping for core
    250  * The pcs tx/rx swap - logical to physical mapping
    251  * The pmd tx/rx addr - logical address associated with the PMD lane with physcal index at the PCS interface
    252  *
    253  * lane_map_tx and lane_map_rx[lane=logic_lane] are logic-lane base.
    254  */
    255 
    256 int tscf16_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    257 {
    258     uint32_t lane, pcs_tx_swap = 0, pcs_rx_swap = 0;
    259     uint8_t pmd_tx_addr[4], pmd_rx_addr[4];
    260     uint32_t uc_enable = 0;
    261     phymod_phy_access_t phy_access;
    262 
    263     if (lane_map->num_of_lanes != TSCF16_NOF_LANES_IN_CORE){
    264         return PHYMOD_E_CONFIG;
    265     }
    266 
    267     TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core);
    268     PHYMOD_IF_ERR_RETURN
    269         (falcon16_uc_active_get(&phy_access.access, &uc_enable));
    270 
    271     for (lane = 0; lane < TSCF16_NOF_LANES_IN_CORE; lane++){
    272         if ((lane_map->lane_map_tx[lane] >= TSCF16_NOF_LANES_IN_CORE)||
    273              (lane_map->lane_map_rx[lane] >= TSCF16_NOF_LANES_IN_CORE)){
    274             return PHYMOD_E_CONFIG;
    275         }
    276         /*encode each lane as four bits*/
    277         pcs_tx_swap += lane_map->lane_map_tx[lane]<<(lane*4);
    278         pcs_rx_swap += lane_map->lane_map_rx[lane]<<(lane*4);
    279     }
    280     /* PMD lane addr is based on PCS logical to physical mapping*/
    281     for (lane = 0; lane < TSCF16_NOF_LANES_IN_CORE; lane++){
    282         pmd_tx_addr[((pcs_tx_swap >> (lane*4)) & 0xf)] = lane;
    283         pmd_rx_addr[((pcs_rx_swap >> (lane*4)) & 0xf)] = lane;
    284     }
    285 
    286     PHYMOD_IF_ERR_RETURN
    287         (tefmod16_pcs_tx_lane_swap(&core->access, pcs_tx_swap));
    288     PHYMOD_IF_ERR_RETURN
    289         (tefmod16_pcs_rx_lane_swap(&core->access, pcs_rx_swap));
    290 
    291     /* If re-program lane swap while micro is running, it needs to put micro in reset state first */
    292     if (uc_enable){
    293         PHYMOD_IF_ERR_RETURN
    294             (falcon16_tsc_core_dp_reset(&phy_access.access, 1));
    295         PHYMOD_IF_ERR_RETURN
    296             (falcon16_tsc_uc_reset(&phy_access.access,1));
    297     }
    298     PHYMOD_IF_ERR_RETURN
    299         (falcon16_tsc_map_lanes(&core->access, TSCF16_NOF_LANES_IN_CORE, pmd_tx_addr, pmd_rx_addr));
    300     if (uc_enable){
    301         PHYMOD_IF_ERR_RETURN
    302             (falcon16_tsc_uc_reset(&phy_access.access,0));
    303         PHYMOD_IF_ERR_RETURN
    304             (falcon16_tsc_core_dp_reset(&phy_access.access,0));
    305     }
    306 
    307     return PHYMOD_E_NONE;
    308 }
    309 
    310 /*
    311  * Get lane map information 
    312  * param core core access information
    313  * param lane_map (num_of_lanes, lane_map_rx, lane_map_tx) 
    314  * Returns PHYMOD_E_NONE if successful else  PHYMOD_E_ERROR 
    315  */
    316 int tscf16_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
    317 {
    318     uint32_t pcs_tx_swap = 0 , pcs_rx_swap = 0, lane;
    319 
    320     PHYMOD_IF_ERR_RETURN(tefmod16_pcs_tx_lane_swap_get(&core->access, &pcs_tx_swap)); 
    321     PHYMOD_IF_ERR_RETURN(tefmod16_pcs_rx_lane_swap_get(&core->access, &pcs_rx_swap));
    322 
    323     for (lane = 0; lane < TSCF16_NOF_LANES_IN_CORE ; lane++){
    324         /*decode each lane from four bits*/
    325         lane_map->lane_map_tx[lane] = (pcs_tx_swap>>(lane*4)) & TSCF16_LANE_SWAP_LANE_MASK;
    326         lane_map->lane_map_rx[lane] = (pcs_rx_swap>>(lane*4)) & TSCF16_LANE_SWAP_LANE_MASK;
    327     }
    328     lane_map->num_of_lanes = TSCF16_NOF_LANES_IN_CORE;
    329         
    330     return PHYMOD_E_NONE;
    331 }
    332 
    333 
    334 int tscf16_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
    335 {
    336         
    337     return PHYMOD_E_UNAVAIL;
    338     
    339 }
    340 
    341 int tscf16_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
    342 {
    343         
    344     return PHYMOD_E_UNAVAIL;
    345     
    346 }
    347 
    348 
    349 int tscf16_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info)
    350 {
    351         
    352     return PHYMOD_E_NONE;
    353     
    354 }
    355 
    356 
    357 /* 
    358  * Tscf16 firmware load
    359  * param core core access information
    360  * param load_method firmware load method: external fw load is valid
    361  * fw_loader  firmware loader
    362  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    363  */
    364 
    365 STATIC
    366 int _tscf16_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader)
    367 {
    368     switch(load_method){
    369     case phymodFirmwareLoadMethodInternal:
    370         PHYMOD_IF_ERR_RETURN(falcon16_tsc_ucode_mdio_load(&core->access, falcon16_ucode, falcon16_ucode_len));
    371         break;
    372     case phymodFirmwareLoadMethodExternal:
    373         PHYMOD_NULL_CHECK(fw_loader);
    374         PHYMOD_IF_ERR_RETURN(falcon16_tsc_ucode_init(&core->access));
    375         PHYMOD_IF_ERR_RETURN
    376             (falcon16_pram_firmware_enable(&core->access, 1, 0));
    377         PHYMOD_IF_ERR_RETURN(fw_loader(core, falcon16_ucode_len, falcon16_ucode));
    378         PHYMOD_IF_ERR_RETURN
    379             (falcon16_pram_firmware_enable(&core->access, 0, 0));
    380         break;
    381     case phymodFirmwareLoadMethodNone:
    382         break;
    383     default:
    384         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method));
    385     }
    386     if (load_method != phymodFirmwareLoadMethodNone){
    387         /* PHYMOD_IF_ERR_RETURN(tscf_core_firmware_info_get(core, &actual_fw));
    388         if ((falcon16_ucode_crc != actual_fw.fw_crc) || (falcon16_ucode_ver != actual_fw.fw_version)){
    389             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("fw load validation was failed")));
    390         } */
    391     }
    392 
    393     return PHYMOD_E_NONE;
    394 
    395 }
    396 
    397 /* 
    398  * Set firmware configure 
    399  * param phy phy access information
    400  * param fw_core_config  firmare core config  
    401  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    402  */
    403 int tscf16_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config)
    404 {
    405     struct falcon16_tsc_uc_core_config_st serdes_firmware_core_config;
    406     uint32_t rst_status;
    407 
    408     PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config));
    409     serdes_firmware_core_config.field.core_cfg_from_pcs = fw_core_config.CoreConfigFromPCS;
    410     serdes_firmware_core_config.field.vco_rate = fw_core_config.VcoRate;
    411     serdes_firmware_core_config.field.osr_2p5_available = fw_core_config.osr_2p5_available;
    412 
    413     PHYMOD_IF_ERR_RETURN(falcon16_core_soft_reset_read(&phy->access, &rst_status));
    414     if (rst_status) PHYMOD_IF_ERR_RETURN (falcon16_tsc_core_dp_reset(&phy->access, 1));
    415     PHYMOD_IF_ERR_RETURN(falcon16_tsc_INTERNAL_set_uc_core_config(&phy->access, serdes_firmware_core_config));
    416     if (rst_status) PHYMOD_IF_ERR_RETURN (falcon16_tsc_core_dp_reset(&phy->access, 0));
    417 
    418     return PHYMOD_E_NONE;
    419 }
    420 
    421 /* 
    422  * Get firmware configure 
    423  * param phy phy access information
    424  * param fw_core_config  firmare core config  
    425  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    426  */
    427 int tscf16_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config)
    428 {
    429     struct falcon16_tsc_uc_core_config_st serdes_firmware_core_config;
    430 
    431     PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config));
    432     PHYMOD_MEMSET(fw_core_config, 0, sizeof(*fw_core_config));
    433     fw_core_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs;
    434     fw_core_config->VcoRate = serdes_firmware_core_config.field.vco_rate;
    435     fw_core_config->osr_2p5_available = serdes_firmware_core_config.field.osr_2p5_available;
    436 
    437     return PHYMOD_E_NONE;
    438 }
    439 
    440 /* 
    441  * Set firmware lane configure 
    442  * param phy phy access information
    443  * param fw_lane_config  firmare lane config  
    444  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    445  */
    446 
    447 int tscf16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config)
    448 {
    449     phymod_phy_access_t phy_copy;
    450     int start_lane, num_lane, i;
    451 
    452     PHYMOD_IF_ERR_RETURN
    453         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    454     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    455 
    456     /*Hold the per lne soft reset bit*/
    457     for (i = 0; i < num_lane; i++) {
    458         phy_copy.access.lane_mask = 1 << (start_lane + i);
    459         PHYMOD_IF_ERR_RETURN
    460             (falcon16_lane_soft_reset_release(&phy_copy.access, 0));
    461     }
    462 
    463     PHYMOD_IF_ERR_RETURN
    464          (_tscf16_phy_firmware_lane_config_set(phy, fw_lane_config));
    465     /*Hold the per lane soft reset bit*/
    466     for (i = 0; i < num_lane; i++) {
    467         phy_copy.access.lane_mask = 1 << (start_lane + i);
    468         PHYMOD_IF_ERR_RETURN
    469             (falcon16_lane_soft_reset_release(&phy_copy.access, 1));
    470     }
    471 
    472     /* next we need to toggle the pcs data path reset */
    473     PHYMOD_IF_ERR_RETURN
    474         (tefmod16_trigger_speed_change(&phy->access));
    475  
    476     return PHYMOD_E_NONE;
    477 }
    478 
    479 /* 
    480  * Get firmware lane configure 
    481  * param phy phy access information
    482  * param fw_lane_config  firmare lane config  
    483  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    484  */
    485 int tscf16_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config)
    486 {
    487     struct falcon16_tsc_uc_lane_config_st serdes_firmware_config;
    488 
    489     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    490     PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
    491     PHYMOD_MEMSET(fw_lane_config, 0, sizeof(*fw_lane_config));
    492     fw_lane_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs;
    493     fw_lane_config->AnEnabled         = serdes_firmware_config.field.an_enabled;
    494     fw_lane_config->DfeOn             = serdes_firmware_config.field.dfe_on;
    495     fw_lane_config->LpDfeOn           = serdes_firmware_config.field.dfe_lp_mode;
    496     fw_lane_config->ForceBrDfe        = serdes_firmware_config.field.force_brdfe_on;
    497     fw_lane_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis;
    498     fw_lane_config->UnreliableLos     = serdes_firmware_config.field.unreliable_los;
    499     fw_lane_config->MediaType         = serdes_firmware_config.field.media_type;
    500     fw_lane_config->Cl72AutoPolEn     = serdes_firmware_config.field.cl72_auto_polarity_en;
    501     fw_lane_config->Cl72RestTO        = serdes_firmware_config.field.cl72_restart_timeout_en;
    502 
    503     return PHYMOD_E_NONE;
    504 }
    505 
    506 
    507 int tscf16_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
    508 {
    509     return PHYMOD_E_UNAVAIL;
    510     
    511 }
    512 
    513 
    514 int tscf16_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout)
    515 {
    516     switch(event){
    517     case phymodCoreEventPllLock:
    518         /* PHYMOD_IF_ERR_RETURN(tefmod16_pll_lock_wait(&core->access, timeout)); */
    519         break;
    520     default:
    521         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal wait event %u"), event));
    522     }
    523      
    524     return PHYMOD_E_NONE;
    525     
    526 }
    527 
    528 /*
    529  * Re-tune rx path
    530  * param phy phy access information
    531  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    532  */
    533 int tscf16_phy_rx_restart(const phymod_phy_access_t* phy)
    534 {
    535     PHYMOD_IF_ERR_RETURN(falcon16_tsc_rx_restart(&phy->access, 1));     
    536         
    537     return PHYMOD_E_NONE;
    538     
    539 }
    540 
    541 /*
    542  * Set phy polarity
    543  * param phy phy access information
    544  * param polarity   
    545  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    546  */
    547 int tscf16_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    548 {
    549     PHYMOD_IF_ERR_RETURN
    550         (tefmod16_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity));
    551     
    552     return PHYMOD_E_NONE;
    553     
    554 }
    555 
    556 /*
    557  * Get phy polarity
    558  * param phy phy access information
    559  * param polarity   
    560  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    561  */
    562 int tscf16_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    563 {
    564     PHYMOD_IF_ERR_RETURN
    565         (tefmod16_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity));
    566         
    567     return PHYMOD_E_NONE;
    568 }
    569 
    570 /*
    571  * Set tx fir parameters
    572  * param phy phy access information
    573  * param tx struct tx parameter (pre, main, post, post2, post3, rpara)
    574  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    575  */
    576 int tscf16_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    577 {
    578     PHYMOD_IF_ERR_RETURN
    579         (falcon16_tsc_apply_txfir_cfg(&phy->access, (int8_t)tx->pre, (int8_t)tx->main, (int8_t)tx->post, (int8_t)tx->post2, (int8_t)tx->post3));
    580         
    581     return PHYMOD_E_NONE;
    582 }
    583 
    584 /*
    585  * Get tx fir parameters
    586  * param phy phy access information
    587  * param tx struct tx parameter (pre, main, post, post2, post3, rpara)
    588  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    589  */
    590 int tscf16_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    591 {
    592     int8_t value = 0;
    593 
    594     PHYMOD_IF_ERR_RETURN
    595         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value));
    596     tx->pre = value;
    597     PHYMOD_IF_ERR_RETURN
    598         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value));
    599     tx->main = value;
    600     PHYMOD_IF_ERR_RETURN
    601         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value));
    602     tx->post = value;
    603     PHYMOD_IF_ERR_RETURN
    604         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value));
    605     tx->post2 = value;
    606     PHYMOD_IF_ERR_RETURN
    607         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value));
    608     tx->post3 = value;
    609     PHYMOD_IF_ERR_RETURN
    610         (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_RPARA, &value));
    611     tx->rpara = value;
    612 
    613     return PHYMOD_E_NONE;
    614 }
    615 
    616 /*
    617  * Set TX parameters using override   
    618  * param phy phy access information
    619  * param tx struct tx override (enable, value)   
    620  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    621  */
    622 int tscf16_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override)
    623 {
    624     PHYMOD_IF_ERR_RETURN
    625         (falcon16_tsc_tx_pi_freq_override(&phy->access,
    626                                     tx_override->phase_interpolator.enable,
    627                                     tx_override->phase_interpolator.value));
    628     
    629     return PHYMOD_E_NONE;
    630     
    631 }
    632 
    633 /*
    634  * Get TX override    
    635  * param phy phy access information
    636  * param tx struct tx override (enable, value)   
    637  * Returns PHYMOD_E_NONE if successful else PHYMOD_E_ERROR 
    638  */
    639 int tscf16_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override)
    640 {
    641     uint16_t pi_value;
    642 
    643     PHYMOD_IF_ERR_RETURN
    644         (falcon16_tsc_tx_pi_control_get(&phy->access, &pi_value));
    645 
    646     tx_override->phase_interpolator.value = (int32_t) pi_value;
    647 
    648     return PHYMOD_E_NONE;
    649     
    650 }
    651 
    652 int tscf16_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    653 {
    654     uint32_t i;
    655     uint8_t uc_lane_stopped;
    656     phymod_phy_access_t pm_phy_copy;
    657     int start_lane, num_lane, k;
    658 
    659     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    660     /* next program the tx fir taps and driver current based on the input */
    661     PHYMOD_IF_ERR_RETURN
    662         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    663 
    664     /*params check*/
    665     if ((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF16_NOF_DFES)){
    666         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps));
    667     }
    668 
    669        for (k = 0; k < num_lane; k++) {
    670         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + k)) {
    671             continue;
    672         }
    673         pm_phy_copy.access.lane_mask = 1 << (start_lane + k);
    674 
    675         /*vga set*/
    676         /* first check if uc lane is stopped already */
    677         PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_uc_lane_status(&pm_phy_copy.access, &uc_lane_stopped));
    678         if (!uc_lane_stopped) {
    679             PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&pm_phy_copy.access, 1));
    680         }
    681         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_VGA, rx->vga.value));
    682         /*dfe set*/
    683         for (i = 0 ; i < rx->num_of_dfe_taps ; i++){
    684             switch (i) {
    685                 case 0:
    686                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE1, rx->dfe[i].value));
    687                     break;
    688                 case 1:
    689                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE2, rx->dfe[i].value));
    690                     break;
    691                 case 2:
    692                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE3, rx->dfe[i].value));
    693                     break;
    694                 case 3:
    695                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE4, rx->dfe[i].value));
    696                     break;
    697                 case 4:
    698                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE5, rx->dfe[i].value));
    699                     break;
    700                 case 5:
    701                         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE6, rx->dfe[i].value));
    702                     break;
    703                 default:
    704                     return PHYMOD_E_PARAM;
    705             }
    706         }
    707         /*peaking filter set*/
    708         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF, rx->peaking_filter.value));
    709 
    710         /* low freq peak filter */
    711         PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF2, (int8_t)rx->low_freq_peaking_filter.value));
    712     }
    713  
    714     return PHYMOD_E_NONE;
    715     
    716 }
    717 
    718 int tscf16_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    719 {
    720     int8_t tmpData;
    721 
    722     PHYMOD_IF_ERR_RETURN
    723         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_VGA,  &tmpData));
    724     rx->vga.value = tmpData;
    725     PHYMOD_IF_ERR_RETURN
    726         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1,  &tmpData));
    727     rx->dfe[0].value = tmpData;
    728     PHYMOD_IF_ERR_RETURN
    729         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2,  &tmpData));
    730     rx->dfe[1].value = tmpData;
    731     PHYMOD_IF_ERR_RETURN
    732         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3,  &tmpData));
    733     rx->dfe[2].value = tmpData;
    734     PHYMOD_IF_ERR_RETURN
    735         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4,  &tmpData));
    736     rx->dfe[3].value = tmpData;
    737     PHYMOD_IF_ERR_RETURN
    738         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5,  &tmpData));
    739     rx->dfe[4].value = tmpData;
    740     PHYMOD_IF_ERR_RETURN
    741         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE6,  &tmpData));
    742     rx->dfe[5].value = tmpData;
    743     PHYMOD_IF_ERR_RETURN
    744         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_PF,  &tmpData));
    745     rx->peaking_filter.value = tmpData;
    746     PHYMOD_IF_ERR_RETURN
    747         (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_PF2,  &tmpData));
    748     rx->low_freq_peaking_filter.value = tmpData;
    749 
    750     rx->num_of_dfe_taps = TSCF16_NOF_DFES;
    751     rx->dfe[0].enable = 1;
    752     rx->dfe[1].enable = 1;
    753     rx->dfe[2].enable = 1;
    754     rx->dfe[3].enable = 1;
    755     rx->dfe[4].enable = 1;
    756     rx->dfe[5].enable = 1;
    757     rx->vga.enable = 1;
    758     rx->low_freq_peaking_filter.enable = 1;
    759     rx->peaking_filter.enable = 1;
    760     
    761     return PHYMOD_E_NONE;
    762 }
    763 
    764 
    765 int tscf16_phy_rx_adaptation_resume(const phymod_phy_access_t* phy)
    766 {
    767         
    768     uint8_t uc_lane_stopped;
    769 
    770     PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_uc_lane_status(&phy->access, &uc_lane_stopped));
    771     if (uc_lane_stopped) {
    772         PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0));
    773     }
    774  
    775     return PHYMOD_E_NONE;
    776 }
    777 
    778 
    779 int tscf16_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    780 {
    781     PHYMOD_IF_ERR_RETURN(tefmod16_disable_set(&phy->access));
    782 
    783     return PHYMOD_E_NONE;
    784 }
    785 
    786 int tscf16_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    787 {
    788     uint32_t value = 0;
    789 
    790     PHYMOD_IF_ERR_RETURN(tefmod16_enable_get(&phy->access, &value));
    791     reset->tx = value & phymodResetDirectionCount;
    792     reset->rx = value & phymodResetDirectionCount;
    793 
    794     return PHYMOD_E_NONE;
    795     
    796 }
    797 
    798 
    799 int tscf16_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
    800 {
    801     phymod_phy_access_t pm_phy_copy;
    802     int start_lane, num_lane, i;
    803 
    804     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    805     /* next program the tx fir taps and driver current based on the input */
    806     PHYMOD_IF_ERR_RETURN
    807         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    808     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) {
    809         for (i = 0; i < num_lane; i++) {
    810             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    811                 continue;
    812             }
    813             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    814             PHYMOD_IF_ERR_RETURN(tefmod16_port_enable_set(&pm_phy_copy.access, 0));
    815         }
    816     }
    817     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) {
    818         for (i = 0; i < num_lane; i++) {
    819             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    820                 continue;
    821             }
    822             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    823             PHYMOD_IF_ERR_RETURN(tefmod16_port_enable_set(&pm_phy_copy.access, 1));
    824             PHYMOD_IF_ERR_RETURN(tefmod16_power_control(&phy->access, 0, 0));
    825         }
    826     }
    827     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) {
    828             /*disable tx on the PMD side */
    829             PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_disable(&phy->access, 1));
    830     }
    831     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) {
    832             /*enable tx on the PMD side */
    833             PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_disable(&phy->access, 0));
    834     }
    835     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) {
    836             /* disable rx on the PMD side */
    837             PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_set(&phy->access, 1));
    838     }
    839     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) {
    840             /*enable rx on the PMD side */
    841             PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_set(&phy->access, 0));
    842     }
    843  
    844     return PHYMOD_E_NONE;
    845     
    846 }
    847 
    848 int tscf16_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
    849 {
    850     int enable;
    851     uint32_t lb_enable;
    852     phymod_phy_access_t pm_phy_copy;
    853     int start_lane, num_lane;
    854 
    855     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    856     /* next program the tx fir taps and driver current based on the input */
    857     PHYMOD_IF_ERR_RETURN
    858         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    859 
    860     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    861 
    862     PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_get(&pm_phy_copy.access, &enable));
    863 
    864     /* next check if PMD loopback is on */
    865     if (enable) {
    866         PHYMOD_IF_ERR_RETURN(falcon16_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    867         if (lb_enable) enable = 0;
    868     }
    869 
    870     power->rx = (enable == 1)? phymodPowerOff: phymodPowerOn;
    871     /* Commented the following line. Because if in PMD loopback mode, we squelch the
    872            xmit, and we should still see the correct port status */
    873     /* PHYMOD_IF_ERR_RETURN(tefmod16_tx_squelch_get(&pm_phy_copy.access, &enable)); */
    874     power->tx = (enable == 1)? phymodPowerOff: phymodPowerOn;
    875      
    876     return PHYMOD_E_NONE;
    877     
    878 }
    879 
    880 
    881 int tscf16_phy_hg2_codec_control_set(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t hg2_codec)
    882             /* disable rx on the PMD side */
    883 {
    884     tefmod16_hg2_codec_t local_copy;
    885 
    886     switch (hg2_codec) {
    887         case phymodBcmHG2CodecOff: local_copy = TEFMOD16_HG2_CODEC_OFF;
    888                 break;
    889         case phymodBcmHG2CodecOnWith8ByteIPG:  local_copy = TEFMOD16_HG2_CODEC_ON_8BYTE_IPG;
    890                 break;
    891         case phymodBcmHG2CodecOnWith9ByteIPG:  local_copy = TEFMOD16_HG2_CODEC_ON_9BYTE_IPG;
    892                 break;
    893         default: local_copy = TEFMOD16_HG2_CODEC_OFF;
    894                 break;
    895         }
    896     PHYMOD_IF_ERR_RETURN(tefmod16_hg2_codec_set(&phy->access, local_copy));
    897         
    898     return PHYMOD_E_NONE;
    899     
    900 }
    901 
    902 int tscf16_phy_hg2_codec_control_get(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t* hg2_codec)
    903 {
    904     tefmod16_hg2_codec_t local_copy;
    905 
    906     PHYMOD_IF_ERR_RETURN(tefmod16_hg2_codec_get(&phy->access, &local_copy));
    907 
    908     switch (local_copy) {
    909         case TEFMOD16_HG2_CODEC_OFF: *hg2_codec = phymodBcmHG2CodecOff;
    910                 break;
    911         case TEFMOD16_HG2_CODEC_ON_8BYTE_IPG:  *hg2_codec = phymodBcmHG2CodecOnWith8ByteIPG;
    912                 break;
    913         case TEFMOD16_HG2_CODEC_ON_9BYTE_IPG:  *hg2_codec = phymodBcmHG2CodecOnWith9ByteIPG;
    914                 break;
    915         default: *hg2_codec = phymodBcmHG2CodecOff;
    916                 break;
    917         }
    918     
    919     return PHYMOD_E_NONE;
    920     
    921 }
    922 
    923 
    924 int tscf16_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    925 {
    926     phymod_firmware_lane_config_t fw_lane_config;
    927     PHYMOD_IF_ERR_RETURN (tscf16_phy_firmware_lane_config_get(phy, &fw_lane_config));
    928 
    929     switch (tx_control) {
    930     case phymodTxTrafficDisable:
    931         PHYMOD_IF_ERR_RETURN(tefmod16_tx_lane_control_set(&phy->access, TEFMOD16_TX_LANE_TRAFFIC_DISABLE));
    932         break;
    933     case phymodTxTrafficEnable:
    934         PHYMOD_IF_ERR_RETURN(tefmod16_tx_lane_control_set(&phy->access, TEFMOD16_TX_LANE_TRAFFIC_ENABLE));
    935         break;
    936     case phymodTxReset:
    937         PHYMOD_IF_ERR_RETURN(tefmod16_tx_lane_control_set(&phy->access, TEFMOD16_TX_LANE_RESET));
    938         break;
    939     case phymodTxSquelchOn:
    940         PHYMOD_IF_ERR_RETURN(tefmod16_tx_squelch_set(&phy->access, 1));
    941         break;
    942     case phymodTxSquelchOff:
    943         PHYMOD_IF_ERR_RETURN(tefmod16_tx_squelch_set(&phy->access, 0));
    944         break;
    945     case phymodTxElectricalIdleEnable:
    946         if (fw_lane_config.LaneConfigFromPCS == 0) {
    947             PHYMOD_IF_ERR_RETURN(falcon16_electrical_idle_set(&phy->access, 1));
    948         }else{
    949             return PHYMOD_E_UNAVAIL; /*autoneg */
    950         }
    951         break;
    952     case phymodTxElectricalIdleDisable:
    953         if (fw_lane_config.LaneConfigFromPCS == 0) {
    954             PHYMOD_IF_ERR_RETURN(falcon16_electrical_idle_set(&phy->access, 0));
    955         }else{
    956             return PHYMOD_E_UNAVAIL; 
    957         }
    958         break;
    959     default:
    960         break;
    961     }
    962     
    963     return PHYMOD_E_NONE;
    964     
    965 }
    966 
    967 int tscf16_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    968 {
    969     int enable, reset, tx_lane;
    970     uint32_t lb_enable;
    971     phymod_phy_access_t pm_phy_copy;
    972     int start_lane, num_lane;
    973 
    974     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    975     /* next program the tx fir taps and driver current based on the input */
    976     PHYMOD_IF_ERR_RETURN
    977         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    978 
    979     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    980 
    981     PHYMOD_IF_ERR_RETURN(tefmod16_tx_squelch_get(&pm_phy_copy.access, &enable));
    982 
    983     /* next check if PMD loopback is on */
    984     if (enable) {
    985         PHYMOD_IF_ERR_RETURN(falcon16_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    986         if (lb_enable) enable = 0;
    987     }
    988 
    989     if (enable) {
    990         *tx_control = phymodTxSquelchOn;
    991     } else {
    992         PHYMOD_IF_ERR_RETURN(tefmod16_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane));
    993         if (!reset) {
    994             *tx_control = phymodTxReset;
    995         } else if (!tx_lane) {
    996             *tx_control = phymodTxTrafficDisable;
    997         } else {
    998             *tx_control = phymodTxTrafficEnable;
    999         }
   1000     }
   1001     
   1002     return PHYMOD_E_NONE;
   1003     
   1004 }
   1005 
   1006 
   1007 int tscf16_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
   1008 {
   1009     phymod_phy_access_t pm_phy_copy;
   1010     int start_lane, num_lane, i;
   1011 
   1012     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1013     /* next program the tx fir taps and driver current based on the input */
   1014     PHYMOD_IF_ERR_RETURN
   1015         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1016 
   1017     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1018 
   1019     switch (rx_control) {
   1020     case phymodRxReset:
   1021         PHYMOD_IF_ERR_RETURN(tefmod16_rx_lane_control_set(&phy->access, 1));
   1022         break;
   1023     case phymodRxDisable:
   1024         PHYMOD_IF_ERR_RETURN(tefmod16_rx_lane_control_set(&phy->access, 0));
   1025         break;
   1026     case phymodRxSquelchOn:
   1027         for (i = 0; i < num_lane; i++) {
   1028             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1029                 continue;
   1030             }
   1031             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1032             PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_set(&pm_phy_copy.access, 1));
   1033         }
   1034         break;
   1035     case phymodRxSquelchOff:
   1036         for (i = 0; i < num_lane; i++) {
   1037             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1038                 continue;
   1039             }
   1040             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1041             PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_set(&pm_phy_copy.access, 0));
   1042         }
   1043         break;
   1044     default:
   1045         break;
   1046     }
   1047     
   1048     return PHYMOD_E_NONE;
   1049     
   1050 }
   1051 
   1052 int tscf16_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
   1053 {
   1054     int enable, reset;
   1055     uint32_t lb_enable;
   1056     phymod_phy_access_t pm_phy_copy;
   1057     int start_lane, num_lane;
   1058 
   1059     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1060     /* next program the tx fir taps and driver current based on the input */
   1061     PHYMOD_IF_ERR_RETURN
   1062         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1063 
   1064     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1065 
   1066     PHYMOD_IF_ERR_RETURN(tefmod16_rx_squelch_get(&pm_phy_copy.access, &enable));
   1067     /* next check if PMD loopback is on */
   1068     if (enable) {
   1069         PHYMOD_IF_ERR_RETURN(falcon16_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
   1070         if (lb_enable) enable = 0;
   1071     }
   1072     if (enable) {
   1073         *rx_control = phymodRxSquelchOn;
   1074     } else {
   1075         PHYMOD_IF_ERR_RETURN(tefmod16_rx_lane_control_get(&pm_phy_copy.access, &reset));
   1076         if (reset == 0) {
   1077             *rx_control = phymodRxReset;
   1078         } else {
   1079             *rx_control = phymodRxSquelchOff;
   1080         }
   1081     }
   1082      
   1083     return PHYMOD_E_NONE;
   1084     
   1085 }
   1086 
   1087 /*
   1088  * Enables/Disables FEC override bit.
   1089  * 0xc055 field[4:3] 
   1090  *               0x1    Enable for NOFEC 100G AN
   1091  */
   1092 int tscf16_phy_fec_override_set(const phymod_phy_access_t* phy, uint32_t enable)
   1093 {
   1094      if ((enable ==  0) || (enable == 1)) {
   1095          PHYMOD_IF_ERR_RETURN(tefmod16_fec_override_set(&phy->access, enable));
   1096      } else {
   1097          PHYMOD_DEBUG_ERROR(("ERROR :: Supported input values: 1 to set FEC override, 0 to disable FEC override\n"));
   1098      }
   1099 
   1100     return PHYMOD_E_NONE;
   1101 }
   1102 
   1103 int tscf16_phy_fec_override_get(const phymod_phy_access_t* phy, uint32_t* enable)
   1104 {
   1105     
   1106      PHYMOD_IF_ERR_RETURN(tefmod16_fec_override_get(&phy->access, enable));
   1107     
   1108     return PHYMOD_E_NONE;
   1109 
   1110 }
   1111 
   1112 int tscf16_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
   1113 {
   1114     int fec_en;
   1115     tefmod16_fec_type_t fec_type;
   1116 
   1117     /* first check FEC type */
   1118     if (PHYMOD_FEC_CL91_GET(enable)) {
   1119         fec_type = TEFMOD16_CL91;
   1120     } else if (PHYMOD_FEC_CL108_GET(enable)) {
   1121         fec_type = TEFMOD16_CL108;
   1122     } else {
   1123         fec_type = TEFMOD16_CL74;
   1124     }
   1125 
   1126     /* check FEC on/off */
   1127     fec_en   = enable & TEFMOD16_PHY_CONTROL_FEC_MASK;
   1128     PHYMOD_IF_ERR_RETURN(
   1129       tefmod16_FEC_control(&phy->access, fec_type, fec_en, 0));
   1130 
   1131     return PHYMOD_E_NONE;
   1132     
   1133 }
   1134 
   1135 int tscf16_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
   1136 {
   1137     int fec_en;
   1138     tefmod16_fec_type_t fec_type;
   1139 
   1140     /* first check FEC type */
   1141     if (PHYMOD_FEC_CL91_GET(*enable)) {
   1142         fec_type = TEFMOD16_CL91;
   1143     } else if (PHYMOD_FEC_CL108_GET(*enable)) {
   1144         fec_type = TEFMOD16_CL108;
   1145     } else {
   1146         fec_type = TEFMOD16_CL74;
   1147     }
   1148 
   1149     PHYMOD_IF_ERR_RETURN(
   1150       tefmod16_FEC_get(&phy->access, fec_type, &fec_en));
   1151     PHYMOD_DEBUG_VERBOSE(("FEC enable state :: %x :: fec_type :: %x\n", fec_en, fec_type));
   1152     *enable = (uint32_t) fec_en;
   1153 
   1154     return PHYMOD_E_NONE;
   1155 }
   1156 
   1157 
   1158 int tscf16_phy_autoneg_oui_set(const phymod_phy_access_t* phy, phymod_autoneg_oui_t an_oui)
   1159 {
   1160     tefmod16_an_oui_t oui;
   1161 
   1162     oui.oui                    = an_oui.oui;
   1163     oui.oui_override_hpam_adv  = an_oui.oui_override_hpam_adv;
   1164     oui.oui_override_hpam_det  = an_oui.oui_override_hpam_det;
   1165     oui.oui_override_bam73_adv = an_oui.oui_override_bam73_adv;
   1166     oui.oui_override_bam73_det = an_oui.oui_override_bam73_det;
   1167     PHYMOD_IF_ERR_RETURN(tefmod16_an_oui_set(&phy->access, oui));
   1168 
   1169     return PHYMOD_E_NONE;
   1170     
   1171 }
   1172 
   1173 int tscf16_phy_autoneg_oui_get(const phymod_phy_access_t* phy, phymod_autoneg_oui_t* an_oui)
   1174 {
   1175     tefmod16_an_oui_t oui;
   1176 
   1177     PHYMOD_IF_ERR_RETURN(tefmod16_an_oui_get(&phy->access, &oui));
   1178     an_oui->oui_override_hpam_adv  = oui.oui_override_hpam_adv;
   1179     an_oui->oui_override_hpam_det  = oui.oui_override_hpam_det;
   1180     an_oui->oui_override_bam73_adv = oui.oui_override_bam73_adv;
   1181     an_oui->oui_override_bam73_det = oui.oui_override_bam73_det;
   1182 
   1183     return PHYMOD_E_NONE;
   1184     
   1185 }
   1186 
   1187 
   1188 int tscf16_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable)
   1189 {
   1190     uint32_t lpi_bypass;
   1191     int rv = PHYMOD_E_NONE;
   1192 
   1193     lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable);
   1194     enable &= 0x1;
   1195     if (lpi_bypass) {
   1196         rv = tefmod16_eee_control_set(&phy->access,enable);
   1197     } else {
   1198         return PHYMOD_E_UNAVAIL;
   1199     }
   1200 
   1201     return rv;
   1202 }
   1203 
   1204 int tscf16_phy_eee_get(const phymod_phy_access_t* phy, uint32_t* enable)
   1205 {
   1206     if (PHYMOD_LPI_BYPASS_GET(*enable)) {
   1207         PHYMOD_IF_ERR_RETURN(tefmod16_eee_control_get(&phy->access, enable));
   1208         PHYMOD_LPI_BYPASS_SET(*enable);
   1209     } else {
   1210         return PHYMOD_E_UNAVAIL;
   1211     }
   1212 
   1213     return PHYMOD_E_NONE;
   1214 }
   1215 
   1216 int tscf16_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
   1217 {
   1218     uint32_t current_pll_div = 0;
   1219     uint32_t new_pll_div = 0;
   1220     int16_t  new_os_mode =-1;
   1221     tefmod16_spd_intfc_type_t spd_intf = TEFMOD16_SPD_ILLEGAL;
   1222     phymod_phy_access_t pm_phy_copy;
   1223     int start_lane, num_lane, i, pll_switch=0;
   1224     int lane_bkup, os_mode;
   1225     enum falcon16_tsc_pll_refclk_enum refclk = FALCON16_TSC_PLL_REFCLK_156P25MHZ;
   1226     uint32_t  vco_rate;
   1227     phymod_firmware_lane_config_t firmware_lane_config;
   1228     int is_10g_spd_override = 0;
   1229 
   1230     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   1231 
   1232     /*next program the tx fir taps and driver current based on the input*/
   1233     PHYMOD_IF_ERR_RETURN
   1234         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1235 
   1236     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1237 
   1238     /* first hold the pcs lane reset */
   1239     tefmod16_disable_set(&phy->access);
   1240 
   1241     /*Hold the per lane PMD soft reset bit*/
   1242     for (i = 0; i < num_lane; i++) {
   1243         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1244             continue;
   1245         }
   1246         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1247         PHYMOD_IF_ERR_RETURN
   1248             (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1249     }
   1250     /* remove pmd_tx_disable_pin_dis it may be asserted because of ILKn */
   1251     for (i = 0; i < num_lane; i++) {
   1252         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1253             continue;
   1254         }
   1255         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1256         PHYMOD_IF_ERR_RETURN
   1257             (falcon16_pmd_tx_disable_pin_dis_set(&pm_phy_copy.access, 0));
   1258     }
   1259 
   1260     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1261     PHYMOD_IF_ERR_RETURN
   1262         (tscf16_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   1263     
   1264     /*make sure that an and config from pcs is off*/
   1265     firmware_lane_config.AnEnabled = 0;
   1266     firmware_lane_config.LaneConfigFromPCS = 0;
   1267     firmware_lane_config.DfeOn = 1;
   1268     firmware_lane_config.LpDfeOn = 0;
   1269     /* enable pmd_rx_restart after 600ms if the link has faield to complete training */
   1270     firmware_lane_config.Cl72RestTO = 1;
   1271     firmware_lane_config.Cl72AutoPolEn = 0; 
   1272 
   1273     if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1274         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1275     } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1276         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1277     } else {
   1278         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1279     }    
   1280     /* this field is used only when MediaType is optical */
   1281     if (PHYMOD_INTF_MODES_UNRELIABLE_LOS_GET(config)) {
   1282         firmware_lane_config.UnreliableLos = 1;
   1283     } else {
   1284         /* los is reliable */
   1285         firmware_lane_config.UnreliableLos = 0;
   1286     }
   1287     if (config->data_rate == 1000) {
   1288        firmware_lane_config.DfeOn = 0;
   1289     }
   1290 
   1291     PHYMOD_IF_ERR_RETURN
   1292         (tefmod16_update_port_mode(&phy->access, (int *) &pll_switch));
   1293 
   1294     if (config->interface_type == phymodInterface1000X) {
   1295         if (config->pll_divider_req == 165) {
   1296             spd_intf = TEFMOD16_SPD_1G_25G;
   1297         } else {
   1298             spd_intf = TEFMOD16_SPD_1G_20G;
   1299         }
   1300     } else if (config->interface_type == phymodInterfaceSGMII) {
   1301         if (config->pll_divider_req == 165) {
   1302             spd_intf = TEFMOD16_SPD_1G_25G;
   1303         } else {
   1304             spd_intf = TEFMOD16_SPD_1G_20G;
   1305         }
   1306     } else if ((config->interface_type == phymodInterfaceBypass) ||
   1307                (num_lane == 1)) {
   1308         switch (config->data_rate) {
   1309          case 10000:
   1310            spd_intf = TEFMOD16_SPD_10000_XFI;
   1311            if (!PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1312                firmware_lane_config.DfeOn = 0;
   1313            }
   1314            if (config->interface_type != phymodInterfaceBypass) {
   1315                if (config->pll_divider_req == 165) {
   1316                    is_10g_spd_override = 1;
   1317                    PHYMOD_IF_ERR_RETURN
   1318                        (tefmod16_override_10g_x1_spd_intf(&phy->access, 1));
   1319                } else {
   1320                    /*Remove the 10G speed override only when setting 10G working at 20G*/
   1321                    PHYMOD_IF_ERR_RETURN
   1322                        (tefmod16_override_10g_x1_spd_intf(&phy->access, 0));
   1323                }
   1324            }
   1325            break;
   1326          case 12000:
   1327            spd_intf = TEFMOD16_SPD_10000_XFI;
   1328            if (!PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1329                firmware_lane_config.DfeOn = 0;
   1330            }
   1331            break;
   1332          case 10600:
   1333          case 11000:
   1334            spd_intf = TEFMOD16_SPD_10600_XFI_HG;
   1335            if (!PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1336                firmware_lane_config.DfeOn = 0;
   1337            }
   1338            break;
   1339          case 20000:
   1340            spd_intf = TEFMOD16_SPD_20000_XFI;
   1341            break;
   1342          case 21200:
   1343            spd_intf = TEFMOD16_SPD_21200_XFI_HG;
   1344            break;
   1345          case 25000:
   1346            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1347                spd_intf = TEFMOD16_SPD_26500_XFI_HG;
   1348                if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1349                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1350                } else {
   1351                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1352                }
   1353            } else {
   1354                spd_intf = TEFMOD16_SPD_25000_XFI;
   1355                if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1356                    firmware_lane_config.DfeOn = 0;
   1357                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1358                } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1359                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1360                } else {
   1361                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1362                }
   1363            }
   1364            break;
   1365          case 27000:
   1366            spd_intf = TEFMOD16_SPD_26500_XFI_HG;
   1367            firmware_lane_config.DfeOn = 1;
   1368            firmware_lane_config.LpDfeOn = 0;
   1369             if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1370                firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1371            } else {
   1372                firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1373            }
   1374            break;
   1375          default:
   1376            /* if the interface is pcs bypass mode and check the speed */
   1377            if (config->interface_type == phymodInterfaceBypass) {
   1378                /* disable DFE for lower speed */
   1379                if (config->data_rate < 10000) {
   1380                    firmware_lane_config.DfeOn = 0;
   1381                }
   1382            } else {
   1383                spd_intf = TEFMOD16_SPD_10000_XFI;
   1384                firmware_lane_config.DfeOn = 0;
   1385            }
   1386            break;
   1387         }
   1388     } else if ((config->interface_type == phymodInterfaceKR2) ||
   1389                (config->interface_type == phymodInterfaceCR2) ||
   1390                (config->interface_type == phymodInterfaceXLAUI2) ||
   1391                (config->interface_type == phymodInterfaceRXAUI) ||
   1392                (config->interface_type == phymodInterfaceX2) ||
   1393                (num_lane == 2))  {
   1394        switch (config->data_rate) {
   1395          case 20000:
   1396            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1397                spd_intf = TEFMOD16_SPD_21G_MLD_HG_X2;
   1398                firmware_lane_config.DfeOn = 0;
   1399                firmware_lane_config.LpDfeOn = 0;
   1400                firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1401                if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1402                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1403                } else {
   1404                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1405                }
   1406            } else {
   1407                spd_intf = TEFMOD16_SPD_20G_MLD_X2;
   1408                if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1409                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1410                } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1411                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1412                } else {
   1413                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1414                }
   1415            }
   1416            break;
   1417          case 21000:
   1418          case 21200:
   1419            firmware_lane_config.DfeOn = 0;
   1420            firmware_lane_config.LpDfeOn = 0;
   1421            spd_intf = TEFMOD16_SPD_21G_MLD_HG_X2;
   1422            firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1423            break;
   1424          case 40000:
   1425            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1426                spd_intf = TEFMOD16_SPD_42G_MLD_HG_X2;
   1427                firmware_lane_config.DfeOn = 1;
   1428                firmware_lane_config.LpDfeOn = 1;
   1429                firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1430                if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1431                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1432                } else {
   1433                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1434                }
   1435            } else {
   1436                spd_intf = TEFMOD16_SPD_40G_MLD_X2;
   1437                if (config->interface_type == phymodInterfaceXLAUI2) {
   1438                    firmware_lane_config.DfeOn = 0;
   1439                    firmware_lane_config.LpDfeOn = 0;
   1440                } else {
   1441                    firmware_lane_config.DfeOn = 1;
   1442                    firmware_lane_config.LpDfeOn = 1;
   1443                }
   1444                if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1445                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1446                } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1447                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1448                } else {
   1449                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1450                }
   1451            }
   1452            break;
   1453          case 42000:
   1454            spd_intf = TEFMOD16_SPD_42G_MLD_HG_X2;
   1455            firmware_lane_config.DfeOn = 1;
   1456            firmware_lane_config.LpDfeOn = 1;
   1457            firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1458            break;
   1459          case 50000:
   1460            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1461                spd_intf = TEFMOD16_SPD_53G_MLD_HG_X2;
   1462            } else {
   1463                spd_intf = TEFMOD16_SPD_50G_MLD_X2;
   1464            }
   1465            break;
   1466          case 53000:
   1467            spd_intf = TEFMOD16_SPD_53G_MLD_HG_X2;
   1468            break;
   1469          default:
   1470            spd_intf = TEFMOD16_SPD_20G_MLD_X2;
   1471            break;
   1472        }
   1473     } else {
   1474        switch (config->data_rate) {
   1475          case 40000:
   1476            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1477                spd_intf = TEFMOD16_SPD_42G_MLD_HG_X4;
   1478                firmware_lane_config.DfeOn = 1;
   1479                firmware_lane_config.LpDfeOn = 1;
   1480            } else if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1481                spd_intf = TEFMOD16_SPD_40G_MLD_X4;
   1482                firmware_lane_config.DfeOn = 0;
   1483                firmware_lane_config.LpDfeOn = 0;
   1484            } else {
   1485                if (config->interface_type == phymodInterfaceXLAUI) {
   1486                    spd_intf = TEFMOD16_SPD_40G_MLD_X4;
   1487                    firmware_lane_config.DfeOn = 0;
   1488                    firmware_lane_config.LpDfeOn = 0;
   1489                } else {
   1490                    spd_intf = TEFMOD16_SPD_40G_MLD_X4;
   1491                    firmware_lane_config.DfeOn = 1;
   1492                    firmware_lane_config.LpDfeOn = 1;
   1493                }
   1494            }
   1495            break;
   1496          case 42000:
   1497            spd_intf = TEFMOD16_SPD_42G_MLD_HG_X4;
   1498            firmware_lane_config.DfeOn = 1;
   1499            firmware_lane_config.LpDfeOn = 1;
   1500            break;
   1501          case 48000:
   1502            spd_intf = TEFMOD16_SPD_40G_MLD_X4;
   1503            firmware_lane_config.DfeOn = 0;
   1504            firmware_lane_config.LpDfeOn = 0;
   1505            break;
   1506          case 50000:
   1507            spd_intf = TEFMOD16_SPD_50G_MLD_X4;
   1508            break;
   1509          case 53000:
   1510            spd_intf = TEFMOD16_SPD_53G_MLD_HG_X4;
   1511            break;
   1512          case 100000:
   1513            if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1514                spd_intf = TEFMOD16_SPD_106G_MLD_HG_X4;
   1515                if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1516                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1517                } else {
   1518                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1519                }
   1520            } else {
   1521                spd_intf = TEFMOD16_SPD_100G_MLD_X4;
   1522                if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1523                    firmware_lane_config.DfeOn = 0;
   1524                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1525                } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1526                    firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1527                } else {
   1528                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1529                }
   1530                if (config->interface_type == phymodInterfaceCAUI4 || config->interface_type == phymodInterfaceCAUI) {
   1531                    firmware_lane_config.LpDfeOn = 1;
   1532                    firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1533                }
   1534            }
   1535            break;
   1536          case 106000:
   1537            spd_intf = TEFMOD16_SPD_106G_MLD_HG_X4;
   1538            firmware_lane_config.DfeOn = 1;
   1539            firmware_lane_config.LpDfeOn = 0;
   1540            if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1541                firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1542            } else {
   1543                firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1544            }
   1545            break;
   1546          default:
   1547            spd_intf = TEFMOD16_SPD_40G_MLD_X4;
   1548            firmware_lane_config.DfeOn = 0;
   1549            break;
   1550        }
   1551     }
   1552 
   1553     /*only when 10G working at 25G, the 10G clock is enabled*/
   1554     if (is_10g_spd_override) {
   1555         PHYMOD_IF_ERR_RETURN
   1556             (tefmod16_10g_clock_enable(&phy->access, 1));
   1557     } else {
   1558         PHYMOD_IF_ERR_RETURN
   1559             (tefmod16_10g_clock_enable(&phy->access, 0));
   1560     }
   1561     /* get current pll */ 
   1562     PHYMOD_IF_ERR_RETURN
   1563         (falcon16_tsc_INTERNAL_read_pll_div(&phy->access, &current_pll_div));
   1564     
   1565     if (config->interface_type == phymodInterfaceBypass) {
   1566         PHYMOD_IF_ERR_RETURN
   1567             (falcon16_tsc_get_pll_vco_osmode(config, &vco_rate, &new_pll_div, &new_os_mode));
   1568     } else {
   1569         PHYMOD_IF_ERR_RETURN
   1570             (tefmod16_plldiv_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div));
   1571         if ((config->data_rate == 10000) && (num_lane == 1)) {
   1572             if (is_10g_spd_override) {
   1573                 new_pll_div = TEFMOD16_PLL_MODE_DIV_165;
   1574                 new_os_mode = 0;
   1575             }
   1576         }
   1577         /* For 12GG XFI , data rate specified is 12000, and pll_div is set to 160 ( 6 )  */
   1578         if ((config->data_rate == 12000) && (num_lane == 1)) {
   1579             if (config->ref_clock == phymodRefClk125Mhz) {
   1580                 new_pll_div = TEFMOD16_PLL_MODE_DIV_200; 
   1581             } else {       
   1582                 new_pll_div = TEFMOD16_PLL_MODE_DIV_160;
   1583             }     
   1584         }
   1585         if ((config->data_rate == 20000) &&
   1586             PHYMOD_INTF_MODES_HIGIG_GET(config) && (num_lane == 2)) {
   1587                new_pll_div = TEFMOD16_PLL_MODE_DIV_132;
   1588         }
   1589         if ((config->data_rate == 40000) && 
   1590             PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1591            if (num_lane == 4) {
   1592                if (config->ref_clock == phymodRefClk125Mhz) {
   1593                     new_pll_div = TEFMOD16_PLL_MODE_DIV_165;
   1594                } else {
   1595                     new_pll_div = TEFMOD16_PLL_MODE_DIV_132;
   1596                }
   1597            }
   1598            if (num_lane == 2) {
   1599                new_pll_div =  TEFMOD16_PLL_MODE_DIV_132;
   1600            }
   1601         }
   1602         if ((config->data_rate == 48000) && (num_lane == 4)) {
   1603             if (config->ref_clock == phymodRefClk125Mhz) {
   1604                 new_pll_div = TEFMOD16_PLL_MODE_DIV_200; 
   1605             } else {       
   1606                 new_pll_div = TEFMOD16_PLL_MODE_DIV_160;
   1607             }     
   1608         }
   1609         if ((config->data_rate == 100000) &&
   1610             PHYMOD_INTF_MODES_HIGIG_GET(config) &&
   1611             (num_lane == 4)) {
   1612             new_pll_div = TEFMOD16_PLL_MODE_DIV_165;
   1613         }
   1614 
   1615         if ((config->data_rate == 50000) &&
   1616             PHYMOD_INTF_MODES_HIGIG_GET(config) &&
   1617             (num_lane == 2)) {
   1618             new_pll_div = TEFMOD16_PLL_MODE_DIV_165;
   1619         }
   1620         if ((config->data_rate == 25000) &&
   1621             PHYMOD_INTF_MODES_HIGIG_GET(config) &&
   1622             (num_lane == 1)) {
   1623             new_pll_div = TEFMOD16_PLL_MODE_DIV_165;
   1624         }
   1625     }
   1626 
   1627     if (new_os_mode>=0) {
   1628         os_mode = new_os_mode | 0x80000000 ;
   1629     } else {
   1630         os_mode = 0 ;
   1631     }
   1632     PHYMOD_IF_ERR_RETURN
   1633         (tefmod16_pmd_osmode_set(&phy->access, spd_intf, config->ref_clock, os_mode));
   1634 
   1635     /*if pll change is enabled*/
   1636     if ((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){
   1637         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   1638                                (_PHYMOD_MSG("pll has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled"),
   1639                                  (unsigned int)current_pll_div, (unsigned int)new_pll_div));
   1640     }
   1641 
   1642     /*pll switch is required and expected */
   1643     if ((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) {
   1644 
   1645         /* Change in PLL, so reset all the ports first. */
   1646         lane_bkup = pm_phy_copy.access.lane_mask;
   1647         pm_phy_copy.access.lane_mask = 0xf;
   1648         tefmod16_disable_set(&pm_phy_copy.access);
   1649         pm_phy_copy.access.lane_mask = lane_bkup;
   1650 
   1651         /*set the PLL divider */
   1652         if (config->ref_clock == phymodRefClk125Mhz){ 
   1653             refclk = FALCON16_TSC_PLL_REFCLK_125MHZ;
   1654         }
   1655         PHYMOD_IF_ERR_RETURN
   1656             (falcon16_tsc_core_dp_reset(&pm_phy_copy.access, 1));
   1657 
   1658         PHYMOD_IF_ERR_RETURN
   1659             (falcon16_tsc_configure_pll_refclk_div(&pm_phy_copy.access, refclk, new_pll_div));
   1660 
   1661         PHYMOD_IF_ERR_RETURN
   1662             (falcon16_tsc_core_dp_reset(&pm_phy_copy.access, 0));
   1663 
   1664         PHYMOD_IF_ERR_RETURN
   1665             (tefmod16_master_port_num_set(&phy->access, start_lane));
   1666 
   1667         PHYMOD_IF_ERR_RETURN
   1668             (tefmod16_pll_reset_enable_set(&phy->access, 1));
   1669 
   1670          
   1671     }
   1672     if (config->interface_type != phymodInterfaceBypass) {
   1673       PHYMOD_IF_ERR_RETURN
   1674             (tefmod16_set_spd_intf(&phy->access, spd_intf));
   1675     }
   1676 
   1677     for (i = 0; i < num_lane; i++) {
   1678         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1679             continue;
   1680         }
   1681         pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i);
   1682         PHYMOD_IF_ERR_RETURN
   1683              (_tscf16_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   1684     }
   1685 
   1686     /*release the per lne soft reset bit*/
   1687     for (i = 0; i < num_lane; i++) {
   1688         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1689             continue;
   1690         }
   1691         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1692         PHYMOD_IF_ERR_RETURN
   1693             (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1694     }
   1695         
   1696     return PHYMOD_E_NONE;
   1697     
   1698 }
   1699 
   1700 
   1701 
   1702 STATIC
   1703 int _tscf16_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id, phymod_phy_inf_config_t* config)
   1704 {
   1705     int ilkn_set;
   1706     int osr_mode;
   1707     int div_osr_value;
   1708     uint32_t vco_rate;
   1709     uint32_t pll_multiplier;
   1710     uint32_t plldiv_r_val;
   1711 
   1712     PHYMOD_IF_ERR_RETURN(tefmod16_pcs_ilkn_chk(&phy->access, &ilkn_set));
   1713     PHYMOD_IF_ERR_RETURN(tefmod16_get_plldiv(&phy->access, &plldiv_r_val));
   1714 
   1715     if (ilkn_set) {
   1716         config->interface_type = phymodInterfaceBypass;
   1717         PHYMOD_IF_ERR_RETURN(tefmod16_get_plldiv(&phy->access, &plldiv_r_val));
   1718         PHYMOD_IF_ERR_RETURN
   1719             (_tscf16_pll_multiplier_get(plldiv_r_val, &pll_multiplier));
   1720         PHYMOD_IF_ERR_RETURN
   1721             (falcon16_osr_mode_get(&phy->access, &osr_mode));
   1722 
   1723         switch (config->ref_clock) {
   1724             case phymodRefClk156Mhz:
   1725                 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100;
   1726                 break;
   1727             case phymodRefClk125Mhz:
   1728                 vco_rate = pll_multiplier * 125;
   1729                 break;
   1730             default:
   1731                 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100;
   1732                 break;
   1733         }
   1734         div_osr_value = 1 << osr_mode;
   1735         config->data_rate = vco_rate/div_osr_value;
   1736     } else {
   1737         switch (speed_id) {
   1738         case 0x0:
   1739             config->data_rate = 10000;
   1740             config->interface_type = phymodInterfaceCR;
   1741             break;
   1742         case 0x1:
   1743             config->data_rate = 10000;
   1744             config->interface_type = phymodInterfaceKR;
   1745             break;
   1746         case 0x2:
   1747             config->data_rate = 10000;
   1748             config->interface_type = phymodInterfaceKR;
   1749             /*next check the PLL divider to see if 10G or 12G */
   1750             PHYMOD_IF_ERR_RETURN(tefmod16_get_plldiv(&phy->access, &plldiv_r_val));
   1751             if ((config->ref_clock == phymodRefClk125Mhz)  &&
   1752                 (plldiv_r_val == 0xd)) {
   1753                 config->data_rate = 12000;
   1754             }
   1755 
   1756             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1757                 (plldiv_r_val == 0x6)) {
   1758                 config->data_rate = 12000;
   1759             }
   1760             break;
   1761         case 0x4:
   1762             config->data_rate = 11000;
   1763             config->interface_type = phymodInterfaceCR;
   1764             break;
   1765         case 0x5:
   1766             config->data_rate = 11000;
   1767             config->interface_type = phymodInterfaceKR;
   1768             break;
   1769         case 0x6:
   1770             config->data_rate = 11000;
   1771             config->interface_type = phymodInterfaceKR;
   1772             break;
   1773         case 0x8:
   1774             config->data_rate = 20000;
   1775             config->interface_type = phymodInterfaceCR;
   1776             break;
   1777         case 0x9:
   1778             config->data_rate = 20000;
   1779             config->interface_type = phymodInterfaceKR;
   1780             break;
   1781         case 0xa:
   1782             config->data_rate = 20000;
   1783             config->interface_type = phymodInterfaceKR;
   1784             break;
   1785         case 0xc:
   1786             config->data_rate = 21000;
   1787             config->interface_type = phymodInterfaceCR;
   1788             break;
   1789         case 0xd:
   1790             config->data_rate = 21000;
   1791             config->interface_type = phymodInterfaceKR;
   1792             break;
   1793         case 0xe:
   1794             config->data_rate = 21000;
   1795             config->interface_type = phymodInterfaceKR;
   1796             break;
   1797            /* 25G_CR1_MSA */
   1798         case 0x10:
   1799             config->data_rate = 25000;
   1800             config->interface_type = phymodInterfaceCR;
   1801             break;
   1802         case 0x11:
   1803            /* 25G_KR1_MSA */
   1804             config->data_rate = 25000;
   1805             config->interface_type = phymodInterfaceKR;
   1806             break;
   1807            /* 25G_X1_MSA */
   1808         case 0x12:
   1809             config->data_rate = 25000;
   1810             config->interface_type = phymodInterfaceKR;
   1811             break;
   1812            /* 25G_HG2_CR1_MSA */
   1813         case 0x14:
   1814             config->data_rate = 27000;
   1815             if (plldiv_r_val == 0x7) {
   1816                 config->data_rate = 25000;
   1817             }
   1818             config->interface_type = phymodInterfaceCR;
   1819             break;
   1820            /* 25G_HG2_KR1_MSA */
   1821         case 0x15:
   1822             config->data_rate = 27000;
   1823             if (plldiv_r_val == 0x7) {
   1824                 config->data_rate = 25000;
   1825             }
   1826             config->interface_type = phymodInterfaceKR;
   1827             break;
   1828            /* 25G_HG2_X1_MSA */
   1829         case 0x16:
   1830             config->data_rate = 27000;
   1831             if (plldiv_r_val == 0x7) {
   1832                 config->data_rate = 25000;
   1833             }
   1834             config->interface_type = phymodInterfaceKR;
   1835             break;
   1836         case 0x18:
   1837             config->data_rate = 20000;
   1838             config->interface_type = phymodInterfaceCR2;
   1839             break;
   1840         case 0x19:
   1841             config->data_rate = 20000;
   1842             config->interface_type = phymodInterfaceKR2;
   1843             break;
   1844         case 0x1a:
   1845             config->data_rate = 20000;
   1846             config->interface_type = phymodInterfaceKR2;
   1847             break;
   1848         case 0x1c:
   1849             config->data_rate = 21000;
   1850             config->interface_type = phymodInterfaceCR2;
   1851             break;
   1852         case 0x1d:
   1853             config->data_rate = 21000;
   1854             config->interface_type = phymodInterfaceKR2;
   1855             break;
   1856         case 0x1e:
   1857             config->data_rate = 21000;
   1858             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1859                 (plldiv_r_val == 0x4)) {
   1860                 config->data_rate =20000;
   1861             }
   1862             config->interface_type = phymodInterfaceKR2;
   1863             break;
   1864         case 0x20:
   1865             config->data_rate = 40000;
   1866             config->interface_type = phymodInterfaceCR2;
   1867             break;
   1868         case 0x21:
   1869             config->data_rate = 40000;
   1870             config->interface_type = phymodInterfaceKR2;
   1871             break;
   1872         case 0x22:
   1873             config->data_rate = 40000;
   1874             config->interface_type = phymodInterfaceKR2;
   1875             break;
   1876         case 0x24:
   1877             config->data_rate = 42000;
   1878             config->interface_type = phymodInterfaceCR2;
   1879             break;
   1880         case 0x25:
   1881             config->data_rate = 42000;
   1882             config->interface_type = phymodInterfaceKR2;
   1883             break;
   1884         case 0x26:
   1885             config->data_rate = 42000;
   1886             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1887                 (plldiv_r_val == 0x4)) {
   1888                 config->data_rate = 40000;
   1889             }
   1890             config->interface_type = phymodInterfaceKR2;
   1891             break;
   1892         case 0x28:
   1893             config->data_rate = 40000;
   1894             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1895                 (plldiv_r_val == 0x5)) {
   1896                 config->data_rate =42000;
   1897             }
   1898             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1899                 (plldiv_r_val == 0x6)) {
   1900                 config->data_rate =48000;
   1901             }
   1902             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1903                 (plldiv_r_val == 0xa)) {
   1904                 config->data_rate =42000;
   1905             }
   1906             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1907                 (plldiv_r_val == 0xd)) {
   1908                 config->data_rate =48000;
   1909             }
   1910 
   1911             config->interface_type = phymodInterfaceCR4;
   1912             break;
   1913         case 0x29:
   1914             config->data_rate = 40000;
   1915             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1916                 (plldiv_r_val == 0x5)) {
   1917                 config->data_rate =42000;
   1918             }
   1919             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1920                 (plldiv_r_val == 0x6)) {
   1921                 config->data_rate =48000;
   1922             }
   1923             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1924                 (plldiv_r_val == 0xa)) {
   1925                 config->data_rate =42000;
   1926             }
   1927             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1928                 (plldiv_r_val == 0xd)) {
   1929                 config->data_rate =48000;
   1930             }
   1931             config->interface_type = phymodInterfaceKR4;
   1932             break;
   1933         case 0x2a:
   1934             config->data_rate = 40000;
   1935             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1936                 (plldiv_r_val == 0x5)) {
   1937                 config->data_rate =42000;
   1938             }
   1939             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1940                 (plldiv_r_val == 0x6)) {
   1941                 config->data_rate =48000;
   1942             }
   1943             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1944                 (plldiv_r_val == 0xa)) {
   1945                 config->data_rate =42000;
   1946             }
   1947             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1948                 (plldiv_r_val == 0xd)) {
   1949                 config->data_rate =48000;
   1950             }
   1951             config->interface_type = phymodInterfaceKR4;
   1952             break;
   1953         case 0x2c:
   1954             config->data_rate = 42000;
   1955             config->interface_type = phymodInterfaceCR4;
   1956             break;
   1957         case 0x2d:
   1958             config->data_rate = 42000;
   1959             config->interface_type = phymodInterfaceKR4;
   1960             break;
   1961         case 0x2e:
   1962             config->data_rate = 42000;
   1963             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1964                 (plldiv_r_val == 0x4)) {
   1965                 config->data_rate =40000;
   1966             }
   1967             if ((config->ref_clock == phymodRefClk125Mhz) &&
   1968                 (plldiv_r_val == 0x7)) {
   1969                 config->data_rate =40000;
   1970             }
   1971             config->interface_type = phymodInterfaceKR4;
   1972             break;
   1973         case 0x30:
   1974             config->data_rate = 50000;
   1975             config->interface_type = phymodInterfaceCR2;
   1976             break;
   1977         case 0x31:
   1978             config->data_rate = 50000;
   1979             config->interface_type = phymodInterfaceKR2;
   1980             break;
   1981         case 0x32:
   1982             config->data_rate = 50000;
   1983             config->interface_type = phymodInterfaceKR2;
   1984             break;
   1985         case 0x34:
   1986             config->data_rate = 53000;
   1987             config->interface_type = phymodInterfaceCR2;
   1988             break;
   1989         case 0x35:
   1990             config->data_rate = 53000;
   1991             config->interface_type = phymodInterfaceKR2;
   1992             break;
   1993         case 0x36:
   1994             if ((config->ref_clock == phymodRefClk156Mhz) &&
   1995                 (plldiv_r_val == 0x7)) {
   1996                 config->data_rate = 50000;
   1997             } else {
   1998                 config->data_rate = 53000;
   1999             }
   2000             config->interface_type = phymodInterfaceKR2;
   2001             break;
   2002         case 0x38:
   2003             config->data_rate = 50000;
   2004             config->interface_type = phymodInterfaceCR4;
   2005             break;
   2006         case 0x39:
   2007             config->data_rate = 50000;
   2008             config->interface_type = phymodInterfaceKR4;
   2009             break;
   2010         case 0x3a:
   2011             config->data_rate = 50000;
   2012             config->interface_type = phymodInterfaceKR4;
   2013             break;
   2014         case 0x3c:
   2015             config->data_rate = 53000;
   2016             config->interface_type = phymodInterfaceCR4;
   2017             break;
   2018         case 0x3d:
   2019             config->data_rate = 53000;
   2020             config->interface_type = phymodInterfaceKR4;
   2021             break;
   2022         case 0x3e:
   2023             config->data_rate = 53000;
   2024             config->interface_type = phymodInterfaceKR4;
   2025             break;
   2026         case 0x40:
   2027             config->data_rate = 100000;
   2028             config->interface_type = phymodInterfaceCR4;
   2029             break;
   2030         case 0x41:
   2031             config->data_rate = 100000;
   2032             config->interface_type = phymodInterfaceKR4;
   2033             break;
   2034         case 0x42:
   2035             config->data_rate = 100000;
   2036             config->interface_type = phymodInterfaceKR4;
   2037             break;
   2038         case 0x44:
   2039             config->data_rate = 106000;
   2040             if (plldiv_r_val == 7) {
   2041                 config->data_rate = 100000;
   2042             }
   2043             config->interface_type = phymodInterfaceCR4;
   2044             break;
   2045         case 0x45:
   2046             config->data_rate = 106000;
   2047             if (plldiv_r_val == 7) {
   2048                 config->data_rate = 100000;
   2049             }
   2050             config->interface_type = phymodInterfaceKR4;
   2051             break;
   2052         case 0x46:
   2053             config->data_rate = 106000;
   2054             if (plldiv_r_val == 7) {
   2055                 config->data_rate = 100000;
   2056             }
   2057             config->interface_type = phymodInterfaceKR4;
   2058             break;
   2059         case 0x48:
   2060             config->data_rate = 20000;
   2061             config->interface_type = phymodInterfaceKR2;
   2062             break;
   2063         case 0x50:
   2064             config->data_rate = 25000;
   2065             config->interface_type = phymodInterfaceKR2;
   2066             break;
   2067         case 0x58:
   2068             config->data_rate = 1000;
   2069             config->interface_type = phymodInterfaceSGMII;
   2070             break;
   2071         case 0x60:
   2072             config->data_rate = 1000;
   2073             config->interface_type = phymodInterfaceSGMII;
   2074             break;
   2075         case 0x62:
   2076             config->data_rate = 10000;
   2077             config->interface_type = phymodInterfaceXAUI;
   2078             break;
   2079             /* 25G_CR_IEEE*/
   2080         case 0x70:
   2081             config->data_rate = 25000;
   2082             config->interface_type = phymodInterfaceCR;
   2083             break;
   2084             /* 25G_CRS_IEEE*/
   2085         case 0x71:
   2086             config->data_rate = 25000;
   2087             config->interface_type = phymodInterfaceCR;
   2088             break;
   2089             /* 25G_KR_IEEE*/
   2090         case 0x72:
   2091             config->data_rate = 25000;
   2092             config->interface_type = phymodInterfaceKR;
   2093             break;
   2094             /* 25G_KRS_IEEE*/
   2095         case 0x73:
   2096             config->data_rate = 25000;
   2097             config->interface_type = phymodInterfaceKR;
   2098             break;
   2099         default:
   2100             config->data_rate = 10000;
   2101             config->interface_type = phymodInterfaceKR;
   2102             break;
   2103         }
   2104     }
   2105     return PHYMOD_E_NONE;
   2106 }
   2107 
   2108  
   2109 
   2110 int tscf16_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags /*unused */, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config)
   2111 {
   2112     int speed_id;
   2113     phymod_firmware_lane_config_t firmware_lane_config;
   2114     phymod_phy_access_t pm_phy_copy;
   2115     int start_lane, num_lane;
   2116     phymod_autoneg_control_t an_control;
   2117     int an_complete=0;
   2118 
   2119     config->ref_clock = ref_clock;
   2120     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   2121     PHYMOD_MEMSET(&an_control, 0, sizeof(an_control));
   2122 
   2123     PHYMOD_IF_ERR_RETURN
   2124         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2125     PHYMOD_IF_ERR_RETURN
   2126         (tefmod16_speed_id_get(&phy->access, &speed_id));
   2127     PHYMOD_IF_ERR_RETURN
   2128         (_tscf16_speed_id_interface_config_get(phy, speed_id, config));
   2129 
   2130     /* read the current media type */
   2131     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   2132     PHYMOD_IF_ERR_RETURN
   2133         (tscf16_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   2134     if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) {
   2135         PHYMOD_INTF_MODES_FIBER_SET(config);
   2136     } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   2137         PHYMOD_INTF_MODES_FIBER_CLR(config);
   2138         PHYMOD_INTF_MODES_COPPER_SET(config);
   2139     } else {
   2140         PHYMOD_INTF_MODES_FIBER_CLR(config);
   2141         PHYMOD_INTF_MODES_BACKPLANE_SET(config);
   2142     }
   2143         /* next need to check for 40G 4 lanes mode, it's for XLAUI or KR4 */
   2144     if ((config->data_rate == 40000) && (!(firmware_lane_config.DfeOn)) &&
   2145          (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) {
   2146         if (num_lane == 2) {
   2147             config->interface_type = phymodInterfaceXLAUI2;
   2148         } else {
   2149             config->interface_type = phymodInterfaceXLAUI;
   2150         }
   2151     }
   2152 
   2153     PHYMOD_IF_ERR_RETURN
   2154         (tscf16_phy_autoneg_get(phy, &an_control, (uint32_t *) &an_complete));
   2155 
   2156     /* next need to check if we are CAUI4 100G mode */
   2157     if (!(an_control.enable && an_complete)) {
   2158         if ((config->data_rate == 100000) && (firmware_lane_config.LpDfeOn) &&
   2159             (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) {
   2160             config->interface_type = phymodInterfaceCAUI4;
   2161         }
   2162     }
   2163 
   2164     switch (config->interface_type) {
   2165       case phymodInterfaceSGMII:
   2166         if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   2167             config->interface_type = phymodInterface1000X;
   2168         } else {
   2169             config->interface_type = phymodInterfaceSGMII;
   2170         }
   2171         /*
   2172          * Speed ID 0x58 and 0x60 are interpreted as phymodInterfaceSGMII
   2173          * by _tscf_speed_id_interface_config_get(). This is correct when
   2174          * the port is in forced speed mode. However, when AN is enabled
   2175          * and completed the interface type cannot be SGMII because TSCF
   2176          * does not support CL37 & CL37bam. The correct interface type in
   2177          * this scenario should be phymodInterfaceKX.
   2178          */
   2179         if (an_control.enable && an_complete) {
   2180             config->interface_type = phymodInterfaceKX;
   2181         }
   2182         break;
   2183       case phymodInterfaceXFI:
   2184         if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2185             config->interface_type = phymodInterfaceCR;
   2186         } else {
   2187             config->interface_type = phymodInterfaceXFI;
   2188         }
   2189         break;
   2190     case phymodInterfaceKR2:
   2191         if (!an_control.enable) {
   2192             if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   2193                 config->interface_type = phymodInterfaceSR2;
   2194             } else {
   2195                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2196                     config->interface_type = phymodInterfaceCR2;
   2197                 } else {
   2198                     config->interface_type = phymodInterfaceKR2;
   2199                 }
   2200             }
   2201         }
   2202         break;
   2203       case phymodInterfaceKR4:
   2204         if (!an_control.enable) {
   2205             if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   2206                 config->interface_type = phymodInterfaceSR4;
   2207             } else {
   2208                 if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2209                     config->interface_type = phymodInterfaceCR4;
   2210                 } else {
   2211                     config->interface_type = phymodInterfaceKR4;
   2212                 }
   2213             }
   2214         }
   2215         break;
   2216       case phymodInterfaceKR:
   2217         {
   2218            if (!an_control.enable) {
   2219              if (config->data_rate == 10000) {
   2220                 if ( !PHYMOD_INTF_MODES_FIBER_GET(config)) {
   2221                     if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2222                         config->interface_type = phymodInterfaceCR;
   2223                     } else {
   2224                         config->interface_type = phymodInterfaceXFI;
   2225                     }
   2226                 } else {
   2227                     config->interface_type = phymodInterfaceSFI;
   2228                 }
   2229              } else {
   2230                 if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   2231                     config->interface_type = phymodInterfaceSR;
   2232                 } else {
   2233                     if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   2234                         config->interface_type = phymodInterfaceCR;
   2235                     } else {
   2236                         config->interface_type = phymodInterfaceKR;
   2237                     }
   2238                 }
   2239              }
   2240           } else {
   2241             config->interface_type = phymodInterfaceKR;
   2242           }
   2243           break;
   2244         }
   2245 
   2246       default:
   2247         break;
   2248     }
   2249 
   2250     return PHYMOD_E_NONE;
   2251 }
   2252 
   2253 int tscf16_phy_training_tx_fir_post_set(const phymod_phy_access_t* phy, uint8_t tx_post)
   2254 {
   2255     phymod_phy_access_t phy_copy;
   2256     int start_lane, num_lane, i;
   2257 
   2258     PHYMOD_IF_ERR_RETURN
   2259      (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2260     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2261 
   2262     /* lane reset */
   2263     for (i = 0; i < num_lane; i++) {
   2264          phy_copy.access.lane_mask = 1 << (start_lane + i);
   2265          PHYMOD_IF_ERR_RETURN
   2266          (falcon16_lane_soft_reset_release(&phy_copy.access, 0));
   2267     }
   2268 
   2269     /* set TXFIR Post value in uC RAM*/
   2270     PHYMOD_IF_ERR_RETURN
   2271      (falcon16_tsc_txfir_post_uc_set(&phy->access, tx_post));
   2272 
   2273     /* Release lane reset */
   2274     for (i = 0; i < num_lane; i++) {
   2275          phy_copy.access.lane_mask = 1 << (start_lane + i);
   2276          PHYMOD_IF_ERR_RETURN
   2277          (falcon16_lane_soft_reset_release(&phy_copy.access, 1));
   2278     }
   2279 
   2280     return PHYMOD_E_NONE;
   2281 
   2282 }
   2283 
   2284 int tscf16_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
   2285 {
   2286     struct falcon16_tsc_uc_lane_config_st serdes_firmware_config;
   2287     PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
   2288 
   2289     if (serdes_firmware_config.field.dfe_on == 0) {
   2290       PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72/CL93 with no DFE\n"));
   2291       return PHYMOD_E_CONFIG;
   2292     }
   2293 
   2294     PHYMOD_IF_ERR_RETURN
   2295         (tefmod16_clause72_control(&phy->access, cl72_en));
   2296         
   2297         
   2298     return PHYMOD_E_NONE;
   2299     
   2300 }
   2301 
   2302 int tscf16_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
   2303 {
   2304     PHYMOD_IF_ERR_RETURN
   2305         (falcon16_clause72_control_get(&phy->access, cl72_en));
   2306         
   2307     return PHYMOD_E_NONE;
   2308     
   2309 }
   2310 
   2311 
   2312 int tscf16_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
   2313 {
   2314     uint32_t local_status;
   2315 
   2316     PHYMOD_IF_ERR_RETURN
   2317         (falcon16_pmd_cl72_receiver_status(&phy->access, &local_status));
   2318     status->locked = local_status;
   2319     
   2320        
   2321     return PHYMOD_E_NONE;
   2322     
   2323 }
   2324 
   2325 
   2326 int tscf16_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability)
   2327 {
   2328          
   2329     tefmod16_an_adv_ability_t value;
   2330     int start_lane, num_lane;
   2331     phymod_phy_access_t phy_copy;
   2332     phymod_core_info_t core_info;
   2333 
   2334     /* next program the tx fir taps and driver current based on the input */
   2335     PHYMOD_IF_ERR_RETURN
   2336         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2337 
   2338     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2339     phy_copy.access.lane_mask = 0x1 << start_lane;
   2340 
   2341     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2342     PHYMOD_MEMSET(&core_info, 0x0, sizeof(core_info));
   2343 
   2344     PHYMOD_IF_ERR_RETURN
   2345         (tscf16_core_info_get((phymod_core_access_t *)phy, &core_info));
   2346 
   2347     value.an_cl72 = an_ability->an_cl72;
   2348 
   2349     /* Check FEC/CL74/CL91 support */
   2350     if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) {
   2351         value.an_fec = TEFMOD16_FEC_SUPRTD_NOT_REQSTD;
   2352     } else {
   2353         if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec))
   2354             value.an_fec = TEFMOD16_FEC_CL74_SUPRTD_REQSTD;
   2355         if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec))
   2356             value.an_fec |= TEFMOD16_FEC_CL91_SUPRTD_REQSTD;
   2357     }
   2358 
   2359     value.an_hg2 = an_ability->an_hg2;
   2360 
   2361     /* Check pause */
   2362     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) {
   2363         value.an_pause = TEFMOD16_SYMM_PAUSE;
   2364     }
   2365     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   2366         value.an_pause = TEFMOD16_ASYM_PAUSE;
   2367     }
   2368     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   2369         value.an_pause = TEFMOD16_ASYM_SYMM_PAUSE;
   2370     }
   2371 
   2372     /* Check cl73 ability */
   2373     if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)){
   2374         value.an_base_speed |= 1 << TEFMOD16_CL73_1GBASE_KX;
   2375     }
   2376     if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)) {
   2377         value.an_base_speed |= 1 << TEFMOD16_CL73_10GBASE_KR1;
   2378     }
   2379     if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) {
   2380         value.an_base_speed |= 1 << TEFMOD16_CL73_40GBASE_KR4;
   2381     }
   2382     if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) {
   2383         value.an_base_speed |= 1 << TEFMOD16_CL73_40GBASE_CR4;
   2384     }
   2385     if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) {
   2386         value.an_base_speed |= 1 << TEFMOD16_CL73_100GBASE_KR4;
   2387     }
   2388     if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) {
   2389         value.an_base_speed |= 1 << TEFMOD16_CL73_100GBASE_CR4;
   2390     }
   2391     if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap)) {
   2392         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_CR1;
   2393     }
   2394     if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap)) {
   2395         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_KR1;
   2396     }
   2397     if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap)) {
   2398         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_CRS1;
   2399     }
   2400     if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap)) {
   2401         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_KRS1;
   2402     }
   2403     /* check cl73 bam ability */
   2404     if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)) {
   2405         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_20GBASE_KR2;
   2406     }
   2407     if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)) {
   2408         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_20GBASE_CR2;
   2409     }
   2410     if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap)) {
   2411         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_40GBASE_KR2;
   2412     }
   2413     if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap)) {
   2414         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_40GBASE_CR2;
   2415     }
   2416     if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap)) {
   2417         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_KR2;
   2418     }
   2419     if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap)) {
   2420         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_CR2;
   2421     }
   2422     /* 50G 4-lane is not supported for TSCF16(TH2 and TD3) chips
   2423     if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap)) {
   2424         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_KR4;
   2425     }
   2426     if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap)) {
   2427         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_CR4;
   2428     }*/
   2429 
   2430     if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap)) {
   2431         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_20GBASE_KR1;
   2432     }
   2433     if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap)) {
   2434         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_20GBASE_CR1;
   2435     }
   2436     if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap)) {
   2437         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_25GBASE_KR1;
   2438     }
   2439     if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap)) {
   2440         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_25GBASE_CR1;
   2441     }
   2442 
   2443     PHYMOD_IF_ERR_RETURN
   2444         (tefmod16_autoneg_set(&phy_copy.access, &value));
   2445 
   2446     return PHYMOD_E_NONE;
   2447 
   2448 }
   2449 
   2450 int tscf16_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
   2451 {
   2452     tefmod16_an_adv_ability_t value;
   2453     phymod_phy_access_t phy_copy;
   2454     int start_lane, num_lane;
   2455 
   2456     PHYMOD_IF_ERR_RETURN
   2457         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2458     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2459     phy_copy.access.lane_mask = 0x1 << start_lane;
   2460     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2461 
   2462     PHYMOD_IF_ERR_RETURN
   2463         (tefmod16_autoneg_local_ability_get(&phy_copy.access, &value));
   2464 
   2465     an_ability_get_type->an_cl72 = value.an_cl72;
   2466     an_ability_get_type->an_hg2 = value.an_hg2;
   2467 
   2468     an_ability_get_type->an_fec = 0;
   2469     if (value.an_fec == TEFMOD16_FEC_SUPRTD_NOT_REQSTD) {
   2470         PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec);
   2471     } else {
   2472         if (value.an_fec == TEFMOD16_FEC_CL74_SUPRTD_REQSTD) {
   2473             PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   2474         }
   2475         if (value.an_fec == TEFMOD16_FEC_CL91_SUPRTD_REQSTD) {
   2476             PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec);
   2477         }
   2478     }
   2479 
   2480     if (value.an_pause == TEFMOD16_ASYM_PAUSE) {
   2481         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2482     } else if (value.an_pause == TEFMOD16_SYMM_PAUSE) {
   2483         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2484     } else if (value.an_pause == TEFMOD16_ASYM_SYMM_PAUSE) {
   2485         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2486         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2487     }
   2488 
   2489     /* First check cl73 base ability */
   2490     if (value.an_base_speed &  1 << TEFMOD16_CL73_100GBASE_CR4) {
   2491         PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap);
   2492     }
   2493     if (value.an_base_speed & 1 << TEFMOD16_CL73_100GBASE_KR4) {
   2494         PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap);
   2495     }
   2496     if (value.an_base_speed & 1 << TEFMOD16_CL73_40GBASE_CR4) {
   2497         PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   2498     }
   2499     if (value.an_base_speed & 1 << TEFMOD16_CL73_40GBASE_KR4) {
   2500         PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   2501     }
   2502     if (value.an_base_speed & 1 << TEFMOD16_CL73_10GBASE_KR1) {
   2503         PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   2504     }
   2505     if (value.an_base_speed & 1 << TEFMOD16_CL73_1GBASE_KX) {
   2506         PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   2507     }
   2508     if (value.an_base_speed & 1 << TEFMOD16_CL73_25GBASE_KR1) {
   2509         PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap);
   2510     }
   2511     if (value.an_base_speed & 1 << TEFMOD16_CL73_25GBASE_CR1) {
   2512         PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap);
   2513     }
   2514     if (value.an_base_speed & 1 << TEFMOD16_CL73_25GBASE_KRS1) {
   2515         PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap);
   2516     }
   2517     if (value.an_base_speed & 1 << TEFMOD16_CL73_25GBASE_CRS1) {
   2518         PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap);
   2519     }
   2520 
   2521     /* Next check cl73 bam ability */
   2522     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_20GBASE_KR2) {
   2523         PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2524     }
   2525     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_20GBASE_CR2) {
   2526         PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2527     }
   2528     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_40GBASE_KR2) {
   2529         PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2530     }
   2531     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_40GBASE_CR2) {
   2532         PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2533     }
   2534     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_50GBASE_KR2) {
   2535         PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2536     }
   2537     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_50GBASE_CR2) {
   2538         PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2539     }
   2540     /* 
   2541      * 50G 4-lane is not supported for TSCF16(TH2 and TD3) chips.
   2542     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_50GBASE_KR4) {
   2543         PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap);
   2544     }
   2545     if (value.an_bam_speed & 1 << TEFMOD16_CL73_BAM_50GBASE_CR4) {
   2546         PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap);
   2547     }
   2548     */
   2549     if (value.an_bam_speed1 & 1 << TEFMOD16_CL73_BAM_20GBASE_KR1) {
   2550         PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2551     }
   2552     if (value.an_bam_speed1 & 1 << TEFMOD16_CL73_BAM_20GBASE_CR1) {
   2553         PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2554     }
   2555     if (value.an_bam_speed1 & 1 << TEFMOD16_CL73_BAM_25GBASE_KR1) {
   2556         PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2557     }
   2558     if (value.an_bam_speed1 & 1 << TEFMOD16_CL73_BAM_25GBASE_CR1) {
   2559         PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2560     }
   2561 
   2562     return PHYMOD_E_NONE;
   2563 
   2564 }
   2565 
   2566 
   2567 int tscf16_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
   2568 {
   2569     tefmod16_an_adv_ability_t value;
   2570 
   2571     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   2572     PHYMOD_IF_ERR_RETURN
   2573        (tefmod16_autoneg_lp_status_get(&phy->access, &value));
   2574 
   2575       /* cl73 technology abilities A0 - D21 */
   2576     if (value.an_base_speed & ( 1 << TEFMOD16_CL73_1GBASE_KX)){
   2577         PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   2578     }
   2579 
   2580     /* cl73 technology abilities A2 - D23 */
   2581     if (value.an_base_speed & (1 << TEFMOD16_CL73_10GBASE_KR1)){
   2582         PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   2583     }
   2584     /* cl73 technology abilities A3 - D24 */
   2585     if (value.an_base_speed & ( 1 << TEFMOD16_CL73_40GBASE_KR4)){
   2586         PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   2587     }
   2588     /* cl73 technology abilities A4 - D25 */
   2589     if (value.an_base_speed & ( 1 << TEFMOD16_CL73_40GBASE_CR4)){
   2590         PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   2591     }
   2592     /* cl73 technology abilities A7 - D28 */
   2593     if (value.an_base_speed & (1 << TEFMOD16_CL73_100GBASE_KR4)){
   2594         PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap);
   2595     }
   2596     /* cl73 technology abilities A8 - D29 */
   2597     if (value.an_base_speed & (1 << TEFMOD16_CL73_100GBASE_CR4)){
   2598         PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap);
   2599     }
   2600     /* cl73 technology abilities A9 - D30 */
   2601     if (value.an_base_speed & (1 << TEFMOD16_CL73_25GBASE_KRS1)) {
   2602         PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap);
   2603     }
   2604     if (value.an_base_speed & (1 << TEFMOD16_CL73_25GBASE_CRS1)) {
   2605         PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap);
   2606     }
   2607     /* cl73 technology abilities A10 - D31 */
   2608     if (value.an_base_speed & (1 << TEFMOD16_CL73_25GBASE_KR1)) {
   2609         PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap);
   2610     }
   2611     if (value.an_base_speed & (1 << TEFMOD16_CL73_25GBASE_CR1)) {
   2612         PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap);
   2613     }
   2614 
   2615     /* FEC[F0:F1] is encoded in bits [D44:D47] */
   2616     an_ability_get_type->an_fec = 0;
   2617     if ((value.an_fec == TEFMOD16_FEC_SUPRTD_NOT_REQSTD)
   2618         || (value.an_fec == TEFMOD16_FEC_NOT_SUPRTD)) {
   2619         PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec);
   2620     } else {
   2621         if (value.an_fec & TEFMOD16_FEC_CL74_SUPRTD_REQSTD) {
   2622             PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   2623         }
   2624         if (value.an_fec & TEFMOD16_FEC_CL91_SUPRTD_REQSTD) {
   2625             PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec);
   2626         }
   2627     }
   2628 
   2629     /* advertise pause capabilities C[0:1] - D[10:11]*/
   2630     if (value.an_pause & TEFMOD16_SYMM_PAUSE) {
   2631         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   2632     }
   2633     if (value.an_pause & TEFMOD16_ASYM_PAUSE) {
   2634        PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   2635     }
   2636 
   2637     /* BAM73 OUI UP bit 16 */
   2638     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_20GBASE_KR2)) {
   2639         PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2640     }
   2641     /* BAM73 OUI UP bit 17 */
   2642     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_20GBASE_CR2)) {
   2643         PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2644     }
   2645     /* BAM73 OUI UP bit 18 */
   2646     if (value.an_bam_speed1 & (1 << TEFMOD16_CL73_BAM_20GBASE_KR1)) {
   2647         PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2648     }
   2649     /* BAM73 OUI UP bit 19 */
   2650     if (value.an_bam_speed1 & (1 << TEFMOD16_CL73_BAM_20GBASE_CR1)) {
   2651         PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2652     }
   2653     /* BAM73 OUI UP bit 20 */
   2654     if (value.an_bam_speed1 & (1 << TEFMOD16_CL73_BAM_25GBASE_KR1)) {
   2655         PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap);
   2656     }
   2657     /* BAM73 OUI UP bit 21 */
   2658     if (value.an_bam_speed1 & (1 << TEFMOD16_CL73_BAM_25GBASE_CR1)) {
   2659         PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap);
   2660     }
   2661     /* BAM73 OUI UP bit 22 */
   2662     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_40GBASE_KR2)) {
   2663         PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2664     }
   2665     /* BAM73 OUI UP bit 23 */
   2666     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_40GBASE_CR2)) {
   2667         PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2668     }
   2669     /* BAM73 OUI UP bit 24 */
   2670     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_50GBASE_KR2)) {
   2671         PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap);
   2672     }
   2673     /* BAM73 OUI UP bit 25 */
   2674     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_50GBASE_CR2)) {
   2675         PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap);
   2676     }
   2677     /* 50G 4-lane is not supported for TSCF16(TH2 and TD3) */
   2678     /* BAM73 OUI UP bit 32 */
   2679     /*
   2680     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_50GBASE_KR4)) {
   2681         PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap);
   2682     }*/
   2683 
   2684      /* BAM73 OUI UP bit 33 */
   2685     /*
   2686     if (value.an_bam_speed & (1 << TEFMOD16_CL73_BAM_50GBASE_CR4)) {
   2687         PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap);
   2688     }
   2689     */
   2690 
   2691     return PHYMOD_E_NONE;
   2692     
   2693 }
   2694 
   2695 
   2696 int tscf16_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
   2697 {
   2698     int num_lane_adv_encoded;
   2699     int start_lane, num_lane;
   2700     int i, an_enable_bitmap, single_port_mode = 0;
   2701     int do_lane_config_set, do_core_config_set;
   2702     phymod_firmware_lane_config_t firmware_lane_config;
   2703     phymod_firmware_core_config_t firmware_core_config_tmp;
   2704     tefmod16_an_control_t an_control;
   2705     phymod_phy_access_t phy_copy;
   2706 
   2707     /* TSCF16 doesn't support 10G KX4 parallel detection */
   2708     if(PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_GET(an)) {
   2709         return PHYMOD_E_UNAVAIL;
   2710     }
   2711 
   2712     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   2713     PHYMOD_MEMSET(&firmware_core_config_tmp, 0x0, sizeof(firmware_core_config_tmp));
   2714 
   2715     PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control));
   2716     PHYMOD_IF_ERR_RETURN
   2717         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2718 
   2719     if (PHYMOD_AN_F_ALLOW_PLL_CHANGE_GET(an) || (num_lane == 0x4)) {
   2720         single_port_mode = 1;
   2721     }
   2722 
   2723     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2724     phy_copy.access.lane_mask = 0x1 << start_lane;
   2725 
   2726     switch (an->num_lane_adv) {
   2727         case 1:
   2728             num_lane_adv_encoded = 0;
   2729             break;
   2730         case 2:
   2731             num_lane_adv_encoded = 1;
   2732             break;
   2733         case 4:
   2734             num_lane_adv_encoded = 2;
   2735             break;
   2736         case 10:
   2737             num_lane_adv_encoded = 3;
   2738             break;
   2739         default:
   2740             return PHYMOD_E_PARAM;
   2741     }
   2742     
   2743    /* first check if cl72 is allowed to change */
   2744     if (PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_GET(an)) {
   2745         an_control.cl72_config_allowed = 1;
   2746     } else {
   2747         an_control.cl72_config_allowed = 0;
   2748     }
   2749 
   2750     if (PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) {
   2751         an_control.pd_kx_en = 1 ;
   2752     }
   2753     an_control.num_lane_adv = num_lane_adv_encoded;
   2754     an_control.enable       = an->enable;
   2755     an_control.an_property_type = 0x0;   /* for now disable */
   2756     switch (an->an_mode) {
   2757     case phymod_AN_MODE_CL73:
   2758         an_control.an_type = TEFMOD16_AN_MODE_CL73;
   2759         break;
   2760     case phymod_AN_MODE_CL73BAM:
   2761         an_control.an_type = TEFMOD16_AN_MODE_CL73_BAM;
   2762         break;
   2763     case phymod_AN_MODE_MSA:
   2764         an_control.an_type = TEFMOD16_AN_MODE_MSA;
   2765         break;
   2766     case phymod_AN_MODE_CL73_MSA:
   2767         an_control.an_type = TEFMOD16_AN_MODE_CL73_MSA;
   2768         break;        
   2769     case phymod_AN_MODE_HPAM:
   2770         an_control.an_type = TEFMOD16_AN_MODE_HPAM;
   2771         break;
   2772     default:
   2773         an_control.an_type = TEFMOD16_AN_MODE_CL73;
   2774         break;
   2775     }
   2776 
   2777     tefmod16_disable_set(&phy->access);
   2778 
   2779     if (single_port_mode) {
   2780         PHYMOD_IF_ERR_RETURN
   2781             (tefmod16_set_an_single_port_mode(&phy->access, an->enable));
   2782     }
   2783     /* first check if any other lane has An on */
   2784     an_enable_bitmap = 0;
   2785     if (!an->enable) {
   2786         for (i = 0; i < 4; i++ ) {
   2787             phy_copy.access.lane_mask = 0x1 << i;
   2788             if (phy_copy.access.lane_mask & phy->access.lane_mask)  continue;
   2789             PHYMOD_IF_ERR_RETURN
   2790                 (tscf16_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   2791             if (firmware_lane_config.AnEnabled) {
   2792                 an_enable_bitmap |= 1 << i;
   2793             }
   2794         }
   2795 
   2796     }
   2797 
   2798     phy_copy.access.lane_mask = 0x1 << start_lane;
   2799 
   2800     /* make sure the firmware config is set to an enabled */
   2801     PHYMOD_IF_ERR_RETURN
   2802         (tscf16_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   2803     /* make sure the firmware config is set to an enabled */
   2804     PHYMOD_IF_ERR_RETURN
   2805         (tscf16_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp));
   2806     do_lane_config_set = 0;
   2807     do_core_config_set = 0;
   2808 
   2809     if (an->enable) {
   2810         if (firmware_lane_config.AnEnabled != 1) {
   2811           firmware_lane_config.AnEnabled = 1;
   2812           do_lane_config_set = 1;
   2813         }
   2814         if (firmware_lane_config.LaneConfigFromPCS != 1) {
   2815           firmware_lane_config.LaneConfigFromPCS = 1;
   2816           do_lane_config_set = 1;
   2817         }
   2818         if (firmware_core_config_tmp.CoreConfigFromPCS != 1) {
   2819           firmware_core_config_tmp.CoreConfigFromPCS = 1;
   2820           do_core_config_set = 1;
   2821         }
   2822         firmware_lane_config.Cl72RestTO = 0;
   2823     } else {
   2824         if (firmware_lane_config.AnEnabled != 0) {
   2825           firmware_lane_config.AnEnabled = 0;
   2826           do_lane_config_set = 1;
   2827         }
   2828         if (firmware_lane_config.LaneConfigFromPCS != 0) {
   2829           firmware_lane_config.LaneConfigFromPCS = 0;
   2830           do_lane_config_set = 1;
   2831         }
   2832         if (firmware_core_config_tmp.CoreConfigFromPCS != 0) {
   2833             if (!an_enable_bitmap) {
   2834                 firmware_core_config_tmp.CoreConfigFromPCS = 0;
   2835                 do_core_config_set = 1;
   2836             }
   2837         }
   2838         firmware_lane_config.Cl72RestTO = 1;
   2839     }
   2840 
   2841     if (do_core_config_set && single_port_mode) {
   2842         PHYMOD_IF_ERR_RETURN
   2843             (falcon16_tsc_core_dp_reset(&phy_copy.access, 1));
   2844         PHYMOD_USLEEP(1000);
   2845 
   2846         PHYMOD_IF_ERR_RETURN
   2847             (tscf16_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp));
   2848 
   2849         PHYMOD_IF_ERR_RETURN
   2850             (falcon16_tsc_core_dp_reset(&phy_copy.access, 0));
   2851     }
   2852 
   2853     /* To support 10G AN @25G VCO, need to override the speed id S_10G_KR1(0x1)*/
   2854     if (firmware_core_config_tmp.osr_2p5_available) {
   2855          PHYMOD_IF_ERR_RETURN
   2856             (tefmod16_override_10g_kr1_spd_intf(&phy->access, an->enable));
   2857     }
   2858 
   2859     if (do_lane_config_set) {
   2860         for (i = 0; i < num_lane; i++) {
   2861             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2862                 continue;
   2863             }
   2864             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2865             PHYMOD_IF_ERR_RETURN
   2866                 (falcon16_lane_soft_reset_release(&phy_copy.access, 0));
   2867         }
   2868         PHYMOD_USLEEP(1000);
   2869         for (i = 0; i < num_lane; i++) {
   2870             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2871                 continue;
   2872             }
   2873             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2874             PHYMOD_IF_ERR_RETURN
   2875                 (_tscf16_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config));
   2876         }
   2877 
   2878         for (i = 0; i < num_lane; i++) {
   2879             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2880                 continue;
   2881             }
   2882             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2883             PHYMOD_IF_ERR_RETURN
   2884                 (falcon16_lane_soft_reset_release(&phy_copy.access, 1));
   2885         }
   2886     }
   2887 
   2888     phy_copy.access.lane_mask = 0x1 << start_lane;
   2889 
   2890     if (an->enable && single_port_mode) {
   2891         PHYMOD_IF_ERR_RETURN
   2892             (tefmod16_master_port_num_set(&phy_copy.access, start_lane));
   2893     }
   2894 
   2895     PHYMOD_IF_ERR_RETURN
   2896         (tefmod16_autoneg_control(&phy_copy.access, &an_control));
   2897 
   2898     if (!an->enable) {
   2899         PHYMOD_IF_ERR_RETURN(tefmod16_enable_set(&phy->access));
   2900     }
   2901 
   2902     return PHYMOD_E_NONE;
   2903     
   2904 }
   2905 
   2906 int tscf16_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
   2907 {
   2908     tefmod16_an_control_t an_control;
   2909     phymod_phy_access_t phy_copy;
   2910     int start_lane, num_lane;
   2911     int an_complete = 0;
   2912 
   2913     /* next program the tx fir taps and driver current based on the input */
   2914     PHYMOD_IF_ERR_RETURN
   2915         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2916 
   2917     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2918     phy_copy.access.lane_mask = 0x1 << start_lane;
   2919 
   2920     PHYMOD_MEMSET(&an_control, 0x0,  sizeof(tefmod16_an_control_t));
   2921     PHYMOD_IF_ERR_RETURN
   2922         (tefmod16_autoneg_control_get(&phy_copy.access, &an_control, &an_complete));
   2923 
   2924     if (an_control.enable) {
   2925         an->enable = 1;
   2926         *an_done = an_complete;
   2927     } else {
   2928         an->enable = 0;
   2929     }
   2930 
   2931     if(an_control.pd_kx_en) {
   2932         PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an);
   2933     } else {
   2934         PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_CLR(an);
   2935     }
   2936 
   2937     switch (an_control.an_type) {
   2938     case TEFMOD16_AN_MODE_CL73:
   2939         an->an_mode = phymod_AN_MODE_CL73;
   2940         break;
   2941     case TEFMOD16_AN_MODE_CL73_BAM:
   2942         an->an_mode = phymod_AN_MODE_CL73BAM;
   2943         break;
   2944     case TEFMOD16_AN_MODE_MSA:
   2945         an->an_mode = phymod_AN_MODE_MSA;
   2946         break;
   2947     case TEFMOD16_AN_MODE_CL73_MSA:
   2948         an->an_mode = phymod_AN_MODE_CL73_MSA;
   2949         break;        
   2950     case TEFMOD16_AN_MODE_HPAM:
   2951         an->an_mode = phymod_AN_MODE_HPAM;
   2952         break;
   2953     default:
   2954         an->an_mode = phymod_AN_MODE_NONE;
   2955         break;
   2956     }
   2957 
   2958     return PHYMOD_E_NONE;
   2959 
   2960 }
   2961 
   2962 
   2963 int tscf16_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status)
   2964 {
   2965     int speed_id, an_en, an_done;
   2966     phymod_phy_inf_config_t config;
   2967     phymod_ref_clk_t ref_clock;
   2968     const phymod_access_t *pm_acc = &phy->access;
   2969 
   2970     PHYMOD_IF_ERR_RETURN
   2971        (tefmod16_autoneg_status_get(&phy->access, &an_en, &an_done));
   2972 
   2973     PHYMOD_IF_ERR_RETURN
   2974        (tefmod16_speed_id_get(&phy->access, &speed_id));
   2975 
   2976     PHYMOD_IF_ERR_RETURN
   2977        (tefmod16_refclk_get(pm_acc, &ref_clock));
   2978 
   2979     config.ref_clock = ref_clock;
   2980     PHYMOD_IF_ERR_RETURN
   2981        (_tscf16_speed_id_interface_config_get(phy, speed_id, &config));
   2982 
   2983     status->enabled   = an_en;
   2984     status->locked    = an_done;
   2985     status->data_rate = config.data_rate;
   2986     status->interface = config.interface_type;      
   2987             
   2988     return PHYMOD_E_NONE;
   2989 }
   2990 
   2991 
   2992 /* Core initialization
   2993  * 1. De-assert PMD core and PMD lane reset
   2994  * 2. Set heartbeat for comclk
   2995  * 3. Configure lane mapping
   2996  * 4. Micro code load and verify
   2997  * 5. De-assert micro reset
   2998  * 6. Wait for uc_active = 1
   2999  * 7. Initialize software information table for the micro
   3000  * 8. PLL configuration
   3001  * 9. Release core DP soft reset
   3002  */
   3003  STATIC
   3004 int _tscf16_core_init_post_firmware_load(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   3005 {
   3006     phymod_phy_access_t phy_access, phy_access_copy;
   3007     phymod_core_access_t  core_copy;
   3008 
   3009     TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core);
   3010     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   3011     core_copy.access.lane_mask = 0x1;
   3012 
   3013     phy_access_copy = phy_access;
   3014     phy_access_copy.access = core->access;
   3015     phy_access_copy.access.lane_mask = 0x1;
   3016     phy_access_copy.type = core->type;
   3017 
   3018     /* need to check if the ucode load is correct or not */
   3019 #ifndef TSCF16_PMD_CRC_UCODE_VERIFY
   3020     if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   3021         int rv;
   3022 
   3023         rv = falcon16_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &falcon16_ucode, falcon16_ucode_len);
   3024         if (rv != PHYMOD_E_NONE) {
   3025             PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask));
   3026             PHYMOD_IF_ERR_RETURN(rv);
   3027         }
   3028     }
   3029 #endif
   3030 
   3031     /* 5. De-assert micro reset */
   3032     PHYMOD_IF_ERR_RETURN
   3033         (falcon16_tsc_uc_reset(&core_copy.access, 0));
   3034 
   3035     /* 6. Wait for uc_active = 1 */
   3036     PHYMOD_IF_ERR_RETURN
   3037         (falcon16_tsc_wait_uc_active(&phy_access.access));
   3038 
   3039     /* pmd lane hard reset */
   3040     PHYMOD_IF_ERR_RETURN
   3041         (falcon16_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1));
   3042 
   3043     /* 7. Initialize software information table for the micro */
   3044     PHYMOD_IF_ERR_RETURN
   3045         (falcon16_tsc_init_falcon16_tsc_info(&core_copy.access));
   3046 
   3047     if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   3048 #ifdef TSCF16_PMD_CRC_UCODE_VERIFY
   3049         PHYMOD_IF_ERR_RETURN(
   3050             falcon16_tsc_start_ucode_crc_calc(&core_copy.access, falcon16_ucode_len));
   3051 #endif
   3052     }
   3053 
   3054     return PHYMOD_E_NONE;
   3055 }
   3056 
   3057 STATIC
   3058 int _tscf16_core_init_pass1(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   3059 {
   3060     int rv, lane;
   3061     phymod_phy_access_t phy_access;
   3062     phymod_core_access_t  core_copy;
   3063     uint32_t uc_enable = 0;
   3064 
   3065     TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core);
   3066     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   3067     core_copy.access.lane_mask = 0x1;
   3068 
   3069     /* 1. De-assert PMD core power and core data path reset */
   3070     PHYMOD_IF_ERR_RETURN
   3071         (tefmod16_pmd_reset_seq(&core_copy.access, core_status->pmd_active));
   3072 
   3073     /* De-assert PMD lane reset */
   3074     for (lane = 0; lane < TSCF16_NOF_LANES_IN_CORE; lane++) {
   3075      phy_access.access.lane_mask = 1 << lane;
   3076     PHYMOD_IF_ERR_RETURN
   3077         (tefmod16_pmd_x4_reset(&phy_access.access));
   3078     }
   3079 
   3080     /* 2. Set the heart beat, default is for 156.25M */
   3081     if (init_config->interface.ref_clock == phymodRefClk125Mhz) {
   3082         PHYMOD_IF_ERR_RETURN
   3083             (tefmod16_refclk_set(&core_copy.access, phymodRefClk125Mhz));
   3084     }
   3085 
   3086     /* 3. Configure lane mapping */
   3087     PHYMOD_IF_ERR_RETURN
   3088         (tscf16_core_lane_map_set(&core_copy, &init_config->lane_map));
   3089 
   3090     PHYMOD_IF_ERR_RETURN
   3091         (falcon16_uc_active_get(&phy_access.access, &uc_enable));
   3092     if (uc_enable) return PHYMOD_E_NONE;
   3093 
   3094 #ifndef FW_BCAST_DOWNLOAD
   3095     /* 4. Micro code load and verify */
   3096     rv = _tscf16_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader);
   3097     if (rv != PHYMOD_E_NONE) {
   3098         PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask));
   3099         PHYMOD_IF_ERR_RETURN(rv);
   3100     }
   3101 
   3102     PHYMOD_IF_ERR_RETURN(
   3103         _tscf16_core_init_post_firmware_load(core, init_config, core_status));
   3104 #else
   3105     if (!PHYMOD_CORE_INIT_F_SERDES_FW_BCAST_GET(init_config)) {
   3106         /* 4. Micro code load and verify */
   3107         rv = _tscf16_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader);
   3108         if (rv != PHYMOD_E_NONE) {
   3109             PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask));
   3110             PHYMOD_IF_ERR_RETURN(rv);
   3111         }
   3112 
   3113         PHYMOD_IF_ERR_RETURN(
   3114             _tscf16_core_init_post_firmware_load(core, init_config, core_status));
   3115     }
   3116 #endif
   3117 
   3118     return PHYMOD_E_NONE;
   3119 }
   3120 
   3121 
   3122 STATIC
   3123 int _tscf16_core_init_pass2(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   3124 {
   3125     phymod_phy_access_t phy_access, phy_access_copy;
   3126     phymod_core_access_t  core_copy;
   3127     enum falcon16_tsc_pll_refclk_enum refclk;
   3128     enum falcon16_tsc_pll_div_enum div;
   3129 #ifdef DEFAULT_OSR2P5_SET
   3130     int i;
   3131 #endif /* DEFAULT_OSR2P5_SET */
   3132     phymod_firmware_core_config_t firmware_core_config;
   3133 
   3134     PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config));
   3135 
   3136     TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core);
   3137     phy_access_copy = phy_access;
   3138     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   3139     core_copy.access.lane_mask = 0x1;
   3140     phy_access_copy = phy_access;
   3141     phy_access_copy.access = core->access;
   3142     phy_access_copy.access.lane_mask = 0x1;
   3143     phy_access_copy.type = core->type;
   3144 
   3145     refclk = FALCON16_TSC_PLL_REFCLK_156P25MHZ;
   3146     div = FALCON16_TSC_PLL_DIV_175;
   3147 
   3148     if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 
   3149 #ifndef TSCF16_PMD_CRC_UCODE
   3150         /* poll the ready bit in 10 ms */
   3151         enum srds_pmd_uc_cmd_enum cmd; 
   3152         cmd = CMD_CALC_CRC;
   3153         PHYMOD_IF_ERR_RETURN(
   3154             falcon16_tsc_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(&core_copy.access, 100, cmd));
   3155 #else
   3156         PHYMOD_IF_ERR_RETURN(
   3157             falcon16_tsc_check_ucode_crc(&core_copy.access, falcon16_ucode_crc, 200));
   3158 #endif
   3159     }
   3160 
   3161     /* release pmd lane hard reset */
   3162     PHYMOD_IF_ERR_RETURN(
   3163         falcon16_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0));
   3164 
   3165     /* set charge pump current */
   3166     PHYMOD_IF_ERR_RETURN
   3167         (falcon16_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll));
   3168 
   3169     /* 8. PLL configuration */
   3170     if (init_config->interface.ref_clock == phymodRefClk125Mhz) {
   3171         refclk = FALCON16_TSC_PLL_REFCLK_125MHZ;
   3172     } 
   3173 
   3174 #ifdef DEFAULT_OSR2P5_SET
   3175     if (PHYMOD_CORE_INIT_F_DEFAULT_OSR2P5_GET(init_config)) {
   3176         /* set all lanes at OSR2p5 by default */
   3177         for (i = 0; i < 4; i++) {
   3178             phy_access_copy.access.lane_mask = 1 << i;
   3179             PHYMOD_IF_ERR_RETURN
   3180                 (tefmod16_10g_clock_enable(&phy_access_copy.access, 1));
   3181             PHYMOD_IF_ERR_RETURN
   3182                 (tefmod16_pmd_osmode_set(&phy_access_copy.access, TEFMOD16_SPD_10000_XFI, phymodRefClk156Mhz, 0x80000000));
   3183         }
   3184         /* set back to original value */
   3185         phy_access_copy.access.lane_mask = 0x1;
   3186     }
   3187 #endif /* DEFAULT_OSR2P5_SET */
   3188 
   3189     /* reset core DP */
   3190     PHYMOD_IF_ERR_RETURN
   3191         (falcon16_tsc_core_dp_reset(&core_copy.access, 1));
   3192 
   3193     if (165 == init_config->interface.pll_divider_req) {
   3194         PHYMOD_IF_ERR_RETURN
   3195             (tscf16_phy_firmware_core_config_get(&phy_access_copy, &firmware_core_config));
   3196             firmware_core_config.osr_2p5_available = 1;
   3197         PHYMOD_IF_ERR_RETURN
   3198             (tscf16_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config));
   3199     }
   3200 
   3201     if (PHYMOD_CORE_INIT_F_CLK4PCS_3BIT_40T_GET(init_config)) {
   3202         PHYMOD_IF_ERR_RETURN
   3203             (falcon16_clk4pcs_3bit_40t_config(&core_copy.access));
   3204     }
   3205 
   3206     PHYMOD_IF_ERR_RETURN
   3207         (falcon16_tsc_configure_pll_refclk_div(&core_copy.access, refclk, div)); 
   3208 
   3209     /* select tsc_clk_credit */
   3210     PHYMOD_IF_ERR_RETURN
   3211         (tefmod16_default_init(&core->access)); 
   3212    
   3213     PHYMOD_IF_ERR_RETURN
   3214         (tefmod16_autoneg_timer_init(&core->access));
   3215 
   3216     PHYMOD_IF_ERR_RETURN
   3217         (tefmod16_master_port_num_set(&core->access, 0));
   3218 
   3219     PHYMOD_IF_ERR_RETURN
   3220         (tefmod16_cl74_chng_default (&core_copy.access));
   3221 
   3222     PHYMOD_IF_ERR_RETURN
   3223         (tefmod16_cl91_ecc_clear(&core_copy.access));
   3224 
   3225     /* 9. Release core DP soft reset */
   3226     PHYMOD_IF_ERR_RETURN
   3227         (falcon16_tsc_core_dp_reset(&core_copy.access, 0));
   3228 
   3229    return PHYMOD_E_NONE;
   3230 }
   3231 
   3232 #ifdef FW_BCAST_DOWNLOAD
   3233 STATIC
   3234 int _tscf16_core_init_bcast(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   3235 {
   3236     phymod_core_access_t core_copy;
   3237     phymod_phy_access_t phy_access;
   3238     uint32_t uc_enable = 0;
   3239 
   3240     TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core);
   3241     PHYMOD_IF_ERR_RETURN
   3242         (falcon16_uc_active_get(&phy_access.access, &uc_enable));
   3243     if (uc_enable) {
   3244         return PHYMOD_E_NONE;
   3245     }
   3246 
   3247     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   3248     core_copy.access.lane_mask = 0x1;
   3249 
   3250     if (PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_GET(init_config)) {
   3251         /* do nothing */
   3252     } else if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
   3253         PHYMOD_IF_ERR_RETURN(falcon16_tsc_ucode_init(&core_copy.access));
   3254         PHYMOD_IF_ERR_RETURN
   3255             (falcon16_pram_firmware_enable(&core_copy.access, 1, 0));
   3256     } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) {
   3257         PHYMOD_IF_ERR_RETURN(init_config->firmware_loader(core, falcon16_ucode_len, falcon16_ucode));
   3258     } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
   3259         PHYMOD_IF_ERR_RETURN
   3260             (falcon16_pram_firmware_enable(&core_copy.access, 0, 0));
   3261     } else if (PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)) {
   3262         PHYMOD_IF_ERR_RETURN(
   3263             _tscf16_core_init_post_firmware_load(core, init_config, core_status));
   3264     }
   3265 
   3266     return PHYMOD_E_NONE;
   3267 }
   3268 #endif
   3269 
   3270 int tscf16_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   3271 {
   3272 #ifdef FW_BCAST_DOWNLOAD
   3273     if (PHYMOD_CORE_INIT_F_SERDES_FW_BCAST_GET(init_config)
   3274         && !PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)
   3275         && !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) {
   3276         return _tscf16_core_init_bcast(core, init_config, core_status);
   3277     }
   3278 #endif
   3279 
   3280     if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   3281           !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   3282         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   3283         PHYMOD_IF_ERR_RETURN
   3284             (_tscf16_core_init_pass1(core, init_config, core_status));
   3285 
   3286         if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   3287             return PHYMOD_E_NONE;
   3288         }
   3289     }
   3290 
   3291     if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   3292           !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   3293         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) {
   3294         PHYMOD_IF_ERR_RETURN
   3295             (_tscf16_core_init_pass2(core, init_config, core_status));
   3296     }
   3297         
   3298     return PHYMOD_E_NONE;
   3299     
   3300 }
   3301 
   3302 
   3303 int tscf16_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* core_vco_pll_multiplier)
   3304 {
   3305     phymod_phy_access_t pm_phy_copy;
   3306     uint32_t pll_mode = 0;
   3307 
   3308     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   3309     pm_phy_copy.access.lane_mask = 0x1;
   3310 
   3311     PHYMOD_IF_ERR_RETURN
   3312         (falcon16_pll_mode_get(&pm_phy_copy.access, &pll_mode));
   3313     _tscf16_pll_multiplier_get(pll_mode, core_vco_pll_multiplier);
   3314 
   3315     return PHYMOD_E_NONE;
   3316     
   3317 }
   3318 
   3319 
   3320 int tscf16_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
   3321 {
   3322     int pll_restart = 0;
   3323     const phymod_access_t *pm_acc = &phy->access;
   3324     phymod_phy_access_t pm_phy_copy;
   3325     int start_lane, num_lane, i;
   3326     int lane_bkup;
   3327     phymod_polarity_t tmp_pol;
   3328     phymod_firmware_lane_config_t firmware_lane_config;
   3329 
   3330     PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol));
   3331     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   3332     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   3333 
   3334     PHYMOD_IF_ERR_RETURN
   3335         (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane));
   3336     /* per lane based reset release */
   3337     PHYMOD_IF_ERR_RETURN
   3338         (tefmod16_pmd_x4_reset(pm_acc));
   3339 
   3340     lane_bkup = pm_phy_copy.access.lane_mask;
   3341     for (i = 0; i < num_lane; i++) {
   3342         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   3343         PHYMOD_IF_ERR_RETURN
   3344             (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 1));
   3345     }
   3346     pm_phy_copy.access.lane_mask = lane_bkup;
   3347  
   3348     /* clearing all the lane config */
   3349     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   3350 
   3351     /* program the rx/tx polarity */
   3352     for (i = 0; i < num_lane; i++) {
   3353         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3354         tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1;
   3355         tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1;
   3356         PHYMOD_IF_ERR_RETURN
   3357             (tscf16_phy_polarity_set(&pm_phy_copy, &tmp_pol));
   3358     }
   3359 
   3360     for (i = 0; i < num_lane; i++) {
   3361         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3362         /* set tx parameters */
   3363         PHYMOD_IF_ERR_RETURN
   3364             (tscf16_phy_tx_set(&pm_phy_copy, &init_config->tx[i]));
   3365     }
   3366 
   3367     for (i = 0; i < num_lane; i++) {
   3368         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3369         PHYMOD_IF_ERR_RETURN
   3370              (_tscf16_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   3371     }
   3372 
   3373     /* next check if pcs-bypass mode  */
   3374     if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) {
   3375         PHYMOD_IF_ERR_RETURN
   3376             (falcon16_pmd_tx_disable_pin_dis_set(&phy->access, 1));
   3377         PHYMOD_IF_ERR_RETURN
   3378           (tefmod16_init_pcs_ilkn(&phy->access));
   3379     }
   3380 
   3381     PHYMOD_IF_ERR_RETURN
   3382         (tefmod16_update_port_mode(pm_acc, &pll_restart));
   3383 
   3384     PHYMOD_IF_ERR_RETURN
   3385         (tefmod16_rx_lane_control_set(pm_acc, 1));
   3386     PHYMOD_IF_ERR_RETURN
   3387         (tefmod16_tx_lane_control_set(pm_acc, TEFMOD16_TX_LANE_RESET_TRAFFIC_ENABLE));         /* TX_LANE_CONTROL */
   3388 
   3389     PHYMOD_IF_ERR_RETURN
   3390         (tefmod16_25g_rsfec_am_init(pm_acc));
   3391 
   3392     /* Enable FEC error bypass indication */
   3393     PHYMOD_IF_ERR_RETURN
   3394         (tefmod16_fec_bypass_indication_set(pm_acc, 1));
   3395 
   3396     return PHYMOD_E_NONE;
   3397     
   3398 }
   3399 
   3400 
   3401 int tscf16_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
   3402 {
   3403     int i;
   3404     int start_lane, num_lane;
   3405     int rv = PHYMOD_E_NONE;
   3406     uint32_t cl72_en;
   3407     phymod_phy_access_t phy_copy;
   3408 
   3409     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3410 
   3411     /* next figure out the lane num and start_lane based on the input */
   3412     PHYMOD_IF_ERR_RETURN
   3413         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3414 
   3415     switch (loopback) {
   3416     case phymodLoopbackGlobal :
   3417         PHYMOD_IF_ERR_RETURN
   3418             (tscf16_phy_cl72_get(phy, &cl72_en));
   3419         if (cl72_en == 1) {
   3420              PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n",  phy_copy.access.addr, start_lane));
   3421              break;
   3422         }
   3423         PHYMOD_IF_ERR_RETURN(tefmod16_tx_loopback_control(&phy->access, enable, start_lane, num_lane));
   3424         break;
   3425     case phymodLoopbackGlobalPMD :
   3426         PHYMOD_IF_ERR_RETURN
   3427             (tscf16_phy_cl72_get(phy, &cl72_en));
   3428         if (cl72_en == 1) {
   3429              PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pmd gloop not supported with cl72 enabled\n",  phy_copy.access.addr, start_lane));
   3430              break;
   3431         }
   3432             for (i = 0; i < num_lane; i++) {
   3433             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3434             PHYMOD_IF_ERR_RETURN(tefmod16_tx_squelch_set(&phy_copy.access, enable));
   3435             PHYMOD_IF_ERR_RETURN(falcon16_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable));
   3436             PHYMOD_IF_ERR_RETURN(falcon16_pmd_force_signal_detect(&phy_copy.access, (int) enable));
   3437             PHYMOD_IF_ERR_RETURN(tefmod16_rx_lane_control_set(&phy->access, 1));
   3438         }
   3439         break;
   3440     case phymodLoopbackRemotePMD :
   3441         PHYMOD_IF_ERR_RETURN(falcon16_tsc_rmt_lpbk(&phy->access, (uint8_t)enable));
   3442         break;
   3443     case phymodLoopbackRemotePCS :
   3444         /* PHYMOD_IF_ERR_RETURN(tefmod16_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */
   3445         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   3446                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   3447         break;
   3448     default :
   3449         break;
   3450     }
   3451 
   3452     return rv;
   3453 }
   3454 
   3455 int tscf16_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   3456 {
   3457     uint32_t enable_core;
   3458     int start_lane, num_lane;
   3459 
   3460     *enable = 0;
   3461 
   3462     /* next figure out the lane num and start_lane based on the input */
   3463     PHYMOD_IF_ERR_RETURN
   3464         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3465 
   3466     switch (loopback) {
   3467     case phymodLoopbackGlobal :
   3468         PHYMOD_IF_ERR_RETURN(tefmod16_tx_loopback_get(&phy->access, &enable_core));
   3469         *enable = (enable_core >> start_lane) & 0x1;
   3470         break;
   3471     case phymodLoopbackGlobalPMD :
   3472         PHYMOD_IF_ERR_RETURN(falcon16_tsc_dig_lpbk_get(&phy->access, enable));
   3473         break;
   3474     case phymodLoopbackRemotePMD :
   3475         PHYMOD_IF_ERR_RETURN(falcon16_tsc_rmt_lpbk_get(&phy->access, enable));
   3476         break;
   3477     case phymodLoopbackRemotePCS :
   3478         /* PHYMOD_IF_ERR_RETURN(tefmod16_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */
   3479         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   3480                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   3481         break;
   3482     default :
   3483         break;
   3484     }
   3485         
   3486     return PHYMOD_E_NONE;
   3487     
   3488 }
   3489 
   3490 
   3491 int tscf16_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
   3492 {
   3493     PHYMOD_IF_ERR_RETURN(tefmod16_pmd_lock_get(&phy->access, rx_pmd_locked)); 
   3494         
   3495     return PHYMOD_E_NONE;
   3496     
   3497 }
   3498 
   3499 
   3500 int tscf16_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
   3501 {
   3502     if (1) {
   3503         PHYMOD_IF_ERR_RETURN(tefmod16_get_pcs_latched_link_status(&phy->access, link_status));
   3504     } else {
   3505         PHYMOD_IF_ERR_RETURN(tefmod16_get_pcs_link_status(&phy->access, link_status));
   3506     }
   3507     
   3508     return PHYMOD_E_NONE;
   3509     
   3510 }
   3511 
   3512 
   3513 int tscf16_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config)
   3514 {
   3515         
   3516     return PHYMOD_E_UNAVAIL;    
   3517     
   3518 }
   3519 
   3520 int tscf16_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config)
   3521 {
   3522     return PHYMOD_E_UNAVAIL;    
   3523 
   3524 }
   3525 
   3526 
   3527 int tscf16_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val)
   3528 {
   3529     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val));    
   3530         
   3531     return PHYMOD_E_NONE;
   3532     
   3533 }
   3534 
   3535 
   3536 int tscf16_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
   3537 {
   3538     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val));
   3539         
   3540     return PHYMOD_E_NONE;
   3541     
   3542 }
   3543 
   3544 
   3545 int tscf16_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value)
   3546 {
   3547     int start_lane, num_lane;
   3548     phymod_phy_access_t phy_copy;
   3549     int hz_l, hz_r, vt_u, vt_d;
   3550 
   3551 
   3552     /* first get the start_lane */
   3553     PHYMOD_IF_ERR_RETURN
   3554         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3555 
   3556     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3557     phy_copy.access.lane_mask = 0x1 << start_lane;
   3558 
   3559     PHYMOD_IF_ERR_RETURN
   3560         (falcon16_tsc_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d));
   3561 
   3562     switch (eye_margin_mode) {
   3563     case phymod_eye_marign_HZ_L:
   3564         *value = hz_l;
   3565         break;
   3566     case phymod_eye_marign_HZ_R:
   3567         *value = hz_r;
   3568         break;
   3569     case phymod_eye_marign_VT_U:
   3570         *value = vt_u;
   3571         break;
   3572     case phymod_eye_marign_VT_D:
   3573         *value = vt_d;
   3574         break;
   3575     default:
   3576         *value = 0;
   3577         break;
   3578     }
   3579 
   3580     return PHYMOD_E_NONE;
   3581 }
   3582 
   3583 
   3584 int tscf16_phy_rescal_set(const phymod_phy_access_t* phy, uint32_t enable, uint32_t value)
   3585 {
   3586     PHYMOD_IF_ERR_RETURN(falcon16_rescal_val_set(&phy->access, enable, value));
   3587 
   3588     return PHYMOD_E_NONE;
   3589 
   3590 }
   3591 
   3592 
   3593 int tscf16_phy_rescal_get(const phymod_phy_access_t* phy, uint32_t* value)
   3594 {
   3595     PHYMOD_IF_ERR_RETURN(falcon16_rescal_val_get(&phy->access, value));
   3596 
   3597     return PHYMOD_E_NONE;
   3598 
   3599 }
   3600 
   3601 int tscf16_phy_rx_signal_detect_get(const phymod_phy_access_t* phy,  uint32_t* value)
   3602 {
   3603     uint32_t local_rx_signal_det;
   3604     int start_lane, num_lane, i;
   3605 
   3606     *value = 1;
   3607 
   3608     PHYMOD_IF_ERR_RETURN
   3609         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3610 
   3611     for (i = 0; i < num_lane; i++) {
   3612         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   3613             continue;
   3614         }
   3615         PHYMOD_IF_ERR_RETURN
   3616             (falcon16_tsc_signal_detect(&phy->access, &local_rx_signal_det));
   3617         *value = *value & local_rx_signal_det;
   3618     }
   3619 
   3620     return PHYMOD_E_NONE;
   3621 }
   3622 
   3623 int tscf16_phy_sw_an_advert_set(const phymod_phy_access_t* phy,
   3624                               const phymod_autoneg_ability_t* an_ability,
   3625                               phymod_sw_an_ctxt_t* an_ctxt)
   3626 {
   3627     tefmod16_an_adv_ability_t value;
   3628     int start_lane, num_lane;
   3629     phymod_phy_access_t phy_copy;
   3630     phymod_core_info_t core_info;
   3631 
   3632     /* next program the tx fir taps and driver current based on the input */
   3633     PHYMOD_IF_ERR_RETURN
   3634         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3635 
   3636     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3637     phy_copy.access.lane_mask = 0x1 << start_lane;
   3638 
   3639     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   3640     PHYMOD_MEMSET(&core_info, 0x0, sizeof(core_info));
   3641 
   3642     PHYMOD_IF_ERR_RETURN
   3643         (tscf16_core_info_get((phymod_core_access_t *)phy, &core_info));
   3644 
   3645     value.an_cl72 = an_ability->an_cl72;
   3646 
   3647     if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) {
   3648         value.an_fec = TEFMOD16_FEC_SUPRTD_NOT_REQSTD;
   3649     } else {
   3650         if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec))
   3651             value.an_fec = TEFMOD16_FEC_CL74_SUPRTD_REQSTD;
   3652         if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec))
   3653             value.an_fec |= TEFMOD16_FEC_CL91_SUPRTD_REQSTD;
   3654     }
   3655 
   3656     /* value.an_fec = an_ability->an_fec; */
   3657     value.an_hg2 = an_ability->an_hg2;
   3658 
   3659     /* next check pause */
   3660     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) {
   3661         value.an_pause = TEFMOD16_SYMM_PAUSE;
   3662     }
   3663     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   3664         value.an_pause = TEFMOD16_ASYM_PAUSE;
   3665     }
   3666     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   3667         value.an_pause = TEFMOD16_ASYM_SYMM_PAUSE;
   3668     }
   3669 
   3670     /* check cl73 and cl73 bam ability */
   3671     if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap))
   3672         value.an_base_speed |= 1 << TEFMOD16_CL73_1GBASE_KX;
   3673     if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap))
   3674         value.an_base_speed |= 1 << TEFMOD16_CL73_10GBASE_KR1;
   3675     if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap))
   3676         value.an_base_speed |= 1 << TEFMOD16_CL73_40GBASE_KR4;
   3677     if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap))
   3678         value.an_base_speed |= 1 << TEFMOD16_CL73_40GBASE_CR4;
   3679     if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) {
   3680         if (core_info.core_version == phymodCoreVersionTscfA0) {
   3681             value.an_fec = TEFMOD16_FEC_NOT_SUPRTD;
   3682         }
   3683         value.an_base_speed |= 1 << TEFMOD16_CL73_100GBASE_KR4;
   3684     }
   3685     if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) {
   3686         if (core_info.core_version == phymodCoreVersionTscfA0) {
   3687             value.an_fec = TEFMOD16_FEC_NOT_SUPRTD;
   3688         }
   3689         value.an_base_speed |= 1 << TEFMOD16_CL73_100GBASE_CR4;
   3690     }
   3691     if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap))
   3692         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_CR1;
   3693     if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap))
   3694         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_KR1;
   3695     if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap))
   3696         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_CRS1;
   3697     if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap))
   3698         value.an_base_speed |= 1 << TEFMOD16_CL73_25GBASE_KRS1;
   3699 
   3700     /* check cl73 bam ability */
   3701     if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap))
   3702         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_20GBASE_KR2;
   3703     if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap))
   3704         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_20GBASE_CR2;
   3705     if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap))
   3706         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_40GBASE_KR2;
   3707     if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap))
   3708         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_40GBASE_CR2;
   3709     if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap))
   3710         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_KR2;
   3711     if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap))
   3712         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_CR2;
   3713     /*
   3714      * 50G 4-lane is not supported for TSCF16(TH2 and TD3) chips
   3715     if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap))
   3716         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_KR4;
   3717     if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap))
   3718         value.an_bam_speed |= 1 << TEFMOD16_CL73_BAM_50GBASE_CR4;
   3719     */
   3720     if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap))
   3721         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_20GBASE_KR1;
   3722     if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap))
   3723         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_20GBASE_CR1;
   3724     if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap))
   3725         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_25GBASE_KR1;
   3726     if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap))
   3727         value.an_bam_speed1 |= 1 << TEFMOD16_CL73_BAM_25GBASE_CR1;
   3728 
   3729 
   3730     PHYMOD_IF_ERR_RETURN
   3731         (tefmod16_sw_an_advert_set(&phy_copy.access, &value, an_ctxt));
   3732     return PHYMOD_E_NONE;
   3733 
   3734 }
   3735 
   3736 static int _tscf16_sw_an_pmd_lane_cfg_set(phymod_phy_access_t* phy, int enable)
   3737 {
   3738     int start_lane, num_lane, i=0;
   3739     phymod_phy_access_t phy_copy;
   3740     phymod_firmware_lane_config_t firmware_lane_config;
   3741 
   3742 
   3743     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   3744 
   3745     PHYMOD_IF_ERR_RETURN
   3746         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   3747 
   3748 
   3749     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   3750     phy_copy.access.lane_mask = 0x1 << start_lane;
   3751 
   3752    /* make sure the firmware config is set to an eenabled */
   3753     PHYMOD_IF_ERR_RETURN
   3754         (tscf16_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   3755     if (enable) {
   3756         firmware_lane_config.AnEnabled = 1;
   3757         firmware_lane_config.LaneConfigFromPCS = 1;
   3758     } else {
   3759         firmware_lane_config.AnEnabled = 0;
   3760         firmware_lane_config.LaneConfigFromPCS = 0;
   3761     }
   3762 
   3763     for (i = 0; i < num_lane; i++) {
   3764         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   3765             continue;
   3766         }
   3767         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3768         PHYMOD_IF_ERR_RETURN
   3769             (falcon16_lane_soft_reset_release(&phy_copy.access, 0));
   3770     }
   3771 
   3772     PHYMOD_USLEEP(1000);
   3773     for (i = 0; i < num_lane; i++) {
   3774         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   3775             continue;
   3776         }
   3777         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3778         PHYMOD_IF_ERR_RETURN
   3779             (_tscf16_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config));
   3780     }
   3781 
   3782     for (i = 0; i < num_lane; i++) {
   3783         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   3784             continue;
   3785         }
   3786         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   3787         PHYMOD_IF_ERR_RETURN
   3788             (falcon16_lane_soft_reset_release(&phy_copy.access, 1));
   3789     }
   3790 
   3791     return PHYMOD_E_NONE;
   3792 }
   3793 
   3794 
   3795 static int
   3796 _resolve_speed(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t *an_ctxt)
   3797 {
   3798     uint16_t common_tech_ability = 0;
   3799     uint16_t hcd_speed = HCD_SPEED_ID_UNDEFINED;
   3800     uint8_t is_krs = 0;
   3801     uint8_t cl74_fec = 0, cl91_fec = 0, cl74_25gkrs_fec = 0;
   3802     uint32_t   msa_code_13_23 = 0, msa_code_2_12 = 0, msa_code_0_1 =0;
   3803     uint8_t ld_cl91_sup, ld_cl91_req, rd_cl91_sup, rd_cl91_req;
   3804     uint8_t ld_cl74_sup, ld_cl74_req, rd_cl74_sup, rd_cl74_req;
   3805     uint8_t rd_base_cl74_fec_req, rd_base_cl74_fec_sup, ld_base_cl74_fec_req, ld_base_cl74_fec_sup;
   3806     tefmod16_fec_type_t fec_type;
   3807 
   3808     /* Resolve base page tech ability */
   3809     if ((an_ctxt->rx_pages.base_page.page_1 >> AN_BASE1_PAGE_ABILITY_OFFSET) &
   3810         AN_BASE1_PAGE_ABILITY_MASK) {
   3811         common_tech_ability = (((an_ctxt->rx_pages.base_page.page_1) &
   3812                           (an_ctxt->tx_pages.base_page.page_1)) &
   3813                           (AN_BASE1_PAGE_ABILITY_MASK << AN_BASE1_PAGE_ABILITY_OFFSET));
   3814         if ((common_tech_ability >> AN_BASE_TECH_ABILITY_100GKR4_OFFSET) & AN_BASE_TECH_ABILITY_100GKR4_MASK) {
   3815             hcd_speed = TEFMOD16_100G_KR4_SPD_IF;
   3816         } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_100GCR4_OFFSET) & AN_BASE_TECH_ABILITY_100GCR4_MASK) {
   3817             hcd_speed = TEFMOD16_100G_CR4_SPD_IF;
   3818         } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_25GKR_OFFSET) & AN_BASE_TECH_ABILITY_25GKR_MASK) {
   3819             /* speed is 25G KR */
   3820             hcd_speed = TEFMOD16_25G_KR_IEEE_SPD_IF; /* speed ID for 25G KR */
   3821         } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_25GKRS_OFFSET) & AN_BASE_TECH_ABILITY_25GKRS_MASK) {
   3822             hcd_speed = TEFMOD16_25G_KRS_IEEE_SPD_IF; /* IEEE AN does not differntiate between KR and CR, KRS and CRS */
   3823             is_krs = 1;
   3824         } else {
   3825             /* TH SW AN will be used only for IEEE 100/25G and MSA
   3826              * NO need to look for 10G and 40G
   3827              */
   3828              hcd_speed = HCD_SPEED_ID_UNDEFINED;
   3829         }
   3830 
   3831         /* Resolve base page FEC ability */
   3832         if (an_ctxt->rx_pages.base_page.page_2) {
   3833             /* always advertise cl91/74 supported mask */
   3834             cl91_fec =  (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL91_ABILITY_REQ_OFFSET) &
   3835                     AN_BASE_CL91_ABILITY_REQ_MASK) |
   3836                     ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL91_ABILITY_REQ_OFFSET) &
   3837                     AN_BASE_CL91_ABILITY_REQ_MASK));
   3838 
   3839             cl74_25gkrs_fec = (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_25GKRS_REQ_OFFSET) &
   3840                           AN_BASE_CL74_25GKRS_REQ_MASK) |
   3841                           ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_25GKRS_REQ_OFFSET) &
   3842                           AN_BASE_CL74_25GKRS_REQ_MASK));
   3843 
   3844             cl74_fec = (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) &
   3845                     AN_BASE_CL74_ABILITY_REQ_MASK) |
   3846                     ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) &
   3847                     AN_BASE_CL74_ABILITY_REQ_MASK));
   3848         }
   3849 
   3850     }
   3851 
   3852     if (hcd_speed == HCD_SPEED_ID_UNDEFINED) {
   3853         /* NO IEEE Common speed found look for MSA Speeds */
   3854         msa_code_13_23 = ((an_ctxt->rx_pages.msg_page.page_1 >> AN_MSG_PAGE1_OUI_13to23_OFFSET) &
   3855                           AN_MSG_PAGE1_OUI_13to23_MASK);
   3856         msa_code_2_12 = ((an_ctxt->rx_pages.msg_page.page_2 >> AN_MSG_PAGE2_OUI_2to12_OFFSET) &
   3857                           AN_MSG_PAGE2_OUI_2to12_MASK);
   3858         msa_code_0_1  = ((an_ctxt->tx_pages.ufmt_page.page_0 >> AN_UF_PAGE0_OUI_OFFSET) &
   3859                           AN_UF_PAGE0_OUI_MASK);
   3860 
   3861         if ((msa_code_13_23 == MSA_OUI_13to23) &&
   3862             (msa_code_2_12  == MSA_OUT_2to12) &&
   3863             (msa_code_0_1   == MSA_OUI_0to1)) {
   3864 
   3865             /* MSA PAGE FOUND. Now parse the MSA pages */
   3866             common_tech_ability = (an_ctxt->tx_pages.ufmt_page.page_1 & an_ctxt->rx_pages.ufmt_page.page_1);
   3867 
   3868             if ((common_tech_ability >> AN_UF_PAGE1_50G_KR2_ABILITY_OFFSET) &
   3869                 AN_UF_PAGE1_50G_KR2_ABILITY_MASK) {
   3870                 hcd_speed = TEFMOD16_50G_KR2_SPD_IF;
   3871             } else if ((common_tech_ability >> AN_UF_PAGE1_50G_CR2_ABILITY_OFFSET) &
   3872                         AN_UF_PAGE1_50G_CR2_ABILITY_MASK) {
   3873                 hcd_speed = TEFMOD16_50G_CR2_SPD_IF;
   3874             } else if ((common_tech_ability >> AN_UF_PAGE1_25G_KR1_ABILITY_OFFSET) &
   3875                         AN_UF_PAGE1_25G_KR1_ABILITY_MASK) {
   3876                 hcd_speed = TEFMOD16_25G_KR_SPD_IF;
   3877             } else if ((common_tech_ability >> AN_UF_PAGE1_25G_CR1_ABILITY_OFFSET) &
   3878                         AN_UF_PAGE1_25G_CR1_ABILITY_MASK) {
   3879                 hcd_speed = TEFMOD16_25G_CR_SPD_IF;
   3880             } else {
   3881                 /* Resolution error */
   3882                 return PHYMOD_E_CONFIG;
   3883             }
   3884 
   3885             /* resolve FEC */
   3886             if (an_ctxt->tx_pages.ufmt_page.page_2 & an_ctxt->rx_pages.ufmt_page.page_2) {
   3887                 ld_cl91_sup = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_SUPPORT_OFFSET) &
   3888                                 AN_UF_PAGE2_CL91_SUPPORT_MASK);
   3889                 ld_cl91_req = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_REQ_OFFSET) &
   3890                                 AN_UF_PAGE2_CL91_REQ_MASK);
   3891                 ld_cl74_sup = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_SUPPORT_OFFSET) &
   3892                                 AN_UF_PAGE2_CL74_SUPPORT_MASK);
   3893                 ld_cl74_req = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_REQ_OFFSET) &
   3894                                 AN_UF_PAGE2_CL74_REQ_MASK);
   3895 
   3896                 rd_cl91_sup = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_SUPPORT_OFFSET) &
   3897                                 AN_UF_PAGE2_CL91_SUPPORT_MASK);
   3898                 rd_cl91_req = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_REQ_OFFSET) &
   3899                                 AN_UF_PAGE2_CL91_REQ_MASK);
   3900                 rd_cl74_sup = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_SUPPORT_OFFSET) &
   3901                                 AN_UF_PAGE2_CL74_SUPPORT_MASK);
   3902                 rd_cl74_req = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_REQ_OFFSET) &
   3903                                 AN_UF_PAGE2_CL74_REQ_MASK);
   3904 
   3905                 rd_base_cl74_fec_req = ((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) &
   3906                                         AN_BASE_CL74_ABILITY_REQ_MASK);
   3907                 ld_base_cl74_fec_req = ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) &
   3908                                         AN_BASE_CL74_ABILITY_REQ_MASK);
   3909                 rd_base_cl74_fec_sup = ((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_SUP_OFFSET) &
   3910                                         AN_BASE_CL74_ABILITY_SUP_MASK);
   3911                 ld_base_cl74_fec_sup = ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_SUP_OFFSET) &
   3912                                         AN_BASE_CL74_ABILITY_SUP_MASK);
   3913 
   3914                 if ((ld_cl91_req || rd_cl91_req) &&
   3915                     (ld_cl91_sup && rd_cl91_sup)) {
   3916                     cl91_fec = 1;
   3917                 } else if ((ld_cl74_req || rd_cl74_req) &&
   3918                     (ld_cl74_sup && rd_cl74_sup)) {
   3919                     cl74_fec = 1;
   3920                 } else if ((rd_base_cl74_fec_req || ld_base_cl74_fec_req) &&
   3921                     (rd_base_cl74_fec_sup && ld_base_cl74_fec_sup)) {
   3922                     cl74_fec =1;
   3923                 }
   3924 
   3925             }
   3926 
   3927         }
   3928     }
   3929 
   3930     if (is_krs) {
   3931         /* For 25GBASE-KR-S and 25GBASE-CR-S PHYs if either PHY requests RS-FEC or BASE-R FEC then
   3932         * BASE-R operation is enabled. This is because 25GBASE-KR-S and 25GBASE-CR-S PHYs do not support
   3933         * RS-FEC operation
   3934         */
   3935         if (cl91_fec) {
   3936             cl74_25gkrs_fec = 1;
   3937         }
   3938         cl91_fec = 0;
   3939     }
   3940 
   3941     if (cl91_fec) {
   3942         /* enable cl91 FEC */
   3943         fec_type = TEFMOD16_CL91;
   3944     } else if (cl74_fec || cl74_25gkrs_fec) {
   3945         /* enable cl74 FEC */
   3946         fec_type = TEFMOD16_CL74;
   3947     } else {
   3948         /* NO FEC enable */
   3949         fec_type = 0x0;
   3950     }
   3951 
   3952     if (fec_type) {
   3953         PHYMOD_IF_ERR_RETURN
   3954             (tefmod16_FEC_control(&phy->access, fec_type, 1, 0));
   3955         /* HW AN logic does not drive the FEC control in SW AN mode
   3956          * Need to override fec control
   3957          */
   3958         PHYMOD_IF_ERR_RETURN
   3959             (tefmod16_sw_an_fec_override(&phy->access, fec_type, 1));
   3960     }
   3961     /* Program the resolved speed Id to speed control */
   3962     PHYMOD_IF_ERR_RETURN
   3963         (tefmod16_set_speed_id(&phy->access, hcd_speed));
   3964 
   3965     return PHYMOD_E_NONE;
   3966 }
   3967 
   3968 static int _is_send_ack(phymod_sw_an_ctxt_t *an_ctxt)
   3969 {
   3970 
   3971     phymod_an_page_t *tx_page = 0;
   3972     phymod_an_page_t *rx_page = 0;
   3973     int send_ack = 0;
   3974     int is_valid_tx_page =1, is_valid_rx_page = 1;
   3975 
   3976   
   3977 
   3978     /**
   3979      * check the current Tx page and Current Rx page and if the NP bit is set then send the ack
   3980      */
   3981     switch (an_ctxt->tx_pages_cnt) {
   3982         case TEFMOD16_AN_PAGE_ID_BASE_PAGE:
   3983             /* check the base page NP bit */
   3984             tx_page = &an_ctxt->tx_pages.base_page;
   3985             break;
   3986         case TEFMOD16_AN_PAGE_ID_MSG_PAGE:
   3987             /* check the message page NP bit */
   3988             tx_page = &an_ctxt->tx_pages.msg_page;
   3989             break;
   3990         case TEFMOD16_AN_PAGE_ID_UP_PAGE:
   3991            /* check the UF page NP bit */
   3992             tx_page = &an_ctxt->tx_pages.ufmt_page;
   3993             break;
   3994         default:
   3995             tx_page = &an_ctxt->tx_pages.null_page;
   3996             is_valid_tx_page = 0;
   3997         break;
   3998     }
   3999 
   4000     switch (an_ctxt->rx_pages_cnt) {
   4001         case TEFMOD16_AN_PAGE_ID_NONE:
   4002             /* No page has been rcvd yet */
   4003             is_valid_rx_page = 0;
   4004             break;
   4005         case TEFMOD16_AN_PAGE_ID_BASE_PAGE:
   4006             /* Rcvd base page NP bit */
   4007             rx_page = &an_ctxt->rx_pages.base_page;
   4008             break;
   4009         case TEFMOD16_AN_PAGE_ID_MSG_PAGE:
   4010             /* Rcvd msg page NP bit */
   4011             rx_page = &an_ctxt->rx_pages.msg_page;
   4012             break;
   4013         case TEFMOD16_AN_PAGE_ID_UP_PAGE:
   4014             /* Rcvd ufmt page NP bit */
   4015             rx_page = &an_ctxt->rx_pages.ufmt_page;
   4016             break;
   4017         default:
   4018             /* check the cahed page at null page location*/
   4019             rx_page = &an_ctxt->rx_pages.null_page;
   4020             break;
   4021     }
   4022 
   4023     if ( is_valid_tx_page && tx_page->page_0) {
   4024         if ((tx_page->page_0 >> AN_BASE0_PAGE_NP_OFFSET) & 0x1) {
   4025             send_ack = 1;
   4026         }
   4027     }
   4028    if (is_valid_rx_page && rx_page->page_0) {
   4029         if ((rx_page->page_0 >> AN_BASE0_PAGE_NP_OFFSET) & 0x1) {
   4030             send_ack = 1;
   4031         }
   4032     }
   4033 
   4034     return send_ack;
   4035 }
   4036 
   4037 int tscf16_phy_sw_an_control_status_get(const phymod_phy_access_t* phy, phymod_sw_an_ctrl_status_t* an_ctrl_status)
   4038 {
   4039 
   4040     PHYMOD_MEMSET(an_ctrl_status, 0, sizeof(phymod_sw_an_ctrl_status_t));
   4041 
   4042     PHYMOD_IF_ERR_RETURN
   4043         (tefmod16_sw_an_ctl_sts_get(&phy->access, an_ctrl_status));
   4044 
   4045     return PHYMOD_E_NONE;
   4046 }
   4047 
   4048 int tscf16_phy_sw_an_base_page_exchange_handler(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t* an_ctxt)
   4049 {
   4050     phymod_phy_access_t phy_copy;
   4051     int start_lane, num_lane;
   4052 
   4053     PHYMOD_IF_ERR_RETURN
   4054         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4055 
   4056     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   4057     phy_copy.access.lane_mask = 0x1 << start_lane;
   4058 
   4059     PHYMOD_IF_ERR_RETURN
   4060         (tefmod16_setup_for_sw_an(&phy_copy.access, num_lane));
   4061     PHYMOD_IF_ERR_RETURN
   4062         (tefmod16_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.base_page, 1));
   4063     an_ctxt->tx_pages_cnt++;
   4064 
   4065     PHYMOD_IF_ERR_RETURN
   4066         (_tscf16_sw_an_pmd_lane_cfg_set((phymod_phy_access_t*)phy, 1));
   4067     PHYMOD_USLEEP(1);
   4068     PHYMOD_IF_ERR_RETURN
   4069         (tefmod16_sw_an_control(&phy_copy.access, 1));
   4070 
   4071     return PHYMOD_E_NONE;
   4072 
   4073 }
   4074 int tscf16_phy_sw_an_lp_page_rdy_handler(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t* an_ctxt)
   4075 {
   4076     phymod_phy_access_t phy_copy;
   4077     int start_lane, num_lane;
   4078 
   4079 
   4080     PHYMOD_IF_ERR_RETURN
   4081         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4082 
   4083     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   4084     phy_copy.access.lane_mask = 0x1 << start_lane;
   4085     /* 1. Incerement the Rx page count
   4086     * 2. read the lp page and cache it in the rx page buffer
   4087     * 3. if the current tx page NP bit is 1 or rcvd page NP bit is 1
   4088     *      send the ack
   4089     * 4. else
   4090     *      a. parse the received pages
   4091     *      b. resolve speed
   4092     *      c. program the speed control based on resolved speed
   4093     *      d. set the ack
   4094     */
   4095 
   4096     an_ctxt->rx_pages_cnt++;
   4097     switch(an_ctxt->rx_pages_cnt) {
   4098         case TEFMOD16_AN_PAGE_ID_BASE_PAGE:
   4099             /* recevied LP base page */
   4100             PHYMOD_IF_ERR_RETURN
   4101                 (tefmod16_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.base_page));
   4102             break;
   4103         case TEFMOD16_AN_PAGE_ID_MSG_PAGE:
   4104             /* rcvd LP message page */
   4105             PHYMOD_IF_ERR_RETURN
   4106                 (tefmod16_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.msg_page));
   4107             break;
   4108         case TEFMOD16_AN_PAGE_ID_UP_PAGE:
   4109             /* rcvd LP UF page */
   4110             PHYMOD_IF_ERR_RETURN
   4111                 (tefmod16_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.ufmt_page));
   4112             break;
   4113         default:
   4114             /* we are only interested in first 3 pages rest of the pages won't be parsed
   4115              * use the null page entry as a scratch buffer to look for NP bit
   4116              */
   4117             PHYMOD_IF_ERR_RETURN
   4118                 (tefmod16_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.null_page));
   4119             break;
   4120     }
   4121 
   4122     if (_is_send_ack(an_ctxt)) {
   4123         /* Load the next page while the state IEEE SM is in ack det state */
   4124         switch(an_ctxt->tx_pages_cnt) {
   4125             case 0:
   4126                 /* Invalid. Atleast base page shoould have beem txed before
   4127                 * receving ld_page event
   4128                 */
   4129                 break;
   4130             case TEFMOD16_AN_PAGE_ID_BASE_PAGE:
   4131                 /* Tx Message Page */
   4132                 PHYMOD_IF_ERR_RETURN
   4133                     (tefmod16_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.msg_page, 0));
   4134                 an_ctxt->tx_pages_cnt++;
   4135                 break;
   4136             case TEFMOD16_AN_PAGE_ID_MSG_PAGE:
   4137                 /* Tx unformatted Page for BAM abilities */
   4138                 PHYMOD_IF_ERR_RETURN
   4139                     (tefmod16_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.ufmt_page, 0));
   4140                 an_ctxt->tx_pages_cnt++;
   4141                 break;
   4142             default:
   4143                 /* request for page when no more valid pages are available to Tx
   4144                 * Tx NULL pages
   4145                 */
   4146                 PHYMOD_IF_ERR_RETURN
   4147                     (tefmod16_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.null_page, 0));
   4148                 an_ctxt->tx_pages_cnt++;
   4149                 break;
   4150         }
   4151 
   4152     } else {
   4153         PHYMOD_IF_ERR_RETURN
   4154             (_resolve_speed(phy, an_ctxt));
   4155     }
   4156     PHYMOD_IF_ERR_RETURN
   4157         (tefmod16_sw_an_set_ack(&phy_copy.access));
   4158 
   4159     return PHYMOD_E_NONE;
   4160 }
   4161 
   4162 
   4163 int tscf16_phy_sw_autoneg_enable(const phymod_phy_access_t* phy, int enable)
   4164 {
   4165     phymod_phy_access_t phy_copy;
   4166     int start_lane, num_lane;
   4167 
   4168     PHYMOD_IF_ERR_RETURN
   4169         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4170 
   4171     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   4172     phy_copy.access.lane_mask = 0x1 << start_lane;
   4173 
   4174     PHYMOD_IF_ERR_RETURN
   4175         (_tscf16_sw_an_pmd_lane_cfg_set((phymod_phy_access_t*)phy, enable));
   4176     PHYMOD_USLEEP(10);
   4177 
   4178     PHYMOD_IF_ERR_RETURN
   4179         (tefmod16_sw_an_control(&phy_copy.access, enable));
   4180 
   4181     /* When disable SW AN, remove AN FEC override */
   4182     if (!enable) {
   4183        PHYMOD_IF_ERR_RETURN
   4184             (tefmod16_sw_an_fec_override(&phy->access, 0, 0));
   4185     }
   4186     return PHYMOD_E_NONE;
   4187 
   4188 }
   4189 
   4190 int tscf16_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy,
   4191                                   phymod_synce_clk_ctrl_t cfg)
   4192 {
   4193     phymod_phy_access_t phy_copy;
   4194     int start_lane, num_lane;
   4195 
   4196     PHYMOD_IF_ERR_RETURN
   4197         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4198 
   4199     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   4200     phy_copy.access.lane_mask = 0x1 << start_lane;
   4201 
   4202     PHYMOD_IF_ERR_RETURN
   4203          (tefmod16_synce_stg0_mode_set(&phy_copy.access, cfg.stg0_mode));
   4204 
   4205     PHYMOD_IF_ERR_RETURN
   4206         (tefmod16_synce_stg1_mode_set(&phy_copy.access, cfg.stg1_mode));
   4207 
   4208     PHYMOD_IF_ERR_RETURN
   4209         (tefmod16_synce_clk_ctrl_set(&phy_copy.access, cfg.sdm_val));
   4210 
   4211     return PHYMOD_E_NONE;
   4212 }
   4213 
   4214 int tscf16_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy,
   4215                                   phymod_synce_clk_ctrl_t *cfg)
   4216 {
   4217     PHYMOD_IF_ERR_RETURN
   4218         (tefmod16_synce_stg0_mode_get(&phy->access, &(cfg->stg0_mode)));
   4219 
   4220     PHYMOD_IF_ERR_RETURN
   4221         (tefmod16_synce_stg1_mode_get(&phy->access, &(cfg->stg1_mode)));
   4222 
   4223     PHYMOD_IF_ERR_RETURN
   4224         (tefmod16_synce_clk_ctrl_get(&phy->access, &(cfg->sdm_val)));
   4225 
   4226     return PHYMOD_E_NONE;
   4227 }
   4228 
   4229 int tscf16_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm)
   4230 {
   4231     int start_lane, num_lane;
   4232     phymod_phy_access_t pm_phy_copy;
   4233 
   4234     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   4235 
   4236     PHYMOD_IF_ERR_RETURN
   4237         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4238 
   4239     pm_phy_copy.access.lane_mask = 1 << start_lane;
   4240     PHYMOD_IF_ERR_RETURN
   4241         (falcon16_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm));
   4242 
   4243     return PHYMOD_E_NONE;
   4244 }
   4245 
   4246 int tscf16_phy_fec_bypass_indication_set(const phymod_phy_access_t* phy,
   4247                                   uint32_t enable)
   4248 {
   4249     PHYMOD_IF_ERR_RETURN(
   4250       tefmod16_fec_bypass_indication_set(&phy->access, enable));
   4251 
   4252     return PHYMOD_E_NONE;
   4253 }
   4254 
   4255 int tscf16_phy_fec_bypass_indication_get(const phymod_phy_access_t* phy,
   4256                                   uint32_t *enable)
   4257 {
   4258     int start_lane, num_lane;
   4259     phymod_phy_access_t pm_phy_copy;
   4260 
   4261     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   4262 
   4263     PHYMOD_IF_ERR_RETURN
   4264         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   4265 
   4266     pm_phy_copy.access.lane_mask = 1 << start_lane;
   4267 
   4268     PHYMOD_IF_ERR_RETURN(
   4269       tefmod16_fec_bypass_indication_get(&pm_phy_copy.access, enable));
   4270 
   4271     return PHYMOD_E_NONE;
   4272 }
   4273