openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

tscf.c (149518B)


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