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

falcon.c (60265B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <phymod/phymod.h>
     11 #include <phymod/phymod_system.h>
     12 #include <phymod/phymod_util.h>
     13 #include <phymod/phymod_dispatch.h>
     14 #include <phymod/chip/bcmi_falcon_xgxs_defs.h>
     15 #include <phymod/chip/falcon.h>
     16 #include "../../falcon/tier1/falcon_cfg_seq.h"
     17 #include "../../falcon/tier1/falcon_tsc_enum.h"
     18 #include "../../falcon/tier1/falcon_tsc_common.h"
     19 #include "../../falcon/tier1/falcon_tsc_interface.h"
     20 #include "../../falcon/tier1/falcon_tsc_dependencies.h"
     21 #include "../../falcon/tier1/falcon_tsc_debug_functions.h"
     22 
     23 #define FALCON_ID0        0
     24 #define FALCON_ID1        0
     25 #define FALCON_MODEL    0x1b
     26 #define FALCON_REV_MASK   0x0
     27 #define TSCF_PHY_ALL_LANES 0xf
     28 #define FALCON_PMD_CRC_UCODE 1
     29 
     30 #define TSCF_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \
     31     do{\
     32         PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\
     33         (_phy_access)->type           = (_core_access)->type; \
     34         (_phy_access)->port_loc       = (_core_access)->port_loc; \
     35         (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \
     36         (_phy_access)->access.lane_mask = TSCF_PHY_ALL_LANES; \
     37     }while(0)
     38 
     39 #define TSCF_NOF_DFES 9
     40 #define TSCF_NOF_LANES_IN_CORE 4
     41 extern unsigned char  tscf_ucode[];
     42 extern unsigned short tscf_ucode_len;
     43 extern unsigned short tscf_ucode_crc;
     44 
     45 
     46 int falcon_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
     47 {
     48     const phymod_access_t *pm_acc = &core->access;
     49     falcon_rev_id0_t rev_id0;
     50     falcon_rev_id1_t rev_id1;
     51     *is_identified = 0;
     52 
     53     /* PHY IDs match - now check model */
     54     PHYMOD_IF_ERR_RETURN(falcon_tsc_identify(pm_acc, &rev_id0, &rev_id1));
     55     if (rev_id0.revid_model == FALCON_MODEL)  {
     56         *is_identified = 1;
     57     }
     58 
     59     return PHYMOD_E_NONE;
     60 }
     61 
     62 
     63 int falcon_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info)
     64 {
     65         
     66     info->core_version = phymodCoreVersionFalconA0;
     67     info->serdes_id = 0;
     68     info->phy_id0 = 0;
     69     info->phy_id1 = 0;
     70 
     71     return PHYMOD_E_NONE;
     72     
     73 }
     74 
     75 
     76 int falcon_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
     77 {
     78         
     79     
     80     /* Not supported */
     81     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_pll_sequencer_restart)\n"));
     82 
     83         
     84     return PHYMOD_E_NONE;
     85     
     86 }
     87 
     88 int falcon_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
     89 {
     90     int lane;    
     91     uint32_t pmd_swap = 0;
     92     PHYMOD_IF_ERR_RETURN(falcon_pmd_lane_swap_tx_get(&core->access, &pmd_swap));
     93     for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){
     94         /*deccode each lane from four bits*/
     95         /*considering the pcs lane swap: tx_map[lane] = pmd_map[pcs_map[lane]]*/
     96         /* lane_map->lane_map_tx[lane] = (pmd_swap>>(lane_map->lane_map_rx[lane]*4)) & TSCF_LANE_SWAP_LANE_MASK; */
     97         lane_map->lane_map_tx[lane] = (pmd_swap>>(lane*4)) & 0x3;
     98         /*rx lane map is not supported*/
     99         lane_map->lane_map_rx[lane] = lane;
    100     }
    101     lane_map->num_of_lanes = TSCF_NOF_LANES_IN_CORE;   
    102     return PHYMOD_E_NONE;
    103 
    104         
    105     return PHYMOD_E_NONE;
    106     
    107 }
    108 
    109 
    110 int falcon_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
    111 {
    112         
    113     
    114     /* Not supported */
    115     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_reset_set)\n"));
    116 
    117         
    118     return PHYMOD_E_NONE;
    119     
    120 }
    121 
    122 int falcon_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
    123 {
    124         
    125     
    126     /* Not supported */
    127     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_reset_get) \n"));
    128 
    129         
    130     return PHYMOD_E_NONE;
    131     
    132 }
    133 
    134 
    135 int falcon_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info)
    136 {
    137         
    138     
    139     /* Not supported */
    140     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_firmware_info_get) \n"));
    141 
    142         
    143     return PHYMOD_E_NONE;
    144     
    145 }
    146 
    147 int falcon_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    148 {
    149         
    150     
    151     switch (tx_control)
    152     {
    153         case phymodTxElectricalIdleEnable:
    154             PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 1));
    155             break;
    156         case phymodTxElectricalIdleDisable:
    157             PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 0));
    158             break;
    159         case phymodTxSquelchOn:
    160             PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 1));
    161             break;
    162         case phymodTxSquelchOff:
    163             PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 0));
    164             break;
    165         default:
    166             PHYMOD_DEBUG_ERROR(("This control is NOT SUPPORTED!! (falcon_phy_tx_lane_control_set) \n"));
    167             break;
    168     }
    169 
    170     return PHYMOD_E_NONE; 
    171 }
    172 
    173 
    174 int falcon_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t *tx_control)
    175 {
    176     uint8_t disable;
    177 
    178     PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable_get(&phy->access, &disable));
    179     if(disable) {
    180       *tx_control = phymodTxSquelchOn;
    181     } else {
    182       *tx_control = phymodTxSquelchOff;
    183     }
    184 
    185     return PHYMOD_E_NONE;
    186 }
    187 
    188 /*Rx control*/
    189 int falcon_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    190 {
    191     phymod_phy_access_t pm_phy_copy;
    192     int start_lane, num_lane, i;
    193 
    194     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    195     /* next program the tx fir taps and driver current based on the input */
    196     PHYMOD_IF_ERR_RETURN
    197         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    198 
    199     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    200 
    201     switch (rx_control) {
    202     case phymodRxSquelchOn:
    203         for (i = 0; i < num_lane; i++) {
    204             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    205                 continue;
    206             }
    207             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    208             PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_set(&pm_phy_copy.access, 1));
    209         }
    210         break;
    211     case phymodRxSquelchOff:
    212         for (i = 0; i < num_lane; i++) {
    213             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    214                 continue;
    215             }
    216             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    217             PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_set(&pm_phy_copy.access, 0));
    218         }
    219         break;
    220     default:
    221         /* Not supported */
    222         PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_rx_lane_control_set) \n"));
    223         break;
    224     }
    225     return PHYMOD_E_NONE;
    226 }
    227 
    228 
    229 int falcon_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    230 {
    231     uint32_t enable, lb_enable;
    232     phymod_phy_access_t pm_phy_copy;
    233     int start_lane, num_lane;
    234 
    235     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    236     /* next program the tx fir taps and driver current based on the input */
    237     PHYMOD_IF_ERR_RETURN
    238         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    239 
    240     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    241 
    242     PHYMOD_IF_ERR_RETURN(falcon_rx_squelch_get(&pm_phy_copy.access, &enable));
    243     /* next check if PMD loopback is on */
    244     if (enable) {
    245         PHYMOD_IF_ERR_RETURN(falcon_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    246         if (lb_enable) enable = 0;
    247     }
    248     if(enable) {
    249         *rx_control = phymodRxSquelchOn;
    250     } else {
    251         *rx_control = phymodRxSquelchOff;
    252     }
    253     return PHYMOD_E_NONE;
    254 }
    255 
    256 int falcon_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type)
    257 {
    258         
    259     
    260     /* Not supported */
    261     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_rx_lane_control_get) \n"));
    262 
    263         
    264     return PHYMOD_E_NONE;
    265     
    266 }
    267 
    268 int falcon_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    269 {
    270         
    271     
    272     /* Not supported */
    273     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_ability_get) \n"));
    274 
    275         
    276     return PHYMOD_E_NONE;
    277     
    278 }
    279 
    280 int falcon_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
    281 {
    282         
    283     
    284     /* Not supported */
    285     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_set) \n"));
    286 
    287         
    288     return PHYMOD_E_NONE;
    289     
    290 }
    291 
    292 int falcon_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
    293 {
    294         
    295     
    296     /* Not supported */
    297     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_get) \n"));
    298 
    299         
    300     return PHYMOD_E_NONE;
    301     
    302 }
    303 
    304 int falcon_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status)
    305 {
    306         
    307     
    308     /* Not supported */
    309     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_phy_autoneg_status_get) \n"));
    310 
    311         
    312     return PHYMOD_E_NONE;
    313     
    314 }
    315 
    316 /* load tscf fw. the fw_loader parameter is valid just for external fw load*/
    317 STATIC
    318 int _falcon_core_firmware_load(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config)
    319 {
    320     int wait;
    321 
    322     switch(init_config->firmware_load_method){
    323     case phymodFirmwareLoadMethodInternal:
    324         PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_mdio_load(&core->access, tscf_ucode, tscf_ucode_len));
    325         break;
    326     case phymodFirmwareLoadMethodExternal:
    327         if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
    328             PHYMOD_NULL_CHECK(init_config->firmware_loader);
    329             PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_init(&core->access));
    330             if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    331                 wait = 0;
    332             } else {
    333                 wait = 1;
    334             }
    335             PHYMOD_IF_ERR_RETURN(falcon_pram_firmware_enable(&core->access, 1, wait));
    336 
    337             if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    338                 return PHYMOD_E_NONE;
    339             }
    340         
    341             PHYMOD_IF_ERR_RETURN(init_config->firmware_loader(core, tscf_ucode_len, tscf_ucode));
    342         }
    343         PHYMOD_IF_ERR_RETURN(falcon_pram_firmware_enable(&core->access, 0, 0));
    344         break;
    345     case phymodFirmwareLoadMethodNone:
    346         break;
    347     default:
    348         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), init_config->firmware_load_method));
    349     }
    350     if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone){
    351         /*PHYMOD_IF_ERR_RETURN(tscf_core_firmware_info_get(core, &actual_fw));
    352         if((tscf_ucode_crc != actual_fw.fw_crc) || (tscf_ucode_ver != actual_fw.fw_version)){
    353             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("fw load validation was failed")));
    354         } */
    355     }
    356     return PHYMOD_E_NONE;
    357 }
    358 
    359 int falcon_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config)
    360 {
    361     struct falcon_tsc_uc_core_config_st serdes_firmware_core_config;
    362     uint32_t is_write_disabled;
    363 
    364     PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_write_disabled));
    365     if(is_write_disabled) {
    366         return PHYMOD_E_NONE;
    367     }
    368 
    369     
    370     PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config));
    371     serdes_firmware_core_config.field.core_cfg_from_pcs = fw_config.CoreConfigFromPCS;
    372     serdes_firmware_core_config.field.vco_rate = fw_config.VcoRate; 
    373     serdes_firmware_core_config.field.disable_write_pll_iqp = fw_config.disable_write_pll_iqp; 
    374     PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_core_config(&phy->access, serdes_firmware_core_config));
    375     return PHYMOD_E_NONE;
    376 }
    377 
    378 
    379 int falcon_phy_firmware_core_config_get(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     PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config));
    383     PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config));
    384     fw_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs;
    385     fw_config->VcoRate = serdes_firmware_core_config.field.vco_rate;
    386     fw_config->disable_write_pll_iqp = serdes_firmware_core_config.field.disable_write_pll_iqp;
    387     return PHYMOD_E_NONE; 
    388 }
    389 
    390 
    391 int falcon_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config)
    392 {
    393     struct falcon_tsc_uc_lane_config_st serdes_firmware_config;
    394 
    395     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    396     PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
    397     PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config));
    398     fw_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs;
    399     fw_config->AnEnabled         = serdes_firmware_config.field.an_enabled;
    400     fw_config->DfeOn             = serdes_firmware_config.field.dfe_on;
    401     fw_config->LpDfeOn           = serdes_firmware_config.field.dfe_lp_mode;
    402     fw_config->ForceBrDfe        = serdes_firmware_config.field.force_brdfe_on;
    403     /* fw_config->Cl72Enable        = serdes_firmware_config.field.cl72_emulation_en; */
    404     fw_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis;
    405     fw_config->UnreliableLos     = serdes_firmware_config.field.unreliable_los;
    406     fw_config->MediaType         = serdes_firmware_config.field.media_type;
    407     fw_config->Cl72AutoPolEn     = serdes_firmware_config.field.cl72_auto_polarity_en;
    408     fw_config->Cl72RestTO        = serdes_firmware_config.field.cl72_restart_timeout_en;
    409      
    410     return PHYMOD_E_NONE; 
    411 }
    412 
    413 int falcon_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    414 {
    415     
    416     PHYMOD_IF_ERR_RETURN
    417         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre));
    418     PHYMOD_IF_ERR_RETURN
    419         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main));
    420     PHYMOD_IF_ERR_RETURN
    421         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post));
    422     PHYMOD_IF_ERR_RETURN
    423         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2));
    424     PHYMOD_IF_ERR_RETURN
    425         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3));
    426     PHYMOD_IF_ERR_RETURN
    427         (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_AMP,  (int8_t)tx->amp));
    428     if((tx->drivermode != -1) &&
    429        (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) {
    430         PHYMOD_IF_ERR_RETURN
    431             (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE,  (int8_t)tx->drivermode));
    432     }
    433     return PHYMOD_E_NONE;
    434 }
    435 
    436 int falcon_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx)
    437 {
    438     switch (media) {
    439     case phymodMediaTypeChipToChip:
    440       tx->pre   = 0xc;
    441       tx->main  = 0x66;
    442       tx->post  = 0x0;
    443       tx->post2 = 0x0;
    444       tx->post3 = 0x0;
    445       tx->amp   = 0xc;
    446       break;
    447     case phymodMediaTypeShort:
    448       tx->pre   = 0xc;
    449       tx->main  = 0x66;
    450       tx->post  = 0x0;
    451       tx->post2 = 0x0;
    452       tx->post3 = 0x0;
    453       tx->amp   = 0xc;
    454       break;
    455     case phymodMediaTypeMid:
    456       tx->pre   = 0xc;
    457       tx->main  = 0x66;
    458       tx->post  = 0x0;
    459       tx->post2 = 0x0;
    460       tx->post3 = 0x0;
    461       tx->amp   = 0xc;
    462       break;
    463     case phymodMediaTypeLong:
    464       tx->pre   = 0xc;
    465       tx->main  = 0x66;
    466       tx->post  = 0x0;
    467       tx->post2 = 0x0;
    468       tx->post3 = 0x0;
    469       tx->amp   = 0xc;
    470       break;
    471     default:
    472       tx->pre   = 0xc;
    473       tx->main  = 0x66;
    474       tx->post  = 0x0;
    475       tx->post2 = 0x0;
    476       tx->post3 = 0x0;
    477       tx->amp   = 0xc;
    478       break;
    479     }
    480         
    481     return PHYMOD_E_NONE;
    482         
    483     
    484 }
    485 
    486 /* 
    487  * set lane swapping for core 
    488  * The tx swap is composed of PCS swap and after that the PMD swap. 
    489  * The rx swap is composed just by PCS swap 
    490  */
    491 
    492 int falcon_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    493 {
    494     phymod_phy_access_t phy_access;
    495     uint32_t lane, pmd_tx_map =0;
    496 
    497     for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){
    498         pmd_tx_map |= ((lane_map->lane_map_tx[lane]) & 3) << (lane*4);
    499     }
    500 
    501     TSCF_CORE_TO_PHY_ACCESS(&phy_access, core);
    502     PHYMOD_IF_ERR_RETURN
    503         (falcon_pmd_lane_swap(&phy_access.access, pmd_tx_map));
    504 
    505     return PHYMOD_E_NONE;
    506 }
    507 
    508 
    509 
    510 STATIC
    511 int _falcon_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier)
    512 {
    513     switch (pll_div) {
    514     case 0x0:
    515         *pll_multiplier = 64;
    516         break;
    517     case 0x1:
    518         *pll_multiplier = 66;
    519         break;
    520     case 0x2:
    521         *pll_multiplier = 80;
    522         break;
    523     case 0x3:
    524         *pll_multiplier = 128;
    525         break;
    526     case 0x4:
    527         *pll_multiplier = 132;
    528         break;
    529     case 0x5:
    530         *pll_multiplier = 140;
    531         break;
    532     case 0x6:
    533         *pll_multiplier = 160;
    534         break;
    535     case 0x7:
    536         *pll_multiplier = 165;
    537         break;
    538     case 0x8:
    539         *pll_multiplier = 168;
    540         break;
    541     case 0x9:
    542         *pll_multiplier = 170;
    543         break;
    544     case 0xa:
    545         *pll_multiplier = 175;
    546         break;
    547     case 0xb:
    548         *pll_multiplier = 180;
    549         break;
    550     case 0xc:
    551         *pll_multiplier = 184;
    552         break;
    553     case 0xd:
    554         *pll_multiplier = 200;
    555         break;
    556     case 0xe:
    557         *pll_multiplier = 224;
    558         break;
    559     case 0xf:
    560         *pll_multiplier = 264;
    561         break;
    562     default:
    563         *pll_multiplier = 165;
    564         break;
    565     }
    566     return PHYMOD_E_NONE;
    567 }
    568 
    569 
    570 STATIC
    571 int _falcon_actual_osr_get(int osr_mode, int* actual_os)
    572 {
    573     switch(osr_mode) {
    574         case 0: *actual_os = 1; break;
    575         case 1: *actual_os = 2; break;
    576         case 2: *actual_os = 4; break;
    577         default: 
    578             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode));
    579     }
    580     return PHYMOD_E_NONE;
    581 }
    582 
    583 
    584 int _falcon_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
    585 {
    586     uint32_t is_warm_boot;
    587     struct falcon_tsc_uc_lane_config_st serdes_firmware_config;
    588 
    589     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    590     serdes_firmware_config.field.lane_cfg_from_pcs      = fw_config.LaneConfigFromPCS;
    591     serdes_firmware_config.field.an_enabled             = fw_config.AnEnabled;
    592     serdes_firmware_config.field.dfe_on                 = fw_config.DfeOn; 
    593     serdes_firmware_config.field.force_brdfe_on         = fw_config.ForceBrDfe;
    594     /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */
    595     serdes_firmware_config.field.scrambling_dis         = fw_config.ScramblingDisable;
    596     serdes_firmware_config.field.unreliable_los         = fw_config.UnreliableLos;
    597     serdes_firmware_config.field.media_type             = fw_config.MediaType;
    598     serdes_firmware_config.field.dfe_lp_mode            = fw_config.LpDfeOn;
    599     serdes_firmware_config.field.cl72_auto_polarity_en  = fw_config.Cl72AutoPolEn;
    600     serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO;
    601 
    602     PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_warm_boot));
    603 
    604     if(!is_warm_boot) {
    605         PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_lane_cfg(&phy->access, serdes_firmware_config));
    606     }
    607     return PHYMOD_E_NONE;
    608 }
    609 
    610 int falcon_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
    611 {
    612     phymod_phy_access_t phy_copy;
    613     int start_lane, num_lane, i;
    614 
    615     PHYMOD_IF_ERR_RETURN
    616         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    617     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    618 
    619     for (i = 0; i < num_lane; i++) {
    620         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    621             continue;
    622         }
    623         phy_copy.access.lane_mask = 1 << (start_lane + i);
    624         PHYMOD_IF_ERR_RETURN
    625             (falcon_lane_soft_reset_release(&phy_copy.access, 0));
    626     }
    627 
    628 
    629     for (i = 0; i < num_lane; i++) {
    630         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    631             continue;
    632         }
    633         phy_copy.access.lane_mask = 1 << (start_lane + i);
    634         PHYMOD_IF_ERR_RETURN
    635             (_falcon_phy_firmware_lane_config_set(&phy_copy, fw_config));
    636     }
    637 
    638 
    639     for (i = 0; i < num_lane; i++) {
    640         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    641             continue;
    642         }
    643         phy_copy.access.lane_mask = 1 << (start_lane + i);
    644         PHYMOD_IF_ERR_RETURN
    645             (falcon_lane_soft_reset_release(&phy_copy.access, 1));
    646     }
    647 
    648     return PHYMOD_E_NONE;
    649 }
    650 
    651 
    652 /* reset rx sequencer 
    653  * flags - unused parameter
    654  */
    655 int falcon_phy_rx_restart(const phymod_phy_access_t* phy)
    656 {
    657     phymod_phy_access_t phy_copy;
    658     int start_lane, num_lane, i;
    659 
    660     PHYMOD_IF_ERR_RETURN
    661         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    662     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    663 
    664     for (i = 0; i < num_lane; i++) {
    665         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    666             continue;
    667         }
    668         phy_copy.access.lane_mask = 1 << (start_lane + i);
    669 
    670         PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_restart(&phy_copy.access, 1));
    671     }     
    672     return PHYMOD_E_NONE;
    673 }
    674 
    675 
    676 int falcon_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    677 {
    678     PHYMOD_IF_ERR_RETURN
    679         (falcon_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity));
    680     return PHYMOD_E_NONE;
    681 }
    682 
    683 
    684 int falcon_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    685 {
    686    PHYMOD_IF_ERR_RETURN
    687         (falcon_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity));
    688     return PHYMOD_E_NONE;
    689 }
    690 
    691 int falcon_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    692 {
    693     int8_t value = 0;
    694 
    695     PHYMOD_IF_ERR_RETURN
    696         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value));
    697     tx->pre = value;
    698     PHYMOD_IF_ERR_RETURN
    699         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value));
    700     tx->main = value;
    701     PHYMOD_IF_ERR_RETURN
    702         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value));
    703     tx->post = value;
    704     PHYMOD_IF_ERR_RETURN
    705         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value));
    706     tx->post2 = value;
    707     PHYMOD_IF_ERR_RETURN
    708         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value));
    709     tx->post3 = value;
    710     PHYMOD_IF_ERR_RETURN
    711         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_AMP, &value));
    712     tx->amp = value;
    713     PHYMOD_IF_ERR_RETURN
    714         (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &value));
    715     tx->drivermode = value;
    716 
    717     return PHYMOD_E_NONE;
    718 }
    719 
    720 
    721 
    722 int falcon_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override)
    723 {
    724     phymod_phy_access_t phy_copy;
    725     int start_lane, num_lane, i;
    726 
    727     PHYMOD_IF_ERR_RETURN
    728         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    729     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    730 
    731     for (i = 0; i < num_lane; i++) {
    732         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    733             continue;
    734         }
    735         phy_copy.access.lane_mask = 1 << (start_lane + i);
    736 
    737         PHYMOD_IF_ERR_RETURN
    738             (falcon_tsc_tx_pi_freq_override(&phy_copy.access,
    739                                         tx_override->phase_interpolator.enable,
    740                                         tx_override->phase_interpolator.value));
    741     }                                          
    742     return PHYMOD_E_NONE;
    743 }
    744 
    745 int falcon_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override)
    746 {
    747 /*
    748     PHYMOD_IF_ERR_RETURN
    749         (temod_tx_pi_control_get(&phy->access, &tx_override->phase_interpolator.value));
    750 */
    751     return PHYMOD_E_NONE;
    752 }
    753 
    754 
    755 int falcon_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    756 {
    757     uint32_t i;
    758 
    759     /*params check*/
    760     if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF_NOF_DFES)){
    761         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps));
    762     }
    763 
    764     /*vga set*/
    765     if (rx->vga.enable) {
    766         /* first stop the rx adaption */
    767         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1));
    768         PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_VGA, rx->vga.value));
    769     } else {
    770         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0));
    771     }
    772 
    773     /*dfe set*/
    774     for (i = 0 ; i < rx->num_of_dfe_taps ; i++){
    775         if(rx->dfe[i].enable){
    776             PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1));
    777             switch (i) {
    778                 case 0:
    779                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE1, rx->dfe[i].value));
    780                     break;
    781                 case 1:
    782                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE2, rx->dfe[i].value));
    783                     break;
    784                 case 2:
    785                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE3, rx->dfe[i].value));
    786                     break;
    787                 case 3:
    788                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE4, rx->dfe[i].value));
    789                     break;
    790                 case 4:
    791                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE5, rx->dfe[i].value));
    792                     break;
    793                 case 5:
    794                     PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_DFE6, rx->dfe[i].value));
    795                     break;
    796                 default:
    797                     return PHYMOD_E_PARAM;
    798             }
    799         } else {
    800             PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0));
    801         }
    802 
    803         
    804     }
    805 
    806     /*peaking filter set*/
    807     if(rx->peaking_filter.enable){
    808         /* first stop the rx adaption */
    809         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1));
    810         PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_PF, rx->peaking_filter.value));
    811     } else {
    812         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0));
    813     }
    814 
    815     if(rx->low_freq_peaking_filter.enable){
    816         /* first stop the rx adaption */
    817         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 1));
    818         PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&phy->access, RX_AFE_PF2, rx->low_freq_peaking_filter.value));
    819     } else {
    820         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0));
    821     }
    822     return PHYMOD_E_NONE;
    823 }
    824 
    825 
    826 int falcon_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    827 {
    828     int8_t val;
    829 
    830     PHYMOD_IF_ERR_RETURN
    831         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF, &val));
    832     rx->peaking_filter.value = val;
    833 
    834     PHYMOD_IF_ERR_RETURN
    835         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF2, &val));
    836     rx->low_freq_peaking_filter.value = val;
    837 
    838     PHYMOD_IF_ERR_RETURN
    839         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_VGA, &val));
    840     rx->vga.value = val;
    841 
    842     PHYMOD_IF_ERR_RETURN
    843         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1, &val));
    844     rx->dfe[0].value = val;
    845 
    846     PHYMOD_IF_ERR_RETURN
    847         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2, &val));
    848     rx->dfe[1].value = val;
    849 
    850     PHYMOD_IF_ERR_RETURN
    851         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3, &val));
    852     rx->dfe[2].value = val;
    853 
    854     PHYMOD_IF_ERR_RETURN
    855         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4, &val));
    856     rx->dfe[3].value = val;
    857 
    858     PHYMOD_IF_ERR_RETURN
    859         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5, &val));
    860     rx->dfe[4].value = val;
    861 
    862     PHYMOD_IF_ERR_RETURN
    863         (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE6, &val));
    864     rx->dfe[5].value = val;
    865 
    866     rx->num_of_dfe_taps = 6;
    867     rx->dfe[0].enable = 1;
    868     rx->dfe[1].enable = 1;
    869     rx->dfe[2].enable = 1;
    870     rx->dfe[3].enable = 1;
    871     rx->dfe[4].enable = 1;
    872     rx->dfe[5].enable = 1;
    873     rx->vga.enable = 1;
    874     rx->low_freq_peaking_filter.enable = 1;
    875     rx->peaking_filter.enable = 1;
    876 
    877     return PHYMOD_E_NONE;
    878 }
    879 
    880 int falcon_phy_rx_adaptation_resume(const phymod_phy_access_t* phy)
    881 {
    882     uint8_t uc_lane_stopped;
    883     PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_uc_lane_status(&phy->access, &uc_lane_stopped));
    884     if (uc_lane_stopped) {
    885         PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0));
    886     }
    887     return PHYMOD_E_NONE;
    888 }
    889 
    890 
    891 int falcon_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    892 {
    893     uint32_t rst, rst_rx, rst_tx;
    894     int start_lane, num_lane, i;
    895     phymod_phy_access_t phy_copy;
    896 
    897     PHYMOD_IF_ERR_RETURN
    898         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    899     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    900 
    901     if (reset->rx == reset->tx) {
    902         PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release_get(&phy_copy.access, &rst_tx));
    903         PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release_get(&phy_copy.access, &rst_rx));
    904         for (i = 0; i < num_lane; i++) {
    905             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    906                 continue;
    907             }
    908             phy_copy.access.lane_mask = 1 << (start_lane + i);
    909             /*If tx is in reset, release tx lane*/
    910             if (rst_tx == 0) {
    911                 PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1));
    912                 PHYMOD_USLEEP(10);
    913             }
    914             /*If rx is in reset, release rx lane*/
    915             if (rst_rx == 0) {
    916                 PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1));
    917                 PHYMOD_USLEEP(10);
    918             }
    919             switch (reset->tx) {
    920                 case phymodResetDirectionIn:
    921                     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 0));
    922                     break;
    923                 case phymodResetDirectionOut:
    924                     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1));
    925                     break;
    926                 case phymodResetDirectionInOut:
    927                     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 0));
    928                     PHYMOD_USLEEP(10);
    929                     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1));
    930                     break;
    931                 default:
    932                     break;
    933             }
    934         }
    935     } else {
    936         PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release_get(&phy->access, &rst));
    937         for (i = 0; i < num_lane; i++) {
    938             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    939                 continue;
    940             }
    941             phy_copy.access.lane_mask = 1 << (start_lane + i);
    942             /*If ln_rst is is in reset , release ln_rst first*/
    943             if (rst == 0) {
    944                 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&phy_copy.access, 1));
    945                 PHYMOD_USLEEP(10);
    946             }
    947             switch (reset->tx) {
    948                 case phymodResetDirectionIn:
    949                     PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 0));
    950                     break;
    951                 case phymodResetDirectionOut:
    952                     PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1));
    953                     break;
    954                 case phymodResetDirectionInOut:
    955                     PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 0));
    956                     PHYMOD_USLEEP(10);
    957                     PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release(&phy_copy.access, 1));
    958                     break;
    959                 default:
    960                     break;
    961             }
    962             switch (reset ->rx) {
    963                 case phymodResetDirectionIn:
    964                     PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 0));
    965                     break;
    966                 case phymodResetDirectionOut:
    967                     PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1));
    968                     break;
    969                 case phymodResetDirectionInOut:
    970                     PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 0));
    971                     PHYMOD_USLEEP(10);
    972                     PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release(&phy_copy.access, 1));
    973                     break;
    974                 default:
    975                     break;
    976             }
    977         }
    978     }
    979 
    980     
    981     return PHYMOD_E_NONE;
    982 }
    983 
    984 
    985 int falcon_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    986 {
    987         
    988     uint32_t rst, rst_rx, rst_tx;
    989     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release_get(&phy->access, &rst));    
    990     if(rst == 0) {
    991        reset->tx = phymodResetDirectionIn;
    992        reset->rx = phymodResetDirectionIn;
    993     } else {
    994        PHYMOD_IF_ERR_RETURN(falcon_tx_lane_soft_reset_release_get(&phy->access, &rst_tx));
    995        PHYMOD_IF_ERR_RETURN(falcon_rx_lane_soft_reset_release_get(&phy->access, &rst_rx));
    996        if (rst_tx == 0) {
    997            reset->tx = phymodResetDirectionIn;
    998        } else {
    999            reset->tx = phymodResetDirectionOut;
   1000        }
   1001 
   1002        if(rst_rx == 0) {
   1003            reset->rx = phymodResetDirectionIn;
   1004        } else {
   1005            reset->rx = phymodResetDirectionOut;
   1006        }
   1007     }
   1008 
   1009     return PHYMOD_E_NONE;
   1010 }
   1011 
   1012 
   1013 int falcon_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
   1014 {
   1015     enum srds_core_pwrdn_mode_enum mode;
   1016     phymod_phy_access_t phy_copy;
   1017     int start_lane, num_lane, i;
   1018 
   1019     PHYMOD_IF_ERR_RETURN
   1020         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1021     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1022 
   1023     for (i = 0; i < num_lane; i++) {
   1024         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1025             continue;
   1026         }
   1027         phy_copy.access.lane_mask = 1 << (start_lane + i);
   1028 
   1029         if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) {
   1030                 /*disable tx on the PMD side */
   1031                 mode = PWRDN_TX;
   1032                 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode));
   1033         }
   1034         if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) {
   1035                 /*enable tx on the PMD side */
   1036                 PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_set(&phy_copy.access, 1, 0));
   1037         }
   1038         if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) {
   1039                 /*disable rx on the PMD side */
   1040                 mode = PWRDN_RX;
   1041                 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode));
   1042         }
   1043         if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) {
   1044                 PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_set(&phy_copy.access, 0, 0));
   1045                 /*enable rx on the PMD side */
   1046         }
   1047         if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) {
   1048                 mode = PWR_ON;
   1049                 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode));
   1050         }
   1051         if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) {
   1052                 /* Both Tx and Rx power down */
   1053                 mode = PWRDN;
   1054                 PHYMOD_IF_ERR_RETURN(falcon_tsc_lane_pwrdn(&phy_copy.access, mode));
   1055         }
   1056     }
   1057     return PHYMOD_E_NONE; 
   1058 }
   1059 
   1060 int falcon_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
   1061 {
   1062     power_status_t pwrdn;
   1063     PHYMOD_IF_ERR_RETURN(falcon_tsc_pwrdn_get(&phy->access, &pwrdn));
   1064     power->rx = (pwrdn.rx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff;
   1065     power->tx = (pwrdn.tx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff;
   1066     return PHYMOD_E_NONE;
   1067 }
   1068 
   1069 
   1070 int falcon_phy_interface_config_set(const phymod_phy_access_t* phy, 
   1071                                     uint32_t flags, 
   1072                                     const phymod_phy_inf_config_t* config)
   1073 {
   1074     /* phymod_tx_t tx_params; */
   1075     uint32_t      current_pll_div=0;
   1076     uint32_t vco_rate;
   1077     uint32_t new_pll_div=0;
   1078     int16_t  new_os_mode =0;
   1079     phymod_phy_access_t pm_phy_copy;
   1080     int start_lane, num_lane, i;
   1081     int rv;
   1082     uint32_t enable[PHYMOD_MAX_LANES_PER_CORE] = {0};
   1083 
   1084     /* sc_table_entry exp_entry; RAVI */
   1085     phymod_firmware_lane_config_t firmware_lane_config;
   1086     phymod_firmware_core_config_t firmware_core_config;
   1087 
   1088     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   1089     PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config));
   1090     firmware_lane_config.MediaType = 0;
   1091 
   1092     /*next program the tx fir taps and driver current based on the input*/
   1093     PHYMOD_IF_ERR_RETURN
   1094         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1095 
   1096     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1097 
   1098     /*Get lane reset status*/
   1099     for (i = 0; i < num_lane; i++) {
   1100         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1101             continue;
   1102         }
   1103         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1104         PHYMOD_IF_ERR_RETURN
   1105             (falcon_lane_soft_reset_release_get(&pm_phy_copy.access, &enable[i]));
   1106     }
   1107 
   1108     /*Hold the per lne soft reset bit*/
   1109     for (i = 0; i < num_lane; i++) {
   1110         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1111             continue;
   1112         }
   1113         if (enable[i])
   1114         {
   1115             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1116             PHYMOD_IF_ERR_RETURN
   1117                 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1118         }
   1119     }
   1120 
   1121     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1122      PHYMOD_IF_ERR_RETURN
   1123         (falcon_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   1124 
   1125     /*make sure that an and config from pcs is off*/
   1126     firmware_core_config.CoreConfigFromPCS = 0;
   1127     firmware_lane_config.AnEnabled = 0;
   1128     firmware_lane_config.LaneConfigFromPCS = 0;
   1129     firmware_lane_config.DfeOn = 1;
   1130     firmware_lane_config.LpDfeOn = 0;
   1131     firmware_lane_config.Cl72RestTO = 1;
   1132     if(config->data_rate == 1000)
   1133        firmware_lane_config.DfeOn = 0;
   1134 
   1135 
   1136     if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1137         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1138     } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
   1139         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   1140     } else {
   1141         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   1142     }     
   1143 
   1144     /* No PCS
   1145     PHYMOD_IF_ERR_RETURN
   1146         (tefmod_update_port_mode(&phy->access, (int *) &pll_switch));
   1147     */
   1148 
   1149     /* Error code returned by get_vco function is not compliant with BCM error code
   1150      convert the tier1 error code to the PHYMOD error code which is compliant with 
   1151      BCM error codes */
   1152      rv = falcon_tsc_get_vco(config, &vco_rate, &new_pll_div, &new_os_mode);
   1153      if (rv != PHYMOD_E_NONE) {
   1154         /* SDK-95356 the above function could fail due to invalid param */
   1155         return PHYMOD_E_CONFIG;
   1156     }
   1157 
   1158     PHYMOD_IF_ERR_RETURN
   1159         (falcon_pll_mode_get(&pm_phy_copy.access, &current_pll_div));
   1160 
   1161     /* new_pll_div already found
   1162     PHYMOD_IF_ERR_RETURN
   1163         (tefmod_plldiv_lkup_get(&phy->access, spd_intf, &new_pll_div));
   1164     */
   1165 
   1166     /*
   1167     if(config->device_aux_modes !=NULL){
   1168         PHYMOD_IF_ERR_RETURN
   1169             (_tscf_st_hto_interface_config_set(config->device_aux_modes, start_lane, new_speed_vec, &new_pll_div, &new_os_mode)) ;
   1170     }
   1171     */
   1172 
   1173     
   1174 
   1175 
   1176 
   1177     /*if pll change is enabled*/
   1178     if((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){
   1179         if(config->interface_type != phymodInterfaceBypass) {
   1180             /*Terminate the execution of the function*/
   1181             PHYMOD_DEBUG_WARN(("PLL has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled \n",
   1182                                (unsigned int)current_pll_div, (unsigned int)new_pll_div));
   1183             return PHYMOD_E_NONE;
   1184         }
   1185     }
   1186     /*pll switch is required and expected */
   1187     if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) {
   1188         /* phymod_access_t tmp_phy_access; */
   1189         PHYMOD_IF_ERR_RETURN
   1190             (falcon_core_soft_reset_release(&pm_phy_copy.access, 0));
   1191 
   1192         /*release the uc reset */
   1193 #if 0
   1194         PHYMOD_IF_ERR_RETURN
   1195             (falcon_tsc_uc_reset(&pm_phy_copy.access ,0));
   1196 #endif
   1197         /*set the PLL divider */
   1198         PHYMOD_IF_ERR_RETURN
   1199             (falcon_pll_mode_set(&pm_phy_copy.access, new_pll_div));
   1200         /* In case of 22.5G (div 180 and ref_clk 125MHz), need to call falcon_tsc_configure_pll to set AMS_PLL_CTL values */
   1201         if ((new_pll_div == 0xb) && (config->ref_clock == phymodRefClk125Mhz))
   1202         {
   1203             PHYMOD_IF_ERR_RETURN
   1204                 (falcon_tsc_configure_pll (&pm_phy_copy.access, FALCON_TSC_pll_div_180x_refc125));
   1205         }
   1206 
   1207         firmware_core_config.VcoRate = (vco_rate * 16 + 500) / 1000 - 224;
   1208 
   1209         /*change the  master port num to the current caller port */
   1210         
   1211         /*
   1212         PHYMOD_IF_ERR_RETURN
   1213             (tefmod_master_port_num_set(&phy->access, start_lane));
   1214         ////////////////// Do we need PLL reset ///////////////
   1215         */
   1216 #if 0
   1217         PHYMOD_IF_ERR_RETURN
   1218             (falcon_pll_reset_enable_set(&pm_phy_copy.access, 1));
   1219 #endif
   1220         /*update the firmware config properly*/
   1221         PHYMOD_IF_ERR_RETURN
   1222             (falcon_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config));
   1223         PHYMOD_IF_ERR_RETURN
   1224             (falcon_core_soft_reset_release(&pm_phy_copy.access, 1));
   1225     }
   1226 
   1227     /*
   1228     PHYMOD_IF_ERR_RETURN
   1229         (tefmod_set_spd_intf(&phy->access, spd_intf));
   1230     */
   1231 
   1232     /*change TX parameters if enabled*/
   1233     /*
   1234     if((PHYMOD_IF_F_DONT_OVERIDE_TX_PARAMS & flags) == 0) {
   1235         PHYMOD_IF_ERR_RETURN
   1236             (tscf_phy_media_type_tx_get(phy, phymodMediaTypeMid, &tx_params));
   1237     }
   1238     */
   1239     for (i = 0; i < num_lane; i++) {
   1240         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1241             continue;
   1242         }
   1243         pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i);
   1244         PHYMOD_IF_ERR_RETURN
   1245              (_falcon_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   1246     }    
   1247     for (i = 0; i < num_lane; i++) {
   1248         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1249             continue;
   1250         }
   1251         pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i);
   1252         PHYMOD_IF_ERR_RETURN
   1253             (falcon_osr_mode_set(&pm_phy_copy.access, new_os_mode));
   1254     }
   1255         
   1256     /*release the per lne soft reset bit*/
   1257     for (i = 0; i < num_lane; i++) {
   1258         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1259             continue;
   1260         }
   1261         if (enable[i])
   1262         {
   1263             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1264             PHYMOD_IF_ERR_RETURN
   1265                 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1266         }
   1267     }
   1268 
   1269     
   1270 
   1271     return PHYMOD_E_NONE;
   1272 }
   1273 
   1274 /*flags- unused parameter*/
   1275 int falcon_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)
   1276 {
   1277     int osr_mode;
   1278     uint32_t pll_div;
   1279     uint32_t pll_multiplier, refclk;
   1280     phymod_phy_access_t phy_copy;
   1281     int actual_osr;
   1282     phymod_firmware_lane_config_t firmware_lane_config;
   1283     int start_lane, num_lane;
   1284 
   1285     config->ref_clock = ref_clock;
   1286 
   1287     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1288     PHYMOD_IF_ERR_RETURN
   1289         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1290     phy_copy.access.lane_mask = 0x1 << start_lane;
   1291 
   1292     PHYMOD_IF_ERR_RETURN
   1293         (falcon_osr_mode_get(&phy->access, &osr_mode));
   1294     PHYMOD_IF_ERR_RETURN
   1295         (falcon_pll_mode_get(&phy_copy.access, &pll_div));
   1296     PHYMOD_IF_ERR_RETURN
   1297         (_falcon_pll_multiplier_get(pll_div, &pll_multiplier));
   1298 
   1299     PHYMOD_IF_ERR_RETURN
   1300         (falcon_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   1301     if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) {
   1302         PHYMOD_INTF_MODES_FIBER_SET(config);
   1303     } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   1304         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1305         PHYMOD_INTF_MODES_COPPER_SET(config);
   1306     } else {
   1307         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1308         PHYMOD_INTF_MODES_BACKPLANE_SET(config);
   1309     }
   1310 
   1311     if (ref_clock == phymodRefClk156Mhz) {
   1312         refclk = 15625;
   1313     } else if (ref_clock == phymodRefClk125Mhz) {
   1314         refclk = 12500;
   1315     } else {
   1316         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL,  (_PHYMOD_MSG("Unknown refclk")));
   1317     }
   1318        
   1319     PHYMOD_IF_ERR_RETURN(_falcon_actual_osr_get(osr_mode, &actual_osr));
   1320 
   1321     config->data_rate = (refclk*pll_multiplier)/(100*actual_osr);
   1322     config->interface_type = phymodInterfaceBypass;
   1323 
   1324     if(osr_mode == 1) {
   1325         PHYMOD_INTF_MODES_OS2_SET(config);
   1326     }
   1327 
   1328     return PHYMOD_E_NONE;
   1329 }
   1330 
   1331 
   1332 int falcon_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
   1333 {
   1334     phymod_phy_access_t phy_copy;
   1335     int start_lane, num_lane, i;
   1336 
   1337     PHYMOD_IF_ERR_RETURN
   1338         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1339     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1340 
   1341     for (i = 0; i < num_lane; i++) {
   1342         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1343             continue;
   1344         }
   1345         phy_copy.access.lane_mask = 1 << (start_lane + i);
   1346 
   1347         PHYMOD_IF_ERR_RETURN
   1348                 (falcon_lane_soft_reset_release(&phy_copy.access, 0));
   1349     }
   1350 
   1351     for (i = 0; i < num_lane; i++) {
   1352         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1353             continue;
   1354         }
   1355         phy_copy.access.lane_mask = 1 << (start_lane + i);
   1356 
   1357         PHYMOD_IF_ERR_RETURN
   1358             (falcon_clause72_control(&phy_copy.access, cl72_en));
   1359     }
   1360 
   1361     for (i = 0; i < num_lane; i++) {
   1362         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1363             continue;
   1364         }
   1365         phy_copy.access.lane_mask = 1 << (start_lane + i);
   1366 
   1367         PHYMOD_IF_ERR_RETURN
   1368                 (falcon_lane_soft_reset_release(&phy_copy.access, 1));
   1369     }
   1370     return PHYMOD_E_NONE;
   1371 }
   1372 
   1373 int falcon_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
   1374 {
   1375     PHYMOD_IF_ERR_RETURN
   1376         (falcon_clause72_control_get(&phy->access, cl72_en));
   1377     return PHYMOD_E_NONE;
   1378 }
   1379 
   1380 
   1381 int falcon_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
   1382 {
   1383     uint32_t local_status;
   1384     PHYMOD_IF_ERR_RETURN
   1385         (falcon_pmd_cl72_receiver_status(&phy->access, &local_status));
   1386     status->locked = local_status;
   1387     return PHYMOD_E_NONE;
   1388 }
   1389 
   1390 int falcon_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
   1391 {
   1392     int i;
   1393     int start_lane, num_lane;
   1394     int rv = PHYMOD_E_NONE;
   1395     phymod_phy_access_t phy_copy;
   1396 
   1397     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1398 
   1399     /* next figure out the lane num and start_lane based on the input */
   1400     PHYMOD_IF_ERR_RETURN
   1401         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1402 
   1403     switch (loopback) {
   1404     case phymodLoopbackGlobal :
   1405         /* PHYMOD_IF_ERR_RETURN(tefmod_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); */
   1406         break;
   1407     case phymodLoopbackGlobalPMD :
   1408         for (i = 0; i < num_lane; i++) {
   1409             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1410                 continue;
   1411             }
   1412             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   1413             PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable));
   1414             PHYMOD_IF_ERR_RETURN(falcon_pmd_force_signal_detect(&phy_copy.access, (int) enable));
   1415         }
   1416         break;
   1417     case phymodLoopbackRemotePMD :
   1418         PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk(&phy->access, (uint8_t)enable));
   1419         break;
   1420     case phymodLoopbackRemotePCS :
   1421         /* PHYMOD_IF_ERR_RETURN(tefmod_rx_loopback_control(&phy->access, enable)); */
   1422         break;
   1423     default :
   1424         break;
   1425     }
   1426     return rv;
   1427 }
   1428 
   1429 int falcon_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   1430 {
   1431     int start_lane, num_lane;
   1432 
   1433     /*next figure out the lane num and start_lane based on the input*/
   1434     PHYMOD_IF_ERR_RETURN
   1435         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1436 
   1437     switch (loopback) {
   1438     case phymodLoopbackGlobal :
   1439         /* PHYMOD_IF_ERR_RETURN(temod_tx_loopback_get(&phy->access, &enable_core)); */
   1440         /* *enable = (enable_core >> start_lane) & 0x1; */
   1441         break;
   1442     case phymodLoopbackGlobalPMD :
   1443         PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk_get(&phy->access, enable));
   1444         break;
   1445     case phymodLoopbackRemotePMD :
   1446         PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk_get(&phy->access, enable));
   1447         break;
   1448     case phymodLoopbackRemotePCS :
   1449         /* PHYMOD_IF_ERR_RETURN(temod_rx_loopback_control(&phy->access, enable, enable, enable)); */
   1450         break;
   1451     default :
   1452         break;
   1453     }             
   1454     return PHYMOD_E_NONE;
   1455 }
   1456 
   1457 int falcon_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   1458 {
   1459     int rv;
   1460     phymod_phy_access_t phy_access, phy_access_copy;
   1461     phymod_core_access_t  core_copy;
   1462     phymod_firmware_core_config_t  firmware_core_config_tmp;
   1463     uint32_t default_pll_div=0xa;
   1464 
   1465     TSCF_CORE_TO_PHY_ACCESS(&phy_access, core);
   1466     phy_access_copy = phy_access;
   1467     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   1468     core_copy.access.lane_mask = 0x1;
   1469     phy_access_copy = phy_access;
   1470     phy_access_copy.access = core->access;
   1471     phy_access_copy.access.lane_mask = 0x1;
   1472     phy_access_copy.type = core->type;
   1473 
   1474 
   1475     
   1476     if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
   1477         PHYMOD_IF_ERR_RETURN
   1478             (falcon_pmd_reset_seq(&core_copy.access, core_status->pmd_active));
   1479     }
   1480 
   1481     /* need to set the heart beat default is for 156.25M */
   1482     PHYMOD_IF_ERR_RETURN(falcon_refclk_set(&core_copy.access,  init_config->interface.com_clock));
   1483 
   1484     rv = _falcon_core_firmware_load(&core_copy, init_config);
   1485     if (rv != PHYMOD_E_NONE) {
   1486         PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask));
   1487         PHYMOD_IF_ERR_RETURN(rv);
   1488     }
   1489 
   1490     if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
   1491         return PHYMOD_E_NONE;
   1492     }
   1493 
   1494     /*next we need to check if the load is correct or not */
   1495     if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   1496 
   1497         /*next we need to set the uc active and release uc */
   1498         PHYMOD_IF_ERR_RETURN
   1499             (falcon_uc_active_set(&core_copy.access ,1));
   1500 
   1501         /*release the uc reset */
   1502         PHYMOD_IF_ERR_RETURN
   1503             (falcon_tsc_uc_reset(&core_copy.access ,0));
   1504 
   1505 #ifndef FALCON_PMD_CRC_UCODE
   1506         if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   1507             rv = falcon_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &tscf_ucode, tscf_ucode_len);
   1508 
   1509             if (rv != PHYMOD_E_NONE) {
   1510                 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask));
   1511                 PHYMOD_IF_ERR_RETURN(rv);
   1512             }
   1513         }
   1514 #endif
   1515 
   1516         PHYMOD_IF_ERR_RETURN
   1517             (falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1));
   1518 
   1519         /* we need to wait at least 10ms for the uc to settle */
   1520         PHYMOD_USLEEP(10000);
   1521 
   1522        /* poll the ready bit in 10 ms */
   1523 #ifndef FALCON_PMD_CRC_UCODE
   1524         PHYMOD_IF_ERR_RETURN
   1525             (falcon_tsc_poll_uc_dsc_ready_for_cmd_equals_1(&phy_access_copy.access, 1));
   1526 #else
   1527         if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   1528             rv = falcon_tsc_ucode_crc_verify(&core_copy.access, tscf_ucode_len, tscf_ucode_crc);
   1529             if (rv != PHYMOD_E_NONE) {
   1530                 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC load-verify failed\n", core->access.addr, core->access.lane_mask));
   1531                 PHYMOD_IF_ERR_RETURN(rv);
   1532             }
   1533         }
   1534 #endif
   1535         PHYMOD_IF_ERR_RETURN
   1536             (falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0));
   1537     }
   1538 
   1539     /* AFE/PLL config */
   1540     if(init_config->afe_pll.afe_pll_change_default) {
   1541       PHYMOD_IF_ERR_RETURN
   1542         (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll));
   1543       firmware_core_config_tmp.disable_write_pll_iqp = 1;
   1544     } else {
   1545       PHYMOD_IF_ERR_RETURN
   1546         (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll));
   1547       firmware_core_config_tmp.disable_write_pll_iqp = 0;
   1548     }
   1549 
   1550     /* plldiv CONFIG */
   1551     PHYMOD_IF_ERR_RETURN
   1552         (falcon_pll_mode_set(&core_copy.access, default_pll_div));
   1553     /* In case of 22.5G (div 180 and ref_clk 125MHz), need to call falcon_tsc_configure_pll to set AMS_PLL_CTL values */
   1554     /* The below dead-code was added deliberately, for potential future cases, in which default_pll_div will be modified */
   1555     /* coverity[dead_error_line] */
   1556     if ((default_pll_div == 0xb) && (init_config->interface.com_clock == phymodRefClk125Mhz))
   1557     {
   1558         PHYMOD_IF_ERR_RETURN
   1559             (falcon_tsc_configure_pll (&core_copy.access, FALCON_TSC_pll_div_180x_refc125));
   1560     }
   1561 
   1562     /*now config the lane mapping and polarity */
   1563     PHYMOD_IF_ERR_RETURN
   1564         (falcon_core_lane_map_set(core, &init_config->lane_map));
   1565     /*
   1566     PHYMOD_IF_ERR_RETURN
   1567         (tscf_core_lane_map_set(core, &init_config->lane_map));
   1568     PHYMOD_IF_ERR_RETURN
   1569         (tefmod_autoneg_timer_init(&core->access));
   1570     PHYMOD_IF_ERR_RETURN
   1571         (tefmod_master_port_num_set(&core->access, 0));
   1572     */
   1573     /*don't overide the fw that set in config set if not specified*/
   1574     firmware_core_config_tmp = init_config->firmware_core_config;
   1575     firmware_core_config_tmp.CoreConfigFromPCS = 0;
   1576     /*set the vco rate to be default at 10.3125G */
   1577     firmware_core_config_tmp.VcoRate = 0x13;
   1578 
   1579     PHYMOD_IF_ERR_RETURN
   1580         (falcon_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp));
   1581 
   1582 
   1583     /* release core soft reset */
   1584     PHYMOD_IF_ERR_RETURN
   1585         (falcon_core_soft_reset_release(&core_copy.access, 1));
   1586 
   1587     return PHYMOD_E_NONE;
   1588 }
   1589 
   1590 int falcon_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
   1591 {
   1592     const phymod_access_t *pm_acc = &phy->access;
   1593     phymod_phy_access_t pm_phy_copy;
   1594     int start_lane, num_lane, i;
   1595     int lane_bkup;
   1596     phymod_polarity_t tmp_pol;
   1597 
   1598     PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol));
   1599     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1600 
   1601     /*next program the tx fir taps and driver current based on the input*/
   1602     PHYMOD_IF_ERR_RETURN
   1603         (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane));
   1604     /*per lane based reset release */
   1605     /* PHYMOD_IF_ERR_RETURN
   1606         (tefmod_pmd_x4_reset(pm_acc)); */
   1607     PHYMOD_IF_ERR_RETURN(falcon_lane_hard_soft_reset_release(&pm_phy_copy.access, 0));
   1608     PHYMOD_IF_ERR_RETURN(falcon_lane_hard_soft_reset_release(&pm_phy_copy.access, 1));
   1609     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1610     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1611     PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1612 
   1613     lane_bkup = pm_phy_copy.access.lane_mask;
   1614     for (i = 0; i < num_lane; i++) {
   1615         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1616             continue;
   1617         }
   1618         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1619         PHYMOD_IF_ERR_RETURN
   1620             (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1621     }
   1622     for (i = 0; i < num_lane; i++) {
   1623         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1624             continue;
   1625         }
   1626         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1627         PHYMOD_IF_ERR_RETURN
   1628             (falcon_lane_soft_reset_release(&pm_phy_copy.access, 0));
   1629     }
   1630     pm_phy_copy.access.lane_mask = lane_bkup;
   1631 
   1632     /* program the rx/tx polarity */
   1633     for (i = 0; i < num_lane; i++) {
   1634         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   1635         tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> (i + start_lane) & 0x1;
   1636         tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> (i + start_lane) & 0x1;
   1637         PHYMOD_IF_ERR_RETURN
   1638             (falcon_phy_polarity_set(&pm_phy_copy, &tmp_pol));
   1639     }
   1640 
   1641     for (i = 0; i < num_lane; i++) {
   1642         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1643             continue;
   1644         }
   1645         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   1646         PHYMOD_IF_ERR_RETURN
   1647             (falcon_phy_tx_set(&pm_phy_copy, &init_config->tx[i]));
   1648     }
   1649 
   1650     PHYMOD_IF_ERR_RETURN
   1651         (falcon_phy_cl72_set(&pm_phy_copy, init_config->cl72_en));
   1652 
   1653     /* ONLY for PCS
   1654     PHYMOD_IF_ERR_RETURN
   1655         (tefmod_update_port_mode(pm_acc, &pll_restart));
   1656 
   1657     PHYMOD_IF_ERR_RETURN
   1658         (tefmod_rx_lane_control_set(pm_acc, 1));
   1659     PHYMOD_IF_ERR_RETURN
   1660         (tefmod_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE));
   1661     */
   1662         
   1663         
   1664     return PHYMOD_E_NONE;
   1665     
   1666 }
   1667 
   1668 
   1669 /* this function gives the PMD_RX_LOCK_STATUS */
   1670 int falcon_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
   1671 {
   1672         
   1673     unsigned char rx_lock;
   1674     PHYMOD_IF_ERR_RETURN(falcon_tsc_pmd_lock_status(&phy->access, &rx_lock));
   1675     *link_status = (uint32_t ) rx_lock;
   1676         
   1677     return PHYMOD_E_NONE;
   1678     
   1679 }
   1680 
   1681 
   1682 int falcon_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* pmd_lock)
   1683 {
   1684         
   1685     PHYMOD_IF_ERR_RETURN(falcon_phy_link_status_get(phy, pmd_lock));
   1686     return PHYMOD_E_NONE;
   1687     
   1688 }
   1689 
   1690 /* this function gives the PMD_RX_LOCK_STATUS */
   1691 int falcon_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* signal_detect)
   1692 {
   1693         
   1694     PHYMOD_IF_ERR_RETURN(falcon_tsc_signal_detect(&phy->access, signal_detect));
   1695         
   1696     return PHYMOD_E_NONE;
   1697     
   1698 }
   1699 
   1700 int falcon_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val)
   1701 {
   1702     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val));
   1703     return PHYMOD_E_NONE;
   1704 }
   1705 
   1706 
   1707 int falcon_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
   1708 {
   1709     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val));
   1710     return PHYMOD_E_NONE;  
   1711 }
   1712 
   1713 int falcon_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 
   1714 {
   1715     int start_lane, num_lane;
   1716     phymod_phy_access_t phy_copy;
   1717     int hz_l, hz_r, vt_u, vt_d;
   1718 
   1719 
   1720     /* first get the start_lane */
   1721     PHYMOD_IF_ERR_RETURN
   1722         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1723 
   1724     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1725     phy_copy.access.lane_mask = 0x1 << start_lane;
   1726 
   1727     PHYMOD_IF_ERR_RETURN
   1728         (falcon_tsc_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d));
   1729 
   1730     switch (eye_margin_mode) {
   1731     case phymod_eye_marign_HZ_L:
   1732         *value = hz_l;
   1733         break;
   1734     case phymod_eye_marign_HZ_R:
   1735         *value = hz_r;
   1736         break;
   1737     case phymod_eye_marign_VT_U:
   1738         *value = vt_u;
   1739         break;
   1740     case phymod_eye_marign_VT_D:
   1741         *value = vt_d;
   1742         break;
   1743     default:
   1744         *value = 0;
   1745         break;
   1746     }
   1747 
   1748     return PHYMOD_E_NONE;
   1749 }
   1750 
   1751 
   1752 
   1753 int falcon_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout)
   1754 {
   1755         
   1756     
   1757     /* Not supported */
   1758     PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon_core_wait_event) \n"));
   1759 
   1760         
   1761     return PHYMOD_E_NONE;
   1762     
   1763 }
   1764 
   1765