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

viper.c (29580B)


      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_dispatch.h>
     13 #include <phymod/phymod_util.h>
     14 #include <phymod/chip/bcmi_viper_xgxs_defs.h>
     15 
     16 #include "../../viper/tier1/viper_inc.h"
     17 
     18 
     19 #define VMOD_ID0       0x0143
     20 #define VMOD_ID1       0xbff0
     21 
     22 #define VXMOD_MODEL     0x8  /*XGXS10G core*/
     23 #define VGMOD_MODEL     0xF  /*QUAD_SGMII core*/
     24 
     25 #define VIPER_NOF_DFES (5)
     26 #define VIPER_NOF_LANES_IN_CORE (4)
     27 #define VIPER_LANE_SWAP_LANE_MASK (0x3)
     28 #define VIPER_PHY_ALL_LANES (0xf)
     29 
     30 #define VIPER_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)->access.lane_mask = VIPER_PHY_ALL_LANES; \
     35     }while(0)
     36 
     37 
     38 int viper_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
     39 {
     40     int ioerr = 0 ;
     41     int rv = PHYMOD_E_NONE;
     42     const phymod_access_t * pm_acc = &core->access;
     43     COMBO_ID1r_t id1;
     44     COMBO_ID2r_t id2;
     45     SERDESID0r_t serdes_id;
     46     uint32_t model = 0;
     47     *is_identified = 0;
     48 
     49     if (core_id == 0){
     50         ioerr += READ_COMBO_ID1r(pm_acc, &id1);
     51         ioerr += READ_COMBO_ID2r(pm_acc, &id2);
     52     } else {
     53         COMBO_ID1r_SET(id1, (core_id >> 16) & 0xffff);
     54         COMBO_ID2r_SET(id2, (core_id & 0xffff));
     55     }
     56 
     57     if ((COMBO_ID1r_GET(id1) == VMOD_ID0) && (COMBO_ID2r_GET(id2) == VMOD_ID1)){
     58         /* PHY IDs match - now check Serdes model */
     59         ioerr += READ_SERDESID0r(pm_acc, &serdes_id);
     60         model = SERDESID0r_MODEL_NUMBERf_GET(serdes_id);
     61         if ((model == VGMOD_MODEL) || (model == VXMOD_MODEL)){
     62             *is_identified = 1;
     63         }
     64     }
     65 #if 0
     66     PHYMOD_VDBG(DBG_CFG, pm_acc, ("%-22s: core_id=%0x identified=%0d adr=%0x lmask=%0x rv=%d\n",
     67             __func__, core_id, *is_identified, pm_acc->addr, pm_acc->lane_mask, rv));
     68 #endif
     69     rv =  ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE;
     70 
     71     return rv;
     72 }
     73 
     74 
     75 int viper_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info)
     76 {
     77     uint32_t serdes_id;
     78     COMBO_ID1r_t id1;
     79     COMBO_ID2r_t id2;
     80     char core_name[15]="viper";
     81     const phymod_access_t * pm_acc = &core->access;
     82 
     83     PHYMOD_IF_ERR_RETURN(viper_revid_read(&core->access, &serdes_id));
     84     info->serdes_id = serdes_id;
     85     if ((serdes_id & 0x3f) == VXMOD_MODEL) {
     86         info->core_version = phymodCoreVersionViperXA0;
     87     } else {
     88         info->core_version = phymodCoreVersionViperGA0;
     89     }
     90     PHYMOD_IF_ERR_RETURN
     91         (phymod_core_name_get(core, serdes_id, core_name, info));
     92 
     93     PHYMOD_IF_ERR_RETURN(READ_COMBO_ID1r(pm_acc, &id1));
     94     PHYMOD_IF_ERR_RETURN(READ_COMBO_ID2r(pm_acc, &id2));
     95 
     96     info->phy_id0 = (uint16_t) id1.v[0];
     97     info->phy_id1 = (uint16_t) id2.v[0];
     98 
     99     return PHYMOD_E_NONE;
    100 }
    101 
    102 /*
    103  * The tx swap is TX Digital to Analog
    104  * The rx swap is RX Analog to Digital
    105  */
    106 int viper_core_lane_map_set(phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    107 {
    108     uint32_t pcs_swap = 0, pmd_swap = 0, lane;
    109 
    110     /* SGMIIPLUS2_X4 core doesn't support lane swap */
    111     if(VIPER_CORE_IS_SGMIIPLUS2_X4(&core->access)) {
    112         return PHYMOD_E_UNAVAIL;
    113     }
    114 
    115     if(lane_map->num_of_lanes != VIPER_NOF_LANES_IN_CORE){
    116         return PHYMOD_E_CONFIG;
    117     }
    118 
    119     for( lane = 0; lane < VIPER_NOF_LANES_IN_CORE; lane++){
    120         if(lane_map->lane_map_rx[lane] >= VIPER_NOF_LANES_IN_CORE){
    121             return PHYMOD_E_CONFIG;
    122         }
    123         pmd_swap += lane_map->lane_map_rx[lane]<<(lane*4);
    124     }
    125 
    126     for( lane = 0; lane < VIPER_NOF_LANES_IN_CORE; lane++){
    127         if(lane_map->lane_map_tx[lane] >= VIPER_NOF_LANES_IN_CORE){
    128             return PHYMOD_E_CONFIG;
    129         }
    130         pcs_swap += lane_map->lane_map_tx[lane]<<(lane*4);
    131     }
    132     PHYMOD_IF_ERR_RETURN(viper_tx_lane_swap(&core->access, pcs_swap));
    133 
    134     PHYMOD_IF_ERR_RETURN(viper_rx_lane_swap(&core->access, pmd_swap));
    135 
    136     return PHYMOD_E_NONE;
    137     
    138 }
    139 
    140 int viper_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
    141 {
    142     uint32_t pmd_swap = 0, pcs_swap = 0, lane;
    143 
    144     /* SGMIIPLUS2_X4 core doesn't support lane swap */
    145     if(VIPER_CORE_IS_SGMIIPLUS2_X4(&core->access)) {
    146         return PHYMOD_E_UNAVAIL;
    147     }
    148 
    149     PHYMOD_IF_ERR_RETURN(viper_tx_lane_swap_get(&core->access, &pcs_swap));
    150     PHYMOD_IF_ERR_RETURN(viper_rx_lane_swap_get(&core->access, &pmd_swap));
    151 
    152     for( lane = 0 ; lane < VIPER_NOF_LANES_IN_CORE ; lane++){
    153         /* Deccode each lane from four bits */
    154         lane_map->lane_map_rx[lane] = (pmd_swap >> (lane*4)) & VIPER_LANE_SWAP_LANE_MASK;
    155         lane_map->lane_map_tx[lane] = (pcs_swap >> (lane*4)) & VIPER_LANE_SWAP_LANE_MASK;
    156     }
    157     lane_map->num_of_lanes = VIPER_NOF_LANES_IN_CORE;
    158         
    159     return PHYMOD_E_NONE;
    160 }
    161 
    162 
    163 int viper_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
    164 {
    165     
    166     /* Place your code here */
    167         
    168     return PHYMOD_E_NONE;
    169 }
    170 
    171 int viper_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
    172 {
    173     
    174     /* Place your code here */
    175         
    176     return PHYMOD_E_NONE;
    177 }
    178 
    179 
    180 int viper_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
    181 {
    182     switch (operation) {
    183         case phymodSeqOpStop:
    184             PHYMOD_IF_ERR_RETURN
    185                 (viper_pll_sequencer_control(&core->access, 0)); 
    186         break;
    187         case phymodSeqOpStart:
    188             PHYMOD_IF_ERR_RETURN
    189                 (viper_pll_sequencer_control(&core->access, 1));
    190             
    191             /* PHYMOD_IF_ERR_RETURN
    192                 (viper_pll_lock_wait(&core->access, 250000)); */
    193         break;
    194         case phymodSeqOpRestart:
    195             PHYMOD_IF_ERR_RETURN
    196                 (viper_pll_sequencer_control(&core->access, 0));
    197             
    198             PHYMOD_IF_ERR_RETURN
    199                 (viper_pll_sequencer_control(&core->access, 1));
    200             
    201             /* PHYMOD_IF_ERR_RETURN
    202                 (viper_pll_lock_wait(&core->access, 250000)); */
    203         break;
    204         default:
    205             return PHYMOD_E_UNAVAIL;
    206         break;
    207     }
    208 
    209     return PHYMOD_E_NONE;
    210 }
    211 
    212 
    213 int viper_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout)
    214 {
    215         
    216     
    217     /* NOT NEED, REMOVE LATER  */
    218         
    219     return PHYMOD_E_NONE;
    220     
    221 }
    222 
    223 
    224 int viper_phy_rx_restart(const phymod_phy_access_t* phy)
    225 {
    226     
    227     /* NOT NEED, REMOVE LATER  */
    228         
    229     return PHYMOD_E_NONE;
    230     
    231 }
    232 
    233 
    234 int viper_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    235 {
    236     int rv = PHYMOD_E_NONE;
    237     phymod_access_t phy_copy;
    238 
    239     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    240     rv = viper_tx_pol_set(&phy_copy, polarity->tx_polarity);
    241     if (rv != PHYMOD_E_NONE) return (rv);
    242 
    243     rv = viper_rx_pol_set(&phy_copy, polarity->rx_polarity);
    244 
    245     return rv;
    246 }
    247 
    248 int viper_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    249 {
    250     int rv = PHYMOD_E_NONE;
    251     phymod_access_t phy_copy;
    252 
    253     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    254 
    255     rv = viper_tx_pol_get(&phy_copy, &polarity->tx_polarity);
    256     if (rv != PHYMOD_E_NONE) return (rv);
    257 
    258     rv = viper_rx_pol_get(&phy_copy, &polarity->rx_polarity);
    259 
    260     return rv;
    261 }
    262 
    263 
    264 int viper_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    265 {
    266     phymod_access_t phy_copy;
    267     int start_lane = 0, num_lane = 0, i;
    268 
    269     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    270 
    271     PHYMOD_IF_ERR_RETURN
    272         (phymod_util_lane_config_get(&phy_copy, &start_lane, &num_lane));
    273 
    274     for (i = 0; i < num_lane; i++) {
    275          phy_copy.lane_mask = 0x1 << (i + start_lane);
    276 
    277          PHYMOD_IF_ERR_RETURN(viper_tx_post_set(&phy_copy, 1, (tx->post & 0xff)));
    278          PHYMOD_IF_ERR_RETURN(viper_tx_main_set(&phy_copy, (tx->main  & 0xff)));
    279     }
    280 
    281     return PHYMOD_E_NONE;
    282 
    283 }
    284 
    285 int viper_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    286 {
    287     uint32_t tx_value, enable;
    288     phymod_access_t phy_copy;
    289 
    290     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    291 
    292     PHYMOD_IF_ERR_RETURN(viper_tx_post_get(&phy_copy, &enable, &tx_value));
    293     tx->post = tx_value & 0xff;
    294 
    295     PHYMOD_IF_ERR_RETURN(viper_tx_main_get(&phy_copy, &tx_value));
    296     tx->main = tx_value & 0xff;
    297 
    298     return PHYMOD_E_NONE;
    299 }
    300 
    301 
    302 int viper_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    303 {
    304     phymod_access_t phy_copy;
    305 
    306     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    307     PHYMOD_IF_ERR_RETURN(viper_rx_pf_set(&phy_copy, rx->peaking_filter.value));
    308 
    309     return PHYMOD_E_NONE;
    310 
    311 }
    312 
    313 int viper_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    314 {
    315     uint32_t rx_value;
    316     phymod_access_t phy_copy;
    317 
    318     PHYMOD_MEMCPY(&phy_copy, &(phy->access), sizeof(phy_copy));
    319 
    320     PHYMOD_IF_ERR_RETURN(viper_rx_pf_get(&phy_copy, &rx_value));
    321     rx->peaking_filter.value = rx_value;
    322 
    323     return PHYMOD_E_NONE;
    324 
    325 }
    326 
    327 
    328 int viper_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    329 {
    330         
    331     
    332     /* Place your code here */
    333 
    334         
    335     return PHYMOD_E_NONE;
    336     
    337 }
    338 
    339 int viper_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    340 {
    341         
    342     
    343     /* Place your code here */
    344 
    345         
    346     return PHYMOD_E_NONE;
    347     
    348 }
    349 
    350 
    351 int viper_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
    352 {
    353     int rv = PHYMOD_E_NONE;
    354     int combo = 0;
    355     viper_actual_speed_id_t speed_id;
    356 
    357     PHYMOD_IF_ERR_RETURN(viper_actual_speed_get(&phy->access, &speed_id));
    358     if (speed_id == VIPER_SPD_10G_CX4)  {
    359         combo = 1;
    360     }
    361 
    362     if (power->tx | power->rx){
    363         rv = viper_phy_enable_set(&phy->access, 1, combo);     
    364     } else {
    365         rv = viper_phy_enable_set(&phy->access, 0, combo);     
    366     }
    367 
    368     return rv;
    369 }
    370 
    371 int viper_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
    372 {
    373 
    374     int rv = PHYMOD_E_NONE; 
    375     int enable = 0;
    376             
    377     rv = viper_phy_enable_get(&phy->access, &enable);
    378     if (rv != PHYMOD_E_NONE) return (rv);
    379     power->tx = enable;
    380     power->rx = enable;
    381         
    382     return rv;
    383     
    384 }
    385 
    386 
    387 int viper_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    388 {
    389         
    390     
    391     /*NOT NEED, REMOVE LATER */
    392         
    393     return PHYMOD_E_NONE;
    394     
    395 }
    396 
    397 int viper_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    398 {
    399         
    400     
    401     /*NOT NEED, REMOVE LATER */
    402         
    403     return PHYMOD_E_NONE;
    404     
    405 }
    406 
    407 
    408 int viper_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    409 {
    410         
    411     
    412     /*NOT NEED, REMOVE LATER */
    413         
    414     return PHYMOD_E_NONE;
    415     
    416 }
    417 
    418 int viper_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    419 {
    420         
    421     
    422     /*NOT NEED, REMOVE LATER */
    423         
    424     return PHYMOD_E_NONE;
    425     
    426 }
    427 
    428 
    429 int viper_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    430 {
    431         
    432     
    433     /*NOT NEED, REMOVE LATER */
    434         
    435     return PHYMOD_E_NONE;
    436     
    437 }
    438 
    439 int viper_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    440 {
    441         
    442     
    443     /*NOT NEED, REMOVE LATER */
    444         
    445     return PHYMOD_E_NONE;
    446     
    447 }
    448 
    449 
    450 int viper_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable)
    451 {
    452     uint32_t lpi_bypass;
    453     int rv = PHYMOD_E_NONE ;
    454     lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable);
    455     enable &= 0x1;
    456     if (lpi_bypass) {
    457         rv = viper_lpi_enable_set(&phy->access,enable);
    458     } else {
    459         return PHYMOD_E_UNAVAIL;
    460     }
    461 
    462     return rv;
    463 }
    464 
    465 int viper_phy_eee_get(const phymod_phy_access_t* phy, uint32_t* enable)
    466 {
    467     if (PHYMOD_LPI_BYPASS_GET(*enable)) {
    468         PHYMOD_IF_ERR_RETURN(viper_lpi_enable_get(&phy->access, enable));
    469         PHYMOD_LPI_BYPASS_SET(*enable);
    470     } else {
    471         return PHYMOD_E_UNAVAIL;
    472     }
    473     return PHYMOD_E_NONE;
    474 }
    475 
    476 int viper_phy_linkdown_transmit_set(const phymod_phy_access_t* phy, uint32_t enable)
    477 {
    478     PHYMOD_IF_ERR_RETURN(viper_linkdown_transmit_set(&phy->access, enable));
    479 
    480     return PHYMOD_E_NONE;
    481 }
    482 
    483 int viper_phy_linkdown_transmit_get(const phymod_phy_access_t* phy, uint32_t* enable)
    484 {
    485     PHYMOD_IF_ERR_RETURN(viper_linkdown_transmit_get(&phy->access, enable));
    486 
    487     return PHYMOD_E_NONE;
    488 }
    489 
    490 int viper_phy_interface_config_set(phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
    491 {
    492     
    493     viper_spd_intfc_type_t spd_intf = VIPER_SPD_ILLEGAL;
    494 
    495     if  (config->interface_type == phymodInterfaceSGMII) {
    496         switch (config->data_rate) {
    497             case 10:
    498                 spd_intf = VIPER_SPD_10_SGMII;
    499                 break;
    500             case 100:
    501                 spd_intf = VIPER_SPD_100_SGMII;
    502                 break;
    503             case 1000:
    504                 spd_intf = VIPER_SPD_1000_SGMII;
    505                 break;
    506             default:
    507                 spd_intf = VIPER_SPD_1000_SGMII;
    508                 break;
    509         }
    510    } else if (config->interface_type == phymodInterface1000X) {
    511         switch (config->data_rate) {
    512             case 100:
    513                 spd_intf = VIPER_SPD_100_FX;
    514                 break;
    515             case 1000:
    516                 spd_intf = VIPER_SPD_1000_X1;
    517                 break;
    518             case 2500:
    519                 spd_intf = VIPER_SPD_2500;
    520                 break;
    521             default:
    522                 spd_intf = VIPER_SPD_1000_X1;
    523                 break;
    524         }
    525     } else if (config->interface_type == phymodInterfaceXAUI) {
    526         /* SGMIIPLUS2_X4 core doesn't support 10G */
    527         if(VIPER_CORE_IS_SGMIIPLUS2_X4(&phy->access)) {
    528             return PHYMOD_E_UNAVAIL;
    529         }
    530 
    531         if (config->data_rate == 10000) {
    532             spd_intf = VIPER_SPD_10000_CX4;
    533         }
    534     }
    535     PHYMOD_IF_ERR_RETURN
    536         (viper_set_spd_intf(&phy->access, spd_intf));
    537 
    538     if (config->interface_type == phymodInterfaceXAUI){
    539         if(VIPER_CORE_IS_SGMIIPLUS2_X4(&phy->access)) {
    540             return PHYMOD_E_UNAVAIL;
    541         }
    542         PHYMOD_IF_ERR_RETURN
    543             (viper_10G_CX4_compliance_set(&phy->access, 0xe));
    544    }
    545 
    546    return PHYMOD_E_NONE;
    547     
    548 }
    549 
    550 
    551 int viper_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)
    552 {
    553     viper_actual_speed_id_t speed_id;
    554     
    555     PHYMOD_IF_ERR_RETURN(viper_actual_speed_get(&phy->access, &speed_id));
    556     PHYMOD_IF_ERR_RETURN(viper_speed_id_interface_config_get(phy, speed_id, config));
    557 
    558     return PHYMOD_E_NONE;
    559     
    560 }
    561 
    562 
    563 int viper_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type)
    564 {
    565     viper_an_ability_t value;
    566 
    567     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
    568 
    569     /* check if sgmii  or not */
    570     if (PHYMOD_AN_CAP_SGMII_GET(an_ability_set_type)) {
    571         switch (an_ability_set_type->sgmii_speed) {
    572             case phymod_CL37_SGMII_10M:
    573                 value.cl37_sgmii_speed = VIPER_CL37_SGMII_10M;
    574                 break;
    575             case phymod_CL37_SGMII_100M:
    576                 value.cl37_sgmii_speed = VIPER_CL37_SGMII_100M;
    577                 break;
    578             case phymod_CL37_SGMII_1000M:
    579                 value.cl37_sgmii_speed = VIPER_CL37_SGMII_1000M;
    580                 break;
    581             default:
    582                 value.cl37_sgmii_speed = VIPER_CL37_SGMII_1000M;
    583                 break;
    584         }
    585     }
    586 
    587     /* next check pause */
    588     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability_set_type) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability_set_type)) {
    589         value.an_pause = VIPER_SYMM_PAUSE;
    590     }
    591     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability_set_type) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability_set_type)) {
    592         value.an_pause = VIPER_ASYM_PAUSE;
    593     }
    594     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability_set_type) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability_set_type)) {
    595         value.an_pause = VIPER_ASYM_SYMM_PAUSE;
    596     }
    597 
    598     PHYMOD_IF_ERR_RETURN(viper_autoneg_local_ability_set(&phy->access, &value));
    599 
    600     return PHYMOD_E_NONE;
    601 }
    602 
    603 int viper_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    604 {
    605     viper_an_adv_ability_t value;
    606 
    607     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
    608 
    609     PHYMOD_IF_ERR_RETURN(viper_autoneg_local_ability_get(&phy->access, &value));
    610     switch (value.cl37_sgmii_speed){
    611     case VIPER_CL37_SGMII_10M:
    612         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M;
    613         break;
    614     case VIPER_CL37_SGMII_100M:
    615         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M;
    616         break;
    617     case VIPER_CL37_SGMII_1000M:
    618         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M;
    619         break;
    620     default:
    621         break;
    622     }
    623 
    624     switch(value.an_pause) {
    625     case VIPER_ASYM_PAUSE:
    626         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
    627         break;
    628     case VIPER_SYMM_PAUSE:
    629         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
    630         break;
    631     case VIPER_ASYM_SYMM_PAUSE:
    632         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
    633         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
    634         break;
    635     default:
    636         break;
    637     }
    638 
    639     return PHYMOD_E_NONE;
    640     
    641 }
    642 
    643 
    644 int viper_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    645 {
    646     viper_an_adv_ability_t value;
    647 
    648     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
    649 
    650     PHYMOD_IF_ERR_RETURN(viper_autoneg_remote_ability_get(&phy->access, &value));
    651     switch (value.cl37_sgmii_speed){
    652     case VIPER_CL37_SGMII_10M:
    653         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M;
    654         break;
    655     case VIPER_CL37_SGMII_100M:
    656         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M;
    657         break;
    658     case VIPER_CL37_SGMII_1000M:
    659         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M;
    660         break;
    661     default:
    662         break;
    663     }
    664 
    665     switch(value.an_pause) {
    666     case VIPER_ASYM_PAUSE:
    667         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
    668         break;
    669     case VIPER_SYMM_PAUSE:
    670         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
    671         break;
    672     case VIPER_ASYM_SYMM_PAUSE:
    673         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
    674         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
    675         break;
    676     default:
    677         break;
    678     }
    679 
    680     return PHYMOD_E_NONE;
    681 }
    682 
    683 
    684 int viper_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
    685 {
    686     PHYMOD_IF_ERR_RETURN(viper_autoneg_set(&phy->access, an));
    687 
    688     return PHYMOD_E_NONE;
    689     
    690 }
    691 
    692 int viper_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
    693 {
    694        
    695     PHYMOD_IF_ERR_RETURN(viper_autoneg_get(&phy->access, an, an_done));
    696        
    697     return PHYMOD_E_NONE;
    698     
    699 }
    700 
    701 
    702 int viper_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status)
    703 {
    704    return (viper_autoneg_status_get(&phy->access, status)); 
    705 }
    706 
    707 int viper_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
    708 {
    709     phymod_core_access_t  core_copy;
    710     phymod_core_access_t  core_copy2;
    711 
    712     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
    713     core_copy.access.lane_mask = 0x1;
    714     PHYMOD_MEMCPY(&core_copy2, core, sizeof(core_copy2));
    715 
    716     /* Enable multiple MMD */
    717     PHYMOD_IF_ERR_RETURN(viper_multimmds_set(&core_copy.access, 1));
    718 
    719     if (init_config->interface.interface_type == phymodInterfaceXAUI){
    720         /* SGMIIPLUS2_X4 core doesn't support 10G */
    721         if(VIPER_CORE_IS_SGMIIPLUS2_X4(&core->access)) {
    722             return PHYMOD_E_UNAVAIL;
    723         }
    724         PHYMOD_IF_ERR_RETURN(viper_multimmds_set(&core_copy.access, 0));
    725         PHYMOD_IF_ERR_RETURN(viper_pll_disable_forced_10G(&core_copy.access));
    726         PHYMOD_IF_ERR_RETURN
    727             (viper_xgxs_sel_enable(&core_copy.access, 1));
    728 
    729         if ((core_copy2.access.lane_mask == 0x1) || (core_copy2.access.lane_mask == 0xf)){
    730             PHYMOD_IF_ERR_RETURN
    731                 (viper_core_lane_map_set(&core_copy2, &init_config->lane_map));
    732         }
    733         PHYMOD_IF_ERR_RETURN(viper_pll_enable_forced_10G(&core_copy.access));
    734     } else {
    735         /* Some cores' TXPLL are not stable when reset chip with default cal_th value 0x6.
    736          * To get TXPLL stable, change SGMIIPlus2 PLL calibration threshold from 0x6 to 0xc before PLL disable/enable.
    737          * To be fixed after ASIC/DEV team confirm the rootcause.
    738         */
    739         if(VIPER_CORE_IS_SGMIIPLUS2_X4(&core->access)) {
    740             PHYMOD_IF_ERR_RETURN(viper_cal_th_set(&core_copy.access, 0xc));
    741         }
    742 
    743         PHYMOD_IF_ERR_RETURN(viper_pll_disable(&core_copy.access));
    744         PHYMOD_IF_ERR_RETURN
    745             (viper_xgxs_sel_enable(&core_copy.access, 1));
    746         /* SGMIIPLUS2_X4 doesn't support lane swap */
    747         if (VIPER_CORE_IS_XGXS_10G_028(&core->access)) {
    748             if ((core_copy2.access.lane_mask == 0x1) || (core_copy2.access.lane_mask == 0xf)){
    749                 PHYMOD_IF_ERR_RETURN
    750                     (viper_core_lane_map_set(&core_copy2, &init_config->lane_map));
    751             }
    752         }
    753         PHYMOD_IF_ERR_RETURN(viper_pll_enable(&core_copy.access));
    754 
    755     }
    756     return PHYMOD_E_NONE;
    757 }
    758 
    759 
    760 int viper_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* core_vco_pll_multiplier)
    761 {
    762     
    763     /* NOT NEED REMOVE LATER  */
    764 
    765     return PHYMOD_E_NONE;
    766     
    767 }
    768 
    769 
    770 int viper_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
    771 {
    772 
    773     /*int pll_restart = 0;*/
    774     const phymod_access_t *pm_acc = &phy->access;
    775     phymod_phy_access_t pm_phy_copy;
    776     phymod_polarity_t tmp_pol;
    777     int start_lane = 0, num_lane = 0, i; 
    778 
    779     PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol));
    780     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    781     
    782     PHYMOD_IF_ERR_RETURN
    783         (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane));
    784 
    785     /* set the receive input voltage (differential pk-pk) to 1200 mVppd */
    786     for ( i = 0; i < num_lane; i++){
    787         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    788 
    789         PHYMOD_IF_ERR_RETURN
    790             (viper_rx_large_swing_set(&pm_phy_copy.access, init_config->rx_swing));
    791     }
    792 
    793     /* program the rx/tx polarity */
    794     for (i = 0; i < num_lane; i++) {
    795         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    796         tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1;
    797         tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1;
    798         PHYMOD_IF_ERR_RETURN
    799             (viper_phy_polarity_set(&pm_phy_copy, &tmp_pol));
    800     }
    801 
    802     for(i = 0; i < num_lane; i++)
    803     {
    804         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    805         /*init hw rx_los:enable signal detect*/
    806         if(init_config->rx_los.rx_los_en)
    807         {
    808             PHYMOD_IF_ERR_RETURN
    809                 (viper_signal_detect_set(&pm_phy_copy.access));
    810         }
    811 
    812          /*init hw rx_los:invert signal detect*/
    813         if(init_config->rx_los.rx_los_invert_en)
    814         {
    815             PHYMOD_IF_ERR_RETURN
    816                 (viper_signal_invert_set(&pm_phy_copy.access));
    817         }
    818     }
    819 #if 0
    820     for (i = 0; i < num_lane; i++) {
    821         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    822         PHYMOD_IF_ERR_RETURN
    823             (viper_phy_tx_set(&pm_phy_copy, &init_config->tx[i]));
    824     }
    825 #endif
    826     pm_phy_copy.access.lane_mask = 0x1;
    827 
    828     /* PHYMOD_IF_ERR_RETURN
    829         (viper_update_port_mode(pm_acc, &pll_restart));
    830 
    831     PHYMOD_IF_ERR_RETURN
    832         (viper_rx_lane_control_set(pm_acc, 1));
    833     PHYMOD_IF_ERR_RETURN
    834         (viper_tx_lane_control_set(pm_acc, TEMOD_TX_LANE_RESET_TRAFFIC_ENABLE));       
    835      */
    836 
    837     return PHYMOD_E_NONE;
    838  
    839 }
    840 
    841 
    842 int viper_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
    843 {
    844     /*PHYMOD_IF_ERR_RETURN(viper_global_loopback_set(&phy->access, (uint8_t) enable));*/
    845     viper_actual_speed_id_t speed_id;
    846     uint32_t fx_mode = 0;
    847 
    848     PHYMOD_IF_ERR_RETURN(viper_actual_speed_get(&phy->access, &speed_id));
    849 
    850     switch (loopback) {
    851     case phymodLoopbackGlobal :
    852         if (speed_id == VIPER_SPD_10G_CX4) {
    853             /* SGMIIPLUS2_X4 core doesn't support 10G */
    854             if(VIPER_CORE_IS_SGMIIPLUS2_X4(&phy->access)) {
    855                 return PHYMOD_E_UNAVAIL; 
    856             }
    857             PHYMOD_IF_ERR_RETURN(viper_10g_global_loopback_set(&phy->access, (uint8_t) enable));
    858         } else { 
    859             PHYMOD_IF_ERR_RETURN(viper_fiber_force_100FX_get(&phy->access, &fx_mode));
    860             if ((speed_id == VIPER_SPD_100M) && fx_mode ){
    861                 PHYMOD_IF_ERR_RETURN(viper_100FX_global_loopback_set(&phy->access, (uint8_t) enable));
    862             } else {
    863                 PHYMOD_IF_ERR_RETURN(viper_global_loopback_set(&phy->access, (uint8_t) enable));
    864             }
    865         }
    866         break;
    867     case phymodLoopbackGlobalPMD :
    868          return PHYMOD_E_UNAVAIL;
    869     case phymodLoopbackRemotePCS :
    870          break;
    871     case phymodLoopbackRemotePMD :
    872         PHYMOD_IF_ERR_RETURN(viper_remote_loopback_set(&phy->access, speed_id, (uint8_t)enable));
    873         break;
    874     default :
    875         break;
    876     }    
    877 
    878     return  PHYMOD_E_NONE;
    879 }
    880 
    881 int viper_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
    882 {
    883     viper_actual_speed_id_t speed_id;
    884     uint32_t fx_mode = 0;
    885 
    886     PHYMOD_IF_ERR_RETURN(viper_actual_speed_get(&phy->access, &speed_id));
    887 
    888     switch (loopback) {
    889     case phymodLoopbackGlobal :
    890         if (speed_id == VIPER_SPD_10G_CX4)  {
    891             /* SGMIIPLUS2_X4 core doesn't support 10G */
    892             if(VIPER_CORE_IS_SGMIIPLUS2_X4(&phy->access)) {
    893                 return PHYMOD_E_UNAVAIL;
    894             }
    895             PHYMOD_IF_ERR_RETURN(viper_10g_global_loopback_get(&phy->access, enable));
    896         } else {
    897             PHYMOD_IF_ERR_RETURN(viper_fiber_force_100FX_get(&phy->access, &fx_mode));
    898             if ((speed_id == VIPER_SPD_100M) && fx_mode ){
    899                 PHYMOD_IF_ERR_RETURN(viper_100FX_global_loopback_get(&phy->access, enable));
    900             } else {
    901                 PHYMOD_IF_ERR_RETURN(viper_global_loopback_get(&phy->access, enable));
    902             }
    903         }
    904         break;
    905     case phymodLoopbackGlobalPMD :
    906         return PHYMOD_E_UNAVAIL;
    907     case phymodLoopbackRemotePCS :
    908          break;
    909     case phymodLoopbackRemotePMD :
    910         PHYMOD_IF_ERR_RETURN(viper_remote_loopback_get(&phy->access, speed_id, enable));
    911         break;
    912     default :
    913         break;
    914     }
    915     return PHYMOD_E_NONE;
    916 }
    917 
    918 
    919 int viper_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
    920 {
    921         
    922     
    923     /* NOT NEED REMOVE LATER */
    924 
    925     
    926     *rx_pmd_locked = 1;
    927 
    928     return PHYMOD_E_NONE;
    929     
    930 }
    931 
    932 
    933 int viper_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
    934 {
    935     viper_actual_speed_id_t speed_id;
    936 
    937     PHYMOD_IF_ERR_RETURN(viper_actual_speed_get(&phy->access, &speed_id));
    938     
    939     if (speed_id == VIPER_SPD_10G_CX4 ) {
    940         /* SGMIIPLUS2_X4 core doesn't support 10G */
    941         if(VIPER_CORE_IS_SGMIIPLUS2_X4(&phy->access)) {
    942             return PHYMOD_E_UNAVAIL;
    943         }
    944         PHYMOD_IF_ERR_RETURN (viper_get_link_status_10G(&phy->access, link_status));
    945     } else {
    946         PHYMOD_IF_ERR_RETURN (viper_get_link_status(&phy->access, link_status));
    947     }
    948     return PHYMOD_E_NONE;
    949 
    950     
    951 }
    952 
    953 
    954 int viper_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config)
    955 {
    956         
    957     
    958     /* NOT NEED REMOVE LATER */
    959         
    960     return PHYMOD_E_NONE;
    961     
    962 }
    963 
    964 int viper_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config)
    965 {
    966     /* NOT NEED REMOVE LATER */
    967         
    968     return PHYMOD_E_NONE;
    969     
    970 }
    971 
    972 
    973 int viper_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val)
    974 {
    975     return(phymod_tsc_iblk_read(&phy->access, reg_addr, val));        
    976 }
    977 
    978 
    979 int viper_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
    980 {
    981     return (phymod_tsc_iblk_write(&phy->access, reg_addr, val));
    982 }
    983 
    984 int viper_phy_rx_ppm_get(const phymod_phy_access_t* phy, uint32_t* rx_ppm)
    985 {
    986     /* Viper doesn't support rx_ppm which is from DSC. */
    987     return PHYMOD_E_UNAVAIL;
    988 }
    989 
    990 int viper_phy_duplex_set(const phymod_phy_access_t* phy, phymod_duplex_mode_t duplex)
    991 {
    992     viper_duplex_mode_t duplex_mode;
    993 
    994     switch (duplex) {
    995         case phymodDuplexHalf:
    996             duplex_mode = VIPER_DUPLEX_HALF;
    997             break;
    998         case phymodDuplexFull:
    999             duplex_mode = VIPER_DUPLEX_FULL;
   1000             break;
   1001         default:
   1002             duplex_mode = VIPER_DUPLEX_FULL;
   1003             break;
   1004     }
   1005     PHYMOD_IF_ERR_RETURN(viper_duplex_set(&phy->access, duplex_mode));
   1006 
   1007     return PHYMOD_E_NONE;
   1008 }
   1009 
   1010 int viper_phy_duplex_get(const phymod_phy_access_t* phy, phymod_duplex_mode_t* duplex)
   1011 {
   1012     viper_duplex_mode_t duplex_mode;
   1013 
   1014     PHYMOD_IF_ERR_RETURN(viper_duplex_get(&phy->access, &duplex_mode));
   1015     switch (duplex_mode) {
   1016         case VIPER_DUPLEX_HALF:
   1017             *duplex = phymodDuplexHalf;
   1018             break;
   1019         case VIPER_DUPLEX_FULL:
   1020             *duplex = phymodDuplexFull;
   1021             break;
   1022         default:
   1023             *duplex = phymodDuplexFull;
   1024             break;
   1025     }
   1026 
   1027     return PHYMOD_E_NONE;
   1028 }
   1029