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

tsce16.c (103536B)


      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_debug.h>
     13 #include <phymod/phymod_util.h>
     14 #include <phymod/chip/bcmi_tsce16_xgxs_defs.h>
     15 #include <phymod/chip/tsce16.h>
     16 #include "tsce16/tier1/temod16_enum_defines.h"
     17 #include "tsce16/tier1/temod16.h"
     18 #include "tsce16/tier1/te16PCSRegEnums.h"
     19 #include "merlin16/tier1/merlin16_cfg_seq.h"
     20 #include "merlin16/tier1/merlin16_common.h"
     21 #include "merlin16/tier1/merlin16_interface.h"
     22 #include "merlin16/tier1/merlin16_debug_functions.h"
     23 #include "merlin16/tier1/merlin16_dependencies.h"
     24 #include "merlin16/tier1/merlin16_internal.h"
     25 
     26 #define TSCE16_ID0          0x600d
     27 #define TSCE16_ID1          0x8770
     28 
     29 #define TSCE16_MODEL        0x12
     30 #define TSCE16_TECH_PROC    0x4     /* 16nm */
     31 
     32 #define TSCE16_NOF_LANES_IN_CORE (4)
     33 #define TSCE16_PHY_ALL_LANES (0xf)
     34 #define TSCE16_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \
     35     do{\
     36         PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\
     37         (_phy_access)->type           = (_core_access)->type; \
     38         (_phy_access)->port_loc       = (_core_access)->port_loc; \
     39         (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \
     40         (_phy_access)->access.lane_mask = TSCE16_PHY_ALL_LANES; \
     41     }while(0)
     42 
     43 #define TSCE16_PMD_CRC_UCODE  1
     44 /* uController's firmware */
     45 extern unsigned char merlin16_ucode[];
     46 extern unsigned short merlin16_ucode_ver;
     47 extern unsigned short merlin16_ucode_crc;
     48 extern unsigned short merlin16_ucode_len;
     49 
     50 typedef int (*sequncer_control_f)(const phymod_access_t* core, uint32_t enable);
     51 typedef int (*rx_DFE_tap_control_set_f)(const phymod_access_t* phy, uint32_t val);
     52 extern int tsce16_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);
     53 
     54 
     55 STATIC
     56 int _tsce16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
     57 {
     58     struct merlin16_uc_lane_config_st serdes_firmware_config;
     59     phymod_phy_access_t phy_copy;
     60     int start_lane, num_lane, i;
     61     /* uint32_t rst_status; */
     62     uint32_t is_warm_boot;
     63 
     64     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
     65     PHYMOD_IF_ERR_RETURN
     66         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
     67     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
     68 
     69     for (i = 0; i < num_lane; i++) {
     70         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
     71             continue;
     72         }
     73         phy_copy.access.lane_mask = 1 << (start_lane + i);
     74         serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS;
     75         serdes_firmware_config.field.an_enabled        = fw_config.AnEnabled;
     76         serdes_firmware_config.field.dfe_on            = fw_config.DfeOn;
     77         serdes_firmware_config.field.force_brdfe_on    = fw_config.ForceBrDfe;
     78         /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */
     79         serdes_firmware_config.field.scrambling_dis    = fw_config.ScramblingDisable;
     80         serdes_firmware_config.field.unreliable_los    = fw_config.UnreliableLos;
     81         serdes_firmware_config.field.media_type        = fw_config.MediaType;
     82         serdes_firmware_config.field.cl72_auto_polarity_en   = fw_config.Cl72AutoPolEn;
     83         serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO;
     84 
     85         PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot));
     86 
     87 		
     88         if (!is_warm_boot) {
     89             /* PHYMOD_IF_ERR_RETURN(merlin16_lane_soft_reset_read(&phy_copy.access, &rst_status)); */
     90             /* if (rst_status) */ PHYMOD_IF_ERR_RETURN (merlin16_lane_soft_reset_release(&phy_copy.access, 0));
     91             PHYMOD_IF_ERR_RETURN(merlin16_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config));
     92             /* if (rst_status) */ PHYMOD_IF_ERR_RETURN (merlin16_lane_soft_reset_release(&phy_copy.access, 1));
     93         }
     94     }
     95     return PHYMOD_E_NONE;
     96 }
     97 
     98 int tsce16_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
     99 {
    100     int ioerr = 0;
    101     const phymod_access_t *pm_acc = &core->access;
    102     PHYID2r_t id2;
    103     PHYID3r_t id3;
    104     MAIN0_SERDESIDr_t serdesid;
    105     /* DIG_REVID0r_t revid; */
    106     uint32_t model;
    107     int rv;
    108     *is_identified = 0;
    109 
    110 #ifdef PHYMOD_DIAG
    111     /*
    112     LOG_ERROR(BSL_LS_SOC_PHYMOD,("%-22s: core_id=%0d adr=%0x lane_mask=%0x v_adr=%0x v_mask=%0x\n",
    113     __func__, core_id, pm_acc->addr, pm_acc->lane_mask, phymod_dbg_addr, phymod_dbg_mask)); */
    114 	PHYMOD_VDBG(DBG_CFG, pm_acc,("%-22s: core_id=%0d adr=%0"PRIx32" lane_mask=%0"PRIx32"\n",
    115                                  __func__, (int)core_id, pm_acc->addr, pm_acc->lane_mask));
    116 #endif
    117     if (core_id == 0) {
    118         ioerr += READ_PHYID2r(pm_acc, &id2);
    119         ioerr += READ_PHYID3r(pm_acc, &id3);
    120     } else {
    121         PHYID2r_SET(id2, ((core_id >> 16) & 0xffff));
    122         PHYID3r_SET(id3, core_id & 0xffff);
    123     }
    124 
    125     if (PHYID2r_GET(id2) == TSCE16_ID0 && PHYID3r_GET(id3) == TSCE16_ID1) {
    126         /* PHY IDs match - now check PCS model */
    127         ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdesid);
    128         model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid);
    129         if (model == TSCE16_MODEL) {
    130             if (MAIN0_SERDESIDr_TECH_PROCf_GET(serdesid) == TSCE16_TECH_PROC) {
    131                 *is_identified = 1;
    132             }
    133         }
    134     }
    135     rv = ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE;
    136 #ifdef PHYMOD_DIAG
    137 	PHYMOD_VDBG(DBG_CFG, pm_acc,("%-22s: core_id=%0d identified=%0d rv=%0d adr=%0"PRIx32" lmask=%0"PRIx32"\n",
    138                                        __func__, (int)core_id, (int)*is_identified, rv, pm_acc->addr, pm_acc->lane_mask));
    139 #endif
    140     return rv;
    141 }
    142 
    143 int tsce16_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info)
    144 {
    145     uint32_t serdes_id;
    146     PHYID2r_t id2;
    147     PHYID3r_t id3;
    148      char core_name[15]="Tsce16";
    149     const phymod_access_t *pm_acc = &phy->access;
    150 
    151     PHYMOD_IF_ERR_RETURN
    152         (temod16_revid_read(&phy->access, &serdes_id));
    153     PHYMOD_IF_ERR_RETURN
    154         (phymod_core_name_get(phy, serdes_id, core_name, info));
    155 
    156     info->serdes_id = serdes_id;
    157     info->core_version = phymodCoreVersionTsce16;
    158 
    159     PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2));
    160     PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3));
    161 
    162     info->phy_id0 = (uint16_t) id2.v[0];
    163     info->phy_id1 = (uint16_t) id3.v[0];
    164 
    165     return PHYMOD_E_NONE;
    166 }
    167 
    168 /* set lane swapping for core
    169  */
    170 int tsce16_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    171 {
    172     uint32_t pcs_swap = 0 , lane;
    173     uint8_t pmd_tx_lane_map[PHYMOD_MAX_LANES_PER_CORE];
    174     uint8_t pmd_rx_lane_map[PHYMOD_MAX_LANES_PER_CORE];
    175     uint8_t num_lanes = (uint8_t) lane_map->num_of_lanes;
    176 
    177 #ifdef PHYMOD_DIAG
    178     const phymod_access_t *pm_acc;
    179     pm_acc = &core->access;
    180     PHYMOD_VDBG(DBG_TOP, pm_acc,
    181        ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" rx_lane_map=%0"PRIx32"%0"PRIx32"%0"PRIx32"%0"PRIx32" tx_lane_map=%0"PRIx32"%0"PRIx32"%0"PRIx32"%0"PRIx32"\n",
    182         __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask,
    183         lane_map->lane_map_rx[3], lane_map->lane_map_rx[2],
    184         lane_map->lane_map_rx[1], lane_map->lane_map_rx[0],
    185         lane_map->lane_map_tx[3], lane_map->lane_map_tx[2],
    186         lane_map->lane_map_tx[1], lane_map->lane_map_tx[0]));
    187 #endif
    188 
    189     /* PCS lane map; PCS lane map specifies which board-side lane a switch-side lane should
    190      * connect to. For instance, on the bring-up board, for TX, lane[0] on the switch is
    191      * actually routed to lane[2] on the board; lane[2] on the switch is routed to lane[0]
    192      * on the board. In this case, "2" should be put in lane_map_tx[0], and "0" should be
    193      * put in lane_map_tx[2].
    194     */
    195     if (lane_map->num_of_lanes != TSCE16_NOF_LANES_IN_CORE) {
    196         return PHYMOD_E_CONFIG;
    197     }
    198 
    199     for (lane = 0; lane < TSCE16_NOF_LANES_IN_CORE; lane++) {
    200         pcs_swap += lane_map->lane_map_tx[lane] << (lane*4);
    201         pcs_swap += lane_map->lane_map_rx[lane] << (lane*4 + 16);
    202     }
    203 
    204     if (!PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) {
    205         PHYMOD_IF_ERR_RETURN(temod16_pcs_lane_swap(&core->access, pcs_swap));
    206     }
    207 
    208     /* PMD lane address map; PCS lane map specifies the lane map from switch's point of
    209      * view, while PMD lane address map specifies the same lane map from board's point
    210      * of view.
    211      * For instance, if PCS specify that lane[0] on the switch TX side connects to lane[2]
    212      * on the board TX side, PCS would put "2" in lane_map_tx[0], and PMD would put "0"
    213      * in lane_map_tx[2]. From PMD's point of view, this means that board lane[2] should
    214      * connect to switch lane[0].
    215      */
    216     for (lane = 0; lane < TSCE16_NOF_LANES_IN_CORE; lane++) {
    217         pmd_tx_lane_map[(int)lane_map->lane_map_tx[lane]] = lane;
    218         pmd_rx_lane_map[(int)lane_map->lane_map_rx[lane]] = lane;
    219     }
    220 
    221     PHYMOD_IF_ERR_RETURN
    222         (merlin16_map_lanes(&core->access, num_lanes, pmd_tx_lane_map, pmd_rx_lane_map));
    223 
    224     return PHYMOD_E_NONE;
    225 }
    226 
    227 /* load tsce fw. the fw_loader parameter is valid just for external fw load */
    228 STATIC
    229 int _tsce16_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader)
    230 {
    231 #ifdef PHYMOD_DIAG
    232     const phymod_access_t *pm_acc;
    233     pm_acc = &core->access;
    234     PHYMOD_VDBG(DBG_CFG, pm_acc,
    235        ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" load_meth=%0d",
    236         __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, (int)load_method));
    237 #endif
    238 
    239     switch (load_method) {
    240     case phymodFirmwareLoadMethodInternal:
    241         PHYMOD_IF_ERR_RETURN(merlin16_ucode_mdio_load(&core->access, merlin16_ucode, merlin16_ucode_len));
    242         break;
    243     case phymodFirmwareLoadMethodExternal:
    244         PHYMOD_NULL_CHECK(fw_loader);
    245         PHYMOD_IF_ERR_RETURN(merlin16_ucode_pram_load_pre(&core->access));
    246         PHYMOD_IF_ERR_RETURN(fw_loader(core, merlin16_ucode_len, merlin16_ucode));
    247         PHYMOD_IF_ERR_RETURN(merlin16_ucode_pram_load_post(&core->access));
    248         break;
    249     case phymodFirmwareLoadMethodNone:
    250         break;
    251     default:
    252         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method));
    253     }
    254     return PHYMOD_E_NONE;
    255 }
    256 
    257 int tsce16_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config)
    258 {
    259     struct merlin16_uc_core_config_st serdes_firmware_core_config;
    260     PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config));
    261     serdes_firmware_core_config.field.core_cfg_from_pcs = fw_config.CoreConfigFromPCS;
    262     serdes_firmware_core_config.field.vco_rate = fw_config.VcoRate;
    263 
    264     PHYMOD_IF_ERR_RETURN(merlin16_INTERNAL_set_uc_core_config(&phy->access, serdes_firmware_core_config));
    265     return PHYMOD_E_NONE;
    266 }
    267 
    268 int tsce16_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config)
    269 {
    270     struct merlin16_uc_core_config_st serdes_firmware_core_config;
    271     PHYMOD_IF_ERR_RETURN(merlin16_get_uc_core_config(&phy->access, &serdes_firmware_core_config));
    272     PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config));
    273     fw_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs;
    274     fw_config->VcoRate = serdes_firmware_core_config.field.vco_rate;
    275     return PHYMOD_E_NONE;
    276 }
    277 
    278 int tsce16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
    279 {
    280     phymod_phy_access_t phy_copy;
    281     int start_lane, num_lane, i;
    282 
    283     PHYMOD_IF_ERR_RETURN
    284         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    285     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    286 
    287     /*Hold the per lne soft reset bit*/
    288     for (i = 0; i < num_lane; i++) {
    289         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    290             continue;
    291         }
    292         phy_copy.access.lane_mask = 1 << (start_lane + i);
    293         PHYMOD_IF_ERR_RETURN
    294             (merlin16_lane_soft_reset_release(&phy_copy.access, 0));
    295     }
    296 
    297     PHYMOD_IF_ERR_RETURN
    298          (_tsce16_phy_firmware_lane_config_set(phy, fw_config));
    299     /*Hold the per lne soft reset bit*/
    300     for (i = 0; i < num_lane; i++) {
    301         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    302             continue;
    303         }
    304         phy_copy.access.lane_mask = 1 << (start_lane + i);
    305         PHYMOD_IF_ERR_RETURN
    306             (merlin16_lane_soft_reset_release(&phy_copy.access, 1));
    307     }
    308 
    309     PHYMOD_IF_ERR_RETURN
    310         (temod16_trigger_speed_change(&phy->access));
    311 
    312     return PHYMOD_E_NONE;
    313 }
    314 
    315 int tsce16_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config)
    316 {
    317     struct merlin16_uc_lane_config_st serdes_firmware_config;
    318     PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config));
    319 
    320     PHYMOD_IF_ERR_RETURN(merlin16_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
    321     PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config));
    322     fw_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs;
    323     fw_config->AnEnabled         = serdes_firmware_config.field.an_enabled;
    324     fw_config->DfeOn             = serdes_firmware_config.field.dfe_on;
    325     fw_config->ForceBrDfe        = serdes_firmware_config.field.force_brdfe_on;
    326     fw_config->Cl72AutoPolEn     = serdes_firmware_config.field.cl72_auto_polarity_en;
    327     fw_config->Cl72RestTO        = serdes_firmware_config.field.cl72_restart_timeout_en;
    328     fw_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis;
    329     fw_config->UnreliableLos     = serdes_firmware_config.field.unreliable_los;
    330     fw_config->MediaType         = serdes_firmware_config.field.media_type;
    331     fw_config->Cl72AutoPolEn     = serdes_firmware_config.field.cl72_auto_polarity_en;
    332     fw_config->Cl72RestTO        = serdes_firmware_config.field.cl72_restart_timeout_en;
    333 
    334     return PHYMOD_E_NONE;
    335 }
    336 
    337 int tsce16_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    338 {
    339     PHYMOD_IF_ERR_RETURN
    340         (merlin16_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity));
    341 
    342     return PHYMOD_E_NONE;
    343 }
    344 
    345 int tsce16_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    346 {
    347     PHYMOD_IF_ERR_RETURN
    348         (merlin16_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity));
    349 
    350     return PHYMOD_E_NONE;
    351 }
    352 
    353 int tsce16_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    354 {
    355     PHYMOD_IF_ERR_RETURN
    356         (merlin16_apply_txfir_cfg(&phy->access, (int8_t)tx->pre, (int8_t)tx->main, (int8_t)tx->post, (int8_t)tx->post2));
    357 
    358     return PHYMOD_E_NONE;
    359 }
    360 
    361 int tsce16_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
    362 {
    363     phymod_phy_access_t pm_phy_copy;
    364     int start_lane, num_lane, i;
    365 
    366     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    367     PHYMOD_IF_ERR_RETURN
    368         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    369 
    370     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) {
    371         for (i = 0; i < num_lane; i++) {
    372             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    373                 continue;
    374             }
    375             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    376             PHYMOD_IF_ERR_RETURN(temod16_port_enable_set(&pm_phy_copy.access, 0));
    377         }
    378     }
    379     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) {
    380         for (i = 0; i < num_lane; i++) {
    381             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    382                 continue;
    383             }
    384             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    385             PHYMOD_IF_ERR_RETURN(temod16_port_enable_set(&pm_phy_copy.access, 1));
    386         }
    387     }
    388     if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) {
    389             /* disable tx on the PMD side */
    390             PHYMOD_IF_ERR_RETURN(merlin16_tx_disable(&phy->access, 1));
    391     }
    392     if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) {
    393             /* enable tx on the PMD side */
    394             PHYMOD_IF_ERR_RETURN(merlin16_tx_disable(&phy->access, 0));
    395     }
    396     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) {
    397             /* disable rx on the PMD side */
    398             PHYMOD_IF_ERR_RETURN(temod16_rx_squelch_set(&phy->access, 1));
    399     }
    400     if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) {
    401             /* enable rx on the PMD side */
    402             PHYMOD_IF_ERR_RETURN(temod16_rx_squelch_set(&phy->access, 0));
    403     }
    404     return PHYMOD_E_NONE;
    405 }
    406 
    407 int tsce16_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    408 {
    409     switch (tx_control) {
    410     case phymodTxTrafficDisable:
    411         PHYMOD_IF_ERR_RETURN(temod16_tx_lane_control_set(&phy->access, TEMOD16_TX_LANE_TRAFFIC_DISABLE));
    412         break;
    413     case phymodTxTrafficEnable:
    414         PHYMOD_IF_ERR_RETURN(temod16_tx_lane_control_set(&phy->access, TEMOD16_TX_LANE_TRAFFIC_ENABLE));
    415         break;
    416     case phymodTxReset:
    417         PHYMOD_IF_ERR_RETURN(temod16_tx_lane_control_set(&phy->access, TEMOD16_TX_LANE_RESET));
    418         break;
    419     case phymodTxSquelchOn:
    420         PHYMOD_IF_ERR_RETURN(temod16_tx_squelch_set(&phy->access, 1));
    421         break;
    422     case phymodTxSquelchOff:
    423         PHYMOD_IF_ERR_RETURN(temod16_tx_squelch_set(&phy->access, 0));
    424         break;
    425     default:
    426         break;
    427     }
    428     return PHYMOD_E_NONE;
    429 }
    430 
    431 int tsce16_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    432 {
    433     int enable, reset, tx_lane;
    434     uint32_t lb_enable;
    435     phymod_phy_access_t pm_phy_copy;
    436     int start_lane, num_lane;
    437 
    438     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    439     /* next program the tx fir taps and driver current based on the input */
    440     PHYMOD_IF_ERR_RETURN
    441         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    442 
    443     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    444 
    445     PHYMOD_IF_ERR_RETURN(temod16_tx_squelch_get(&pm_phy_copy.access, &enable));
    446 
    447     /* next check if PMD loopback is on */
    448     if (enable) {
    449         PHYMOD_IF_ERR_RETURN(merlin16_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    450         if (lb_enable) enable = 0;
    451     }
    452 
    453     if (enable) {
    454         *tx_control = phymodTxSquelchOn;
    455     } else {
    456         PHYMOD_IF_ERR_RETURN(temod16_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane));
    457         if (!reset) {
    458             *tx_control = phymodTxReset;
    459         } else if (!tx_lane) {
    460             *tx_control = phymodTxTrafficDisable;
    461         } else {
    462             *tx_control = phymodTxTrafficEnable;
    463         }
    464     }
    465     return PHYMOD_E_NONE;
    466 }
    467 
    468 int tsce16_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    469 {
    470     phymod_phy_access_t pm_phy_copy;
    471     int start_lane, num_lane, i;
    472 
    473     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    474     /* next program the tx fir taps and driver current based on the input */
    475     PHYMOD_IF_ERR_RETURN
    476         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    477 
    478     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    479 
    480     switch (rx_control) {
    481     case phymodRxReset:
    482         PHYMOD_IF_ERR_RETURN(temod16_rx_lane_control_set(&phy->access, 1));
    483         break;
    484     case phymodRxSquelchOn:
    485         for (i = 0; i < num_lane; i++) {
    486             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    487                 continue;
    488             }
    489             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    490             PHYMOD_IF_ERR_RETURN(temod16_rx_squelch_set(&pm_phy_copy.access, 1));
    491         }
    492         break;
    493     case phymodRxSquelchOff:
    494         for (i = 0; i < num_lane; i++) {
    495             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    496                 continue;
    497             }
    498             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    499             PHYMOD_IF_ERR_RETURN(temod16_rx_squelch_set(&pm_phy_copy.access, 0));
    500         }
    501         break;
    502     default:
    503         break;
    504     }
    505     return PHYMOD_E_NONE;
    506 }
    507 
    508 int tsce16_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    509 {
    510     int enable, reset;
    511     uint32_t lb_enable;
    512     phymod_phy_access_t pm_phy_copy;
    513     int start_lane, num_lane;
    514 
    515     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    516     /* next program the tx fir taps and driver current based on the input */
    517     PHYMOD_IF_ERR_RETURN
    518         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    519 
    520     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    521 
    522     PHYMOD_IF_ERR_RETURN(temod16_rx_squelch_get(&pm_phy_copy.access, &enable));
    523     /* next check if PMD loopback is on */
    524     if (enable) {
    525         PHYMOD_IF_ERR_RETURN(merlin16_pmd_loopback_get(&pm_phy_copy.access, &lb_enable));
    526         if (lb_enable) enable = 0;
    527     }
    528     if (enable) {
    529         *rx_control = phymodRxSquelchOn;
    530     } else {
    531         PHYMOD_IF_ERR_RETURN(temod16_rx_lane_control_get(&pm_phy_copy.access, &reset));
    532         if (reset == 0) {
    533             *rx_control = phymodRxReset;
    534         } else {
    535             *rx_control = phymodRxSquelchOff;
    536         }
    537     }
    538     return PHYMOD_E_NONE;
    539 }
    540 
    541 
    542 int tsce16_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
    543 {
    544     uint32_t current_pll_div=0;
    545     uint32_t new_pll_div=0;
    546     uint16_t new_speed_vec=0;
    547     int16_t  new_os_mode =-1;
    548     temod16_spd_intfc_type spd_intf = TEMOD16_SPD_ILLEGAL;
    549     phymod_phy_access_t pm_phy_copy;
    550     int start_lane=0, num_lane, i, pll_switch = 0;
    551     uint32_t os_dfeon=0;
    552     uint32_t scrambling_dis=0;
    553     uint32_t u_os_mode = 0;
    554     int      dfe_adjust = -1;
    555     int lane_bkup;
    556     int cl72_allowed=0, cl72_req=0;
    557     phymod_phy_inf_config_t temp_config;
    558     temod16_pll_mode_type pll_mode;
    559     uint16_t or_val=0;
    560 
    561     /* sc_table_entry exp_entry; RAVI */
    562     phymod_firmware_lane_config_t firmware_lane_config;
    563 #ifdef PHYMOD_DIAG
    564     const phymod_access_t *pm_acc;
    565     pm_acc = &phy->access;
    566     PHYMOD_VDBG(DBG_SPD, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" speed=%0d intf=%0d(%s) flags=%0x\n",
    567       __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, config->data_rate, config->interface_type,
    568                                   phymod_interface_t_mapping[config->interface_type].key, flags));
    569 #endif
    570 
    571     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
    572     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
    573     PHYMOD_MEMSET(&temp_config, 0x0, sizeof(temp_config));
    574 
    575     /* end of special mode */
    576     firmware_lane_config.MediaType = 0;
    577 
    578     /* next program the tx fir taps and driver current based on the input */
    579     PHYMOD_IF_ERR_RETURN
    580         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    581 
    582     /* reset pcs */
    583     temod16_disable_set(&phy->access);
    584 
    585     /* Hold the per lne soft reset bit */
    586     for (i = 0; i < num_lane; i++) {
    587         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    588             continue;
    589         }
    590         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    591         PHYMOD_IF_ERR_RETURN
    592             (merlin16_lane_soft_reset_release(&pm_phy_copy.access, 0));
    593     }
    594     /* deassert pmd_tx_disable_pin_dis if it is set by ILKn */
    595     /* remove pmd_tx_disable_pin_dis it may be asserted because of ILKn */
    596     if (config->interface_type != phymodInterfaceBypass) {
    597         for (i = 0; i < num_lane; i++) {
    598             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    599                 continue;
    600             }
    601             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    602             PHYMOD_IF_ERR_RETURN
    603               (merlin16_pmd_tx_disable_pin_dis_set(&phy->access, 0));
    604         }
    605     }
    606     /* disable CL72 */
    607     for (i = 0; i < num_lane; i++) {
    608         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    609             continue;
    610         }
    611         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    612         PHYMOD_IF_ERR_RETURN
    613             (temod16_clause72_control(&pm_phy_copy.access, 0));
    614     }
    615 
    616     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
    617      PHYMOD_IF_ERR_RETURN
    618         (tsce16_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
    619 
    620     /* make sure that an and config from pcs is off */
    621     firmware_lane_config.AnEnabled = 0;
    622     firmware_lane_config.LaneConfigFromPCS = 0;
    623 
    624     /* and also make sure the cl72 restart timeout is enabled */
    625     firmware_lane_config.Cl72RestTO = 1;
    626     firmware_lane_config.Cl72AutoPolEn = 0;
    627     if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
    628         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    629     } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) {
    630         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
    631     } else {
    632         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    633     }
    634 
    635     PHYMOD_IF_ERR_RETURN
    636         (temod16_update_port_mode(&phy->access, (int *) &pll_switch));
    637 
    638     spd_intf = TEMOD16_SPD_10_X1_SGMII; /* to prevent undefinded TEMOD16_SPD_ILLEGAL accessing tables */
    639 
    640     /* find the speed */
    641     if (config->interface_type == phymodInterfaceXFI) {
    642         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    643     } else if (config->interface_type == phymodInterfaceSFI) {
    644         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    645     } else if (config->interface_type == phymodInterfaceSFPDAC) {
    646         firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
    647     } else if (config->interface_type == phymodInterface1000X) {
    648         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    649     } else if (config->interface_type == phymodInterfaceSGMII) {
    650         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    651     } else if (config->interface_type == phymodInterfaceLR) {
    652         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    653     } else if (config->interface_type == phymodInterfaceSR) {
    654         firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    655     }
    656 
    657     cl72_req = (flags & (PHYMOD_INTF_F_CL72_REQUESTED_BY_CNFG|PHYMOD_INTF_F_CL72_REQUESTED_BY_API))?1:0;
    658     switch (config->data_rate) {
    659     case 10:
    660         if(config->pll_divider_req==80) {
    661             spd_intf = TEMOD16_SPD_10_SGMII;
    662             /* high_vco_1G = 0; */
    663         } else {
    664             spd_intf = TEMOD16_SPD_10_X1_SGMII;
    665         }
    666         break;
    667     case 100:
    668         if(config->pll_divider_req==80) {
    669             spd_intf = TEMOD16_SPD_100_SGMII;
    670             /* high_vco_1G = 0; */
    671         } else {
    672             spd_intf = TEMOD16_SPD_100_X1_SGMII;
    673         }
    674         break;
    675     case 1000:
    676         if(config->pll_divider_req==80) {
    677             spd_intf = TEMOD16_SPD_1000_SGMII;
    678             /* high_vco_1G = 0; */
    679         } else {
    680             spd_intf = TEMOD16_SPD_1000_X1_SGMII;
    681         }
    682         break;
    683     case 2500:
    684         if(config->pll_divider_req==80) {
    685             spd_intf = TEMOD16_SPD_2500;
    686             /* high_vco_1G = 0; */
    687         } else {
    688             spd_intf = TEMOD16_SPD_2500_X1;
    689         }
    690         break;
    691     case 5000:
    692         if(config->pll_divider_req==80) {
    693             spd_intf = TEMOD16_SPD_5000;
    694         } else {
    695             spd_intf = TEMOD16_SPD_5000_XFI;
    696         }
    697         break;
    698     case 10000:
    699         if (config->interface_type == phymodInterfaceXAUI) {
    700             spd_intf = TEMOD16_SPD_10000;
    701         } else if (config->interface_type == phymodInterfaceRXAUI) {
    702             spd_intf = TEMOD16_SPD_10000_X2;
    703         } else if(config->interface_type == phymodInterfaceX2) {
    704             spd_intf = TEMOD16_SPD_10000_X2;
    705         } else {
    706             cl72_allowed = 1 ;
    707             if (config->interface_type == phymodInterfaceSFI) {
    708                 spd_intf = TEMOD16_SPD_10000_XFI;
    709                 dfe_adjust = 0;
    710             } else if (config->interface_type == phymodInterfaceXFI) {
    711                 spd_intf = TEMOD16_SPD_10000_XFI;
    712                 dfe_adjust = 0;
    713             } else if (config->interface_type == phymodInterfaceXGMII) {
    714                 spd_intf = TEMOD16_SPD_10000;
    715             } else if (config->interface_type == phymodInterfaceKR) {
    716                 spd_intf = TEMOD16_SPD_10000_XFI;
    717                 dfe_adjust = 1;
    718             } else {
    719                 spd_intf = TEMOD16_SPD_10000_XFI;
    720                 if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
    721                     dfe_adjust = 0;
    722                 }
    723             }
    724         }
    725         break;
    726     case 11000:
    727         cl72_allowed = 1 ;
    728         if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    729             spd_intf = TEMOD16_SPD_10600_XFI_HG;
    730         } else {
    731             spd_intf = TEMOD16_SPD_10000_XFI;
    732         }
    733         break;
    734     case 12000:
    735         cl72_allowed = 1 ;
    736         spd_intf = TEMOD16_SPD_12P12_XFI;
    737         if ((config->interface_type == phymodInterfaceSFI) ||
    738             (config->interface_type == phymodInterfaceXFI)) {
    739             dfe_adjust = 0 ;
    740         }
    741         break;
    742     case 15000:
    743         spd_intf = TEMOD16_SPD_15000;
    744         break;
    745     case 16000:
    746         spd_intf = TEMOD16_SPD_16000;
    747         break;
    748     case 20000:
    749         if(config->interface_type == phymodInterfaceKR2 ||
    750            config->interface_type == phymodInterfaceCR2) {
    751             cl72_allowed = 1 ;
    752             spd_intf = TEMOD16_SPD_20G_MLD_DXGXS ;
    753         } else if(config->interface_type == phymodInterfaceRXAUI) {
    754             cl72_allowed = 1 ;
    755             spd_intf = TEMOD16_SPD_20G_DXGXS;
    756         } else {
    757             if (PHYMOD_INTF_MODES_SCR_GET(config)) {
    758                 spd_intf = TEMOD16_SPD_20000_SCR;
    759             } else {
    760                 spd_intf = TEMOD16_SPD_20000;
    761             }
    762         }
    763         break;
    764     case 21000:
    765         if(config->interface_type == phymodInterfaceRXAUI) {
    766             spd_intf = TEMOD16_SPD_20G_DXGXS;
    767         } else if(config->interface_type == phymodInterfaceKR2 ||
    768                   config->interface_type == phymodInterfaceCR2) {
    769             spd_intf = TEMOD16_SPD_21G_HI_MLD_DXGXS; 
    770         } else {
    771             spd_intf = TEMOD16_SPD_21000;
    772         }
    773         break;
    774     case 24000:
    775         if (num_lane == 2) {
    776             cl72_allowed = 1;
    777             spd_intf = TEMOD16_SPD_24P24_MLD_DXGXS;
    778         }
    779         break;
    780     case 40000:
    781         cl72_allowed = 1 ;
    782         spd_intf = TEMOD16_SPD_40G_XLAUI;
    783         if (config->interface_type == phymodInterfaceXLAUI) {
    784             firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    785             dfe_adjust = 0 ;
    786         } else if(PHYMOD_INTF_MODES_FIBER_GET(config)) {
    787             firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics ;
    788              dfe_adjust = 0 ;
    789         } else if(config->interface_type == phymodInterfaceCR4) {
    790             firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable ;
    791         } else if (config->interface_type == phymodInterfaceKR4) {
    792             firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    793         } else if((config->interface_type == phymodInterfaceXGMII) || PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    794             spd_intf = TEMOD16_SPD_40G_X4;
    795         } else {
    796             firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane ;
    797         }
    798         break;
    799     case 42000:
    800         cl72_allowed = 1 ;
    801         if ((config->interface_type == phymodInterfaceKR4) && 
    802             PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    803             spd_intf = TEMOD16_SPD_42G_XLAUI;
    804         }else if((config->interface_type == phymodInterfaceCR4) &&
    805             PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    806             spd_intf = TEMOD16_SPD_42G_XLAUI;
    807             firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable;
    808         }else if((config->interface_type == phymodInterfaceXGMII) || PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    809             spd_intf = TEMOD16_SPD_40G_X4;
    810         } else {
    811             spd_intf = TEMOD16_SPD_42G_XLAUI;
    812         }
    813         break;
    814     case 48000:
    815         cl72_allowed = 1 ;
    816         spd_intf = TEMOD16_SPD_48P48_MLD;
    817         firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    818         dfe_adjust = 0;
    819         break;
    820     default:
    821         PHYMOD_RETURN_WITH_ERR
    822             (PHYMOD_E_CONFIG, (_PHYMOD_MSG("this speed %d is not supported by tsce16"),
    823              config->data_rate));
    824         break;
    825     }
    826 
    827 
    828     if(PHYMOD_INTF_MODES_HIGIG_GET(config)) {
    829        PHYMOD_IF_ERR_RETURN
    830           (temod16_encode_set(&phy->access, spd_intf, 1));
    831        PHYMOD_IF_ERR_RETURN
    832           (temod16_decode_set(&phy->access, spd_intf, 1));
    833     } else {
    834        PHYMOD_IF_ERR_RETURN
    835           (temod16_encode_set(&phy->access, spd_intf, 0));
    836        PHYMOD_IF_ERR_RETURN
    837           (temod16_decode_set(&phy->access, spd_intf, 0));
    838     }
    839 
    840     if (config->data_rate==10 || 
    841         config->data_rate==100 ||
    842         config->data_rate==1000) {
    843         if (config->interface_type == phymodInterfaceSGMII) {
    844             firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
    845         }
    846         if (config->interface_type == phymodInterface1000X) {
    847             firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
    848         }
    849     }
    850 
    851     /* get the current PLL setting */
    852     pm_phy_copy.access.lane_mask = 1 << start_lane;
    853     PHYMOD_IF_ERR_RETURN
    854         (temod16_pll_config_get(&pm_phy_copy.access, &pll_mode));
    855     current_pll_div = (uint32_t) pll_mode;
    856 
    857     /* find the new os mode and new pll div */
    858     if (config->interface_type == phymodInterfaceBypass) {
    859         new_pll_div = TEMOD16_PLL_MODE_DIV_66;
    860         if (config->data_rate == 1000) {
    861             new_os_mode = 8;
    862         }
    863         /* the other supported speed could only be 10G */
    864         else {
    865             new_os_mode = 0;
    866         }
    867     } else {
    868         PHYMOD_IF_ERR_RETURN
    869             (temod16_plldiv_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div, &new_speed_vec));
    870 
    871         if (config->ref_clock == phymodRefClk156Mhz) {
    872             switch (config->data_rate) {
    873             case 21000:
    874                 if (num_lane == 2) {
    875                     new_pll_div = TEMOD16_PLL_MODE_DIV_70;
    876                 }
    877                 break;
    878             case 42000:
    879                 new_pll_div = TEMOD16_PLL_MODE_DIV_70;
    880                 break;
    881             default:
    882                 break;
    883             }
    884         }
    885     }
    886 
    887     if (new_os_mode>=0) {
    888         /* 0x80000000 causes PMD OS mode to be configured based on new_os_mode,
    889          * otherwise the PMD OS mode will be based on spd_intf.
    890          */
    891         u_os_mode = new_os_mode | 0x80000000;
    892     } else {
    893         u_os_mode = 0;
    894     }
    895 
    896     
    897     PHYMOD_IF_ERR_RETURN
    898         (temod16_pmd_osmode_set(&phy->access, spd_intf, u_os_mode));
    899     PHYMOD_IF_ERR_RETURN(temod16_osdfe_on_lkup_get(&phy->access, spd_intf, &os_dfeon));
    900     PHYMOD_IF_ERR_RETURN(temod16_scrambling_dis_lkup_get(&phy->access, spd_intf, &scrambling_dis));
    901     firmware_lane_config.DfeOn = 0;
    902     firmware_lane_config.ScramblingDisable = scrambling_dis;
    903     /* Override scrambler settings in PCS when disable scrambler is needed*/
    904     if(PHYMOD_INTF_F_SCRAMBLE_FORCED_ON & flags) {
    905         firmware_lane_config.ScramblingDisable = 0 ;
    906 
    907         or_val = 1;
    908         PHYMOD_IF_ERR_RETURN
    909             (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_SCR_MODE , or_val));
    910         PHYMOD_IF_ERR_RETURN
    911             (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_DESCR_MODE, or_val));
    912     } else if (PHYMOD_INTF_F_SCRAMBLE_FORCED_OFF & flags) {
    913         firmware_lane_config.ScramblingDisable = 1 ;
    914 
    915         or_val = 0;
    916         PHYMOD_IF_ERR_RETURN
    917             (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_SCR_MODE , or_val));
    918         PHYMOD_IF_ERR_RETURN
    919             (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_DESCR_MODE, or_val));
    920     } else {
    921         /* Override scrambler settings in PCS when disable scrambler is needed*/
    922         if (scrambling_dis){
    923             or_val = 0;
    924             PHYMOD_IF_ERR_RETURN
    925                 (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_SCR_MODE , or_val));
    926             PHYMOD_IF_ERR_RETURN
    927                 (temod16_override_set(&phy->access, TEMOD16_OVERRIDE_DESCR_MODE, or_val));
    928         }
    929         else {
    930             PHYMOD_IF_ERR_RETURN
    931                 (temod16_override_clear(&phy->access, TEMOD16_OVERRIDE_SCR_MODE));
    932             PHYMOD_IF_ERR_RETURN
    933                 (temod16_override_clear(&phy->access, TEMOD16_OVERRIDE_DESCR_MODE));
    934         }
    935     }
    936 
    937     if (os_dfeon == 0x1)
    938         firmware_lane_config.DfeOn = 1;
    939 
    940     if (dfe_adjust >=0)
    941         firmware_lane_config.DfeOn = dfe_adjust;
    942 
    943     /* the speed is not supported */
    944     if (new_pll_div == TEMOD16_PLL_MODE_DIV_ILLEGAL) {
    945         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
    946                                (_PHYMOD_MSG("this speed %d is not supported at this ref clock %d"),
    947                                  config->data_rate, config->ref_clock));
    948     }
    949 
    950 
    951 
    952     /* if pll change is enabled. new_pll_div is the reg vector value */
    953     if ((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) {
    954         if (config->interface_type != phymodInterfaceBypass) {
    955             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
    956                                    (_PHYMOD_MSG("pll has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled"),
    957                                      (unsigned int)current_pll_div, (unsigned int)new_pll_div));
    958         }
    959     }
    960 
    961         /* pll switch is required and expected */
    962     if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) {
    963         lane_bkup = pm_phy_copy.access.lane_mask;
    964         pm_phy_copy.access.lane_mask = 0xf;
    965         temod16_disable_set(&pm_phy_copy.access);
    966         pm_phy_copy.access.lane_mask = lane_bkup;
    967 
    968         PHYMOD_IF_ERR_RETURN
    969             (merlin16_core_soft_reset_release(&pm_phy_copy.access, 0));
    970 
    971         /* set the PLL divider */
    972         PHYMOD_IF_ERR_RETURN
    973             (temod16_pll_config_set(&pm_phy_copy.access, new_pll_div, config->ref_clock));
    974 
    975         /* change the  master port num to the current caller port */
    976         PHYMOD_IF_ERR_RETURN
    977             (temod16_master_port_num_set(&pm_phy_copy.access, start_lane));
    978 
    979         PHYMOD_IF_ERR_RETURN
    980             (temod16_pll_reset_enable_set(&pm_phy_copy.access, 1));
    981 
    982         PHYMOD_IF_ERR_RETURN
    983             (merlin16_core_soft_reset_release(&pm_phy_copy.access, 1));
    984     }
    985 
    986     if (cl72_req & cl72_allowed) {
    987         for (i = 0; i < num_lane; i++) {
    988             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    989                 continue;
    990             }
    991             pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
    992             PHYMOD_IF_ERR_RETURN
    993                 (temod16_clause72_control(&pm_phy_copy.access, 1));
    994         }
    995     }
    996 
    997     if (config->interface_type != phymodInterfaceBypass) {
    998         if (flags & PHYMOD_INTF_F_SET_SPD_NO_TRIGGER) {
    999             (temod16_set_spd_intf(&phy->access, spd_intf, 1));
   1000         } else {
   1001             PHYMOD_IF_ERR_RETURN
   1002                 (temod16_set_spd_intf(&phy->access, spd_intf, 0));
   1003         }
   1004     }
   1005 
   1006     for (i = 0; i < num_lane; i++) {
   1007         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1008             continue;
   1009         }
   1010         pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i);
   1011         PHYMOD_IF_ERR_RETURN
   1012              (_tsce16_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config));
   1013     }
   1014 
   1015     /* release the per lne soft reset bit */
   1016     for (i = 0; i < num_lane; i++) {
   1017         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1018             continue;
   1019         }
   1020         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   1021         PHYMOD_IF_ERR_RETURN
   1022             (merlin16_lane_soft_reset_release(&pm_phy_copy.access, 1));
   1023     }
   1024 #ifdef PHYMOD_DIAG
   1025     PHYMOD_VDBG(DBG_SPD, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" spd=%0d(%s) media=%0d\n",
   1026        __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, spd_intf, e2s_temod16_spd_intfc_type[spd_intf],
   1027             firmware_lane_config.MediaType));
   1028 #endif
   1029 
   1030     return PHYMOD_E_NONE;
   1031 }
   1032 
   1033 
   1034 
   1035 STATIC
   1036 int _tsce16_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id,
   1037                                         phymod_phy_inf_config_t* config, uint16_t an_enable,
   1038                                         phymod_firmware_lane_config_t *lane_config)
   1039 {
   1040     int hg_enable = 0;
   1041     uint32_t current_pll_div=0;
   1042     temod16_pll_mode_type pll_mode;
   1043 
   1044     PHYMOD_IF_ERR_RETURN
   1045         (temod16_pll_config_get(&phy->access, &pll_mode));
   1046     current_pll_div = (uint32_t) pll_mode;     
   1047 
   1048     PHYMOD_IF_ERR_RETURN
   1049         (temod16_hg_enable_get(&phy->access, &hg_enable));
   1050 
   1051     switch (speed_id) {
   1052     case 0x1:
   1053         config->data_rate = 10;
   1054         config->interface_type = phymodInterfaceSGMII;
   1055         break;
   1056     case 0x2:
   1057         config->data_rate = 100;
   1058         config->interface_type = phymodInterfaceSGMII;
   1059         break;
   1060     case 0x3:
   1061         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1062             config->interface_type = phymodInterface1000X;
   1063         } else {
   1064             config->interface_type = phymodInterfaceSGMII;
   1065         }
   1066         config->data_rate = 1000;
   1067         break;
   1068     case 0x4:
   1069         config->data_rate = 1000;
   1070         config->interface_type = phymodInterfaceCX;
   1071         break;
   1072     case 0x5:
   1073         config->data_rate = 1000;
   1074         config->interface_type = phymodInterfaceKX;
   1075         break;
   1076     case 0x6:
   1077         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1078             config->interface_type = phymodInterface1000X;
   1079         } else {
   1080             config->interface_type = phymodInterfaceSGMII;
   1081         }
   1082             config->data_rate = 2500;
   1083         break;
   1084     case 0x7:
   1085         config->data_rate = 5000;
   1086         config->interface_type = phymodInterface1000X;
   1087         break;
   1088     case 0x8:
   1089         config->data_rate = 10000;
   1090         config->interface_type = phymodInterfaceCX4;
   1091         break;
   1092     case 0x9:
   1093         config->data_rate = 10000;
   1094         config->interface_type = phymodInterfaceXAUI;
   1095         break;
   1096     case 0xa:
   1097         config->data_rate = 10000;
   1098         config->interface_type = phymodInterfaceXGMII;
   1099         break;
   1100     case 0xb:
   1101         config->data_rate = 13000;
   1102         config->interface_type = phymodInterfaceXGMII;
   1103         break;
   1104     case 0xc:
   1105         config->data_rate = 15000;
   1106         config->interface_type = phymodInterfaceXGMII;
   1107         break;
   1108     case 0xd:
   1109         config->data_rate = 16000;
   1110         config->interface_type = phymodInterfaceXGMII;
   1111         break;
   1112     case 0xe:
   1113         config->data_rate = 20000;
   1114         config->interface_type = phymodInterfaceCX4;
   1115         break;
   1116     case 0xf:
   1117         config->data_rate = 10000;
   1118         config->interface_type = phymodInterfaceRXAUI;
   1119         break;
   1120     case 0x10:
   1121         config->data_rate = 10000;
   1122         config->interface_type = phymodInterfaceX2;
   1123         break;
   1124     case 0x11:
   1125         config->data_rate = 20000;
   1126         config->interface_type = phymodInterfaceXGMII;
   1127         break;
   1128     case 0x12:
   1129         config->data_rate = 10500;
   1130         config->interface_type = phymodInterfaceX2;
   1131         break;
   1132     case 0x13:
   1133         config->data_rate = 21000;
   1134         config->interface_type = phymodInterfaceCX4;
   1135         break;
   1136     case 0x14:
   1137         config->data_rate = 13000;  /* round up from 12700 */
   1138         config->interface_type = phymodInterfaceX2;
   1139         break;
   1140     case 0x15:
   1141         config->data_rate = 25450;
   1142         config->interface_type = phymodInterfaceKR4;
   1143         break;
   1144     case 0x16:
   1145         config->data_rate = 15750;
   1146         config->interface_type = phymodInterfaceX2;
   1147         break;
   1148     case 0x17:
   1149         config->data_rate = 31500;
   1150         config->interface_type = phymodInterfaceXGMII;
   1151         break;
   1152     case 0x18:
   1153         config->data_rate = 31500;
   1154         config->interface_type = phymodInterfaceKR4;
   1155         break;
   1156     case 0x19:
   1157         config->data_rate = 20000;
   1158         config->interface_type = phymodInterfaceCX2;
   1159         break;
   1160     case 0x1a:
   1161         if(current_pll_div==TEMOD16_PLL_MODE_DIV_70) {
   1162             config->data_rate = 21000;
   1163         } else {
   1164             config->data_rate = 20000;
   1165         }
   1166         config->interface_type = phymodInterfaceX2;
   1167         break;
   1168     case 0x1b:    /* digital_operationSpeeds_SPEED_40G_X4; BRCM */
   1169         if(current_pll_div==TEMOD16_PLL_MODE_DIV_70) {
   1170             config->data_rate = 42000;
   1171         } else {
   1172             config->data_rate = 40000;
   1173         }
   1174         config->interface_type = phymodInterfaceXGMII;
   1175         break;
   1176     case 0x1c:
   1177         if(current_pll_div==TEMOD16_PLL_MODE_DIV_80) {
   1178             config->data_rate = 12000;
   1179         } else if(current_pll_div==TEMOD16_PLL_MODE_DIV_70) {
   1180             config->data_rate = 11000;
   1181         } else {
   1182             config->data_rate = 10000;
   1183         }
   1184         config->interface_type = phymodInterfaceKR;
   1185         if(!an_enable) {
   1186             if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1187                 if(config->interface_type == phymodInterfaceSR) {
   1188                     config->interface_type = phymodInterfaceSR;
   1189                 } else {
   1190                     config->interface_type = phymodInterfaceSFI;
   1191                 }
   1192             } else if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) {
   1193                 config->interface_type = phymodInterfaceCR;
   1194             } else if (lane_config->DfeOn == 1) { 
   1195                 config->interface_type = phymodInterfaceKR;
   1196             } else {
   1197                 config->interface_type = phymodInterfaceXFI;
   1198             }
   1199         }
   1200         break;
   1201     case 0x1d:
   1202         config->data_rate = 11000;
   1203         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1204             if(config->interface_type == phymodInterfaceSR) {
   1205                 config->interface_type = phymodInterfaceSR;
   1206             } else {
   1207                 config->interface_type = phymodInterfaceSFI;
   1208             }
   1209         } else {
   1210             config->interface_type = phymodInterfaceXFI;
   1211         }
   1212         break;
   1213     case 0x1e:
   1214         if(current_pll_div == TEMOD16_PLL_MODE_DIV_80) {
   1215             config->data_rate = 25000;
   1216         } else if(current_pll_div == TEMOD16_PLL_MODE_DIV_70) {
   1217             config->data_rate = 21000;
   1218         } else {
   1219             config->data_rate = 20000;
   1220         }
   1221         if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) {
   1222             config->interface_type = phymodInterfaceCR2;
   1223         } else {
   1224             config->interface_type = phymodInterfaceKR2;
   1225         }
   1226         break;
   1227     case 0x1f:
   1228         if(current_pll_div == TEMOD16_PLL_MODE_DIV_80) {
   1229             config->data_rate = 25000;
   1230         } else if(current_pll_div == TEMOD16_PLL_MODE_DIV_70) {
   1231             config->data_rate = 21000;
   1232         } else {
   1233             config->data_rate = 20000;
   1234         }
   1235         config->interface_type = phymodInterfaceCR2;
   1236         break;
   1237     case 0x20:
   1238         config->data_rate = 21000;
   1239         config->interface_type = phymodInterfaceKR2;
   1240         break;
   1241     case 0x21:  /* digital_operationSpeeds_SPEED_40G_KR4 */
   1242         if (current_pll_div == TEMOD16_PLL_MODE_DIV_80) {
   1243             config->data_rate = 48000;
   1244         } else if (current_pll_div == TEMOD16_PLL_MODE_DIV_70) {
   1245             config->data_rate = 42000;
   1246         } else {
   1247             config->data_rate = 40000;
   1248         }
   1249         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1250             config->interface_type = phymodInterfaceSR4;
   1251         } else if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) {
   1252             config->interface_type = phymodInterfaceCR4;
   1253         } else if ((lane_config->MediaType == phymodFirmwareMediaTypePcbTraceBackPlane) && hg_enable) { 
   1254             config->interface_type = phymodInterfaceKR4;
   1255         } else if(lane_config->DfeOn) {
   1256             config->interface_type = phymodInterfaceKR4;
   1257         } else { 
   1258             config->interface_type = phymodInterfaceXLAUI;
   1259         }
   1260         break;
   1261     case 0x22:
   1262         config->data_rate = 40000;
   1263         config->interface_type = phymodInterfaceCR4;
   1264         break;
   1265     case 0x23:  /* digital_operationSpeeds_SPEED_42G_X4; atcually MLD */
   1266         config->data_rate = 42000;
   1267         if(lane_config->MediaType == phymodFirmwareMediaTypeCopperCable){
   1268             config->interface_type = phymodInterfaceCR4;
   1269         }else if(lane_config->DfeOn) {
   1270             config->interface_type = phymodInterfaceKR4;
   1271         } else {
   1272             config->interface_type = phymodInterfaceXLAUI;
   1273         }
   1274         break;
   1275     case 0x24:
   1276         config->data_rate = 100000;
   1277         config->interface_type = phymodInterfaceCR10;
   1278         break;
   1279     case 0x25:
   1280         config->data_rate = 106000;
   1281         config->interface_type = phymodInterfaceCAUI;
   1282         break;
   1283     case 0x26:
   1284         config->data_rate = 120000;
   1285         /*        config->interface_type = phymodInterfaceXGMII; */
   1286         config->interface_type = phymodInterfaceCAUI;
   1287         break;
   1288     case 0x27:
   1289         config->data_rate = 127000;
   1290         config->interface_type = phymodInterfaceCAUI;
   1291         break;
   1292     case 0x28:
   1293         config->data_rate = 12000;
   1294         config->interface_type = phymodInterfaceKR;
   1295         break;
   1296     case 0x29:
   1297         config->data_rate = 24000;
   1298         config->interface_type = phymodInterfaceKR2;
   1299         break;
   1300     case 0x2a:
   1301         config->data_rate = 48000;
   1302         config->interface_type = phymodInterfaceKR4;
   1303         break;
   1304     case 0x31:
   1305         config->data_rate = 5000;
   1306         config->interface_type = phymodInterfaceKR;
   1307         break;
   1308     case 0x32:
   1309         config->data_rate = 10500;
   1310         config->interface_type = phymodInterfaceXGMII;
   1311         break;
   1312     case 0x35:
   1313         config->data_rate = 10;
   1314         config->interface_type = phymodInterfaceSGMII;
   1315         break;
   1316     case 0x36:
   1317         config->data_rate = 100;
   1318         config->interface_type = phymodInterfaceSGMII;
   1319         break;
   1320     case 0x37:
   1321         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1322             config->interface_type = phymodInterface1000X;
   1323         } else {
   1324             config->interface_type = phymodInterfaceSGMII;
   1325         }     
   1326         config->data_rate = 1000;
   1327         break;
   1328     case 0x38:
   1329         if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) {
   1330             config->interface_type = phymodInterface1000X;
   1331         } else {
   1332             config->interface_type = phymodInterfaceSGMII;
   1333         }
   1334         config->data_rate = 2500;
   1335         break;
   1336     case 0x39:
   1337         config->data_rate = 10000;
   1338         config->interface_type = phymodInterfaceXAUI;
   1339         break;
   1340     case 0x3a:
   1341         config->data_rate = 10000;
   1342         config->interface_type = phymodInterfaceXAUI;
   1343         break;
   1344     default:
   1345         config->data_rate = 0;
   1346         config->interface_type = phymodInterfaceSGMII;
   1347         break;
   1348     }
   1349 
   1350     return PHYMOD_E_NONE;
   1351 }
   1352 
   1353 
   1354 /* flags- unused parameter */
   1355 int tsce16_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)
   1356 {
   1357     int speed_id;
   1358     phymod_firmware_lane_config_t firmware_lane_config;
   1359     phymod_phy_access_t pm_phy_copy;
   1360     int start_lane, num_lane;
   1361     temod16_an_control_t an_control;
   1362     int an_complete = 0;
   1363 
   1364 #ifdef PHYMOD_DIAG
   1365     const phymod_access_t *pm_acc;
   1366     pm_acc = &phy->access;
   1367     PHYMOD_VDBG(DBG_LNK, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" flags=%"PRIx32"\n",
   1368                 __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, flags));
   1369 #endif
   1370     config->ref_clock = ref_clock;
   1371     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   1372     PHYMOD_IF_ERR_RETURN
   1373         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1374 
   1375     PHYMOD_IF_ERR_RETURN
   1376         (temod16_speed_id_get(&phy->access, &speed_id));
   1377 
   1378     pm_phy_copy.access.lane_mask = 0x1 << start_lane;
   1379 
   1380     PHYMOD_MEMSET(&an_control, 0x0,  sizeof(temod16_an_control_t));
   1381     PHYMOD_IF_ERR_RETURN
   1382         (temod16_autoneg_control_get(&pm_phy_copy.access, &an_control, &an_complete));
   1383 
   1384     PHYMOD_IF_ERR_RETURN
   1385         (tsce16_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config));
   1386 
   1387     PHYMOD_IF_ERR_RETURN
   1388         (_tsce16_speed_id_interface_config_get(phy, speed_id, config, an_control.enable, &firmware_lane_config));
   1389 
   1390     if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) {
   1391         PHYMOD_INTF_MODES_FIBER_SET(config);
   1392     } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   1393         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1394         PHYMOD_INTF_MODES_COPPER_SET(config);
   1395     } else {
   1396         PHYMOD_INTF_MODES_FIBER_CLR(config);
   1397         PHYMOD_INTF_MODES_BACKPLANE_SET(config);
   1398     }
   1399 
   1400     switch (config->interface_type) {
   1401     case phymodInterfaceSGMII:
   1402     {
   1403         if (config->data_rate == 1000) {
   1404             if (!PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1405                 config->interface_type = phymodInterfaceSGMII;
   1406             } else {
   1407                 config->interface_type = phymodInterface1000X;
   1408             }
   1409         } else {
   1410             config->interface_type = phymodInterfaceSGMII;
   1411         }
   1412         break;
   1413     }
   1414     case phymodInterfaceKR:
   1415     {
   1416         if (!an_control.enable) {
   1417             if (config->data_rate == 10000) {
   1418                 if (!PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1419                    if (firmware_lane_config.DfeOn == 1) {
   1420                         config->interface_type = phymodInterfaceKR;
   1421                     } else {
   1422                         config->interface_type = phymodInterfaceXFI;
   1423                     }
   1424                 } else {
   1425                     config->interface_type = phymodInterfaceSFI;
   1426                 }
   1427             } else {
   1428                 if (PHYMOD_INTF_MODES_FIBER_GET(config)) {
   1429                     config->interface_type = phymodInterfaceSR;
   1430                 } else {
   1431                     config->interface_type = phymodInterfaceKR;
   1432                 }
   1433             }
   1434         } else {
   1435             config->interface_type = phymodInterfaceKR;
   1436         }
   1437         break;
   1438     }
   1439     default:
   1440         break;
   1441     }
   1442 
   1443 #ifdef PHYMOD_DIAG
   1444     PHYMOD_VDBG(DBG_CFG, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" sp_id=0x%0x rate=%0d phy_intf=%0d(%s) intf_md=%0x\n",
   1445                 __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, speed_id, config->data_rate,
   1446                 config->interface_type, phymod_interface_t_mapping[config->interface_type].key, config->interface_modes));
   1447 #endif
   1448     return PHYMOD_E_NONE;
   1449 }
   1450 
   1451 int tsce16_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability)
   1452 {
   1453     temod16_an_ability_t value;
   1454     int start_lane, num_lane;
   1455     phymod_phy_access_t phy_copy;
   1456 
   1457     PHYMOD_IF_ERR_RETURN
   1458         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1459 
   1460     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1461     phy_copy.access.lane_mask = 0x1 << start_lane;
   1462 
   1463     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   1464 
   1465     value.cl37_adv.an_cl72 = an_ability->an_cl72;
   1466     value.cl73_adv.an_cl72 = an_ability->an_cl72;
   1467     value.cl37_adv.an_hg2 = an_ability->an_hg2;
   1468 
   1469     if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) {
   1470         value.cl37_adv.an_fec = TEMOD16_FEC_CL74_SUPRTD_REQSTD;
   1471         value.cl73_adv.an_fec = TEMOD16_FEC_CL74_SUPRTD_REQSTD;
   1472     } else if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) {
   1473         value.cl37_adv.an_fec = TEMOD16_FEC_SUPRTD_NOT_REQSTD;
   1474         value.cl73_adv.an_fec = TEMOD16_FEC_SUPRTD_NOT_REQSTD;
   1475     }
   1476 
   1477     /* check if sgmii  or not */
   1478     if (PHYMOD_AN_CAP_SGMII_GET(an_ability)) {
   1479         switch (an_ability->sgmii_speed) {
   1480         case phymod_CL37_SGMII_10M:
   1481             value.cl37_adv.cl37_sgmii_speed = TEMOD16_CL37_SGMII_10M;
   1482             break;
   1483         case phymod_CL37_SGMII_100M:
   1484             value.cl37_adv.cl37_sgmii_speed = TEMOD16_CL37_SGMII_100M;
   1485             break;
   1486         case phymod_CL37_SGMII_1000M:
   1487             value.cl37_adv.cl37_sgmii_speed = TEMOD16_CL37_SGMII_1000M;
   1488             break;
   1489         default:
   1490             value.cl37_adv.cl37_sgmii_speed = TEMOD16_CL37_SGMII_1000M;
   1491             break;
   1492         }
   1493     }
   1494 
   1495     /* check pause */
   1496     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) {
   1497         value.cl37_adv.an_pause = TEMOD16_SYMM_PAUSE;
   1498         value.cl73_adv.an_pause = TEMOD16_SYMM_PAUSE;
   1499     }
   1500     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   1501         value.cl37_adv.an_pause = TEMOD16_ASYM_PAUSE;
   1502         value.cl73_adv.an_pause = TEMOD16_ASYM_PAUSE;
   1503     }
   1504     if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) {
   1505         value.cl37_adv.an_pause = TEMOD16_ASYM_SYMM_PAUSE;
   1506         value.cl73_adv.an_pause = TEMOD16_ASYM_SYMM_PAUSE;
   1507     }
   1508 
   1509     /* check cl73 and cl73 bam ability */
   1510     if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap))
   1511         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_1000BASE_KX;
   1512     if (PHYMOD_AN_CAP_10G_KX4_GET(an_ability->an_cap))
   1513         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_10GBASE_KX4;
   1514     if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap))
   1515         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_10GBASE_KR;
   1516     if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap))
   1517         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_40GBASE_KR4;
   1518     if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap))
   1519         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_40GBASE_CR4;
   1520     if (PHYMOD_AN_CAP_100G_CR10_GET(an_ability->an_cap))
   1521         value.cl73_adv.an_base_speed |= 1 << TEMOD16_CL73_100GBASE_CR10;
   1522 
   1523     /* next check cl73 bam ability */
   1524     if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap))
   1525         value.cl73_adv.an_bam_speed |= 1 << TEMOD16_CL73_BAM_20GBASE_KR2;
   1526     if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap))
   1527         value.cl73_adv.an_bam_speed |= 1 << TEMOD16_CL73_BAM_20GBASE_CR2;
   1528 
   1529     /* check cl37 and cl37 bam ability */
   1530     if (PHYMOD_BAM_CL37_CAP_2P5G_GET(an_ability->cl37bam_cap))
   1531         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_2p5GBASE_X;
   1532     if (PHYMOD_BAM_CL37_CAP_5G_X4_GET(an_ability->cl37bam_cap))
   1533         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_5GBASE_X4;
   1534     if (PHYMOD_BAM_CL37_CAP_6G_X4_GET(an_ability->cl37bam_cap))
   1535         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_6GBASE_X4;
   1536     if (PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(an_ability->cl37bam_cap))
   1537         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_10GBASE_X4;
   1538     if (PHYMOD_BAM_CL37_CAP_10G_CX4_GET(an_ability->cl37bam_cap))
   1539         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_10GBASE_X4_CX4;
   1540     if (PHYMOD_BAM_CL37_CAP_12G_X4_GET(an_ability->cl37bam_cap))
   1541         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_12GBASE_X4;
   1542     if (PHYMOD_BAM_CL37_CAP_12P5_X4_GET(an_ability->cl37bam_cap))
   1543         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_12p5GBASE_X4;
   1544     if (PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(an_ability->cl37bam_cap))
   1545         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_10GBASE_X2_CX4;
   1546     if (PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(an_ability->cl37bam_cap))
   1547         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_10GBASE_X2;
   1548     if (PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(an_ability->cl37bam_cap))
   1549         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_BAM_10p5GBASE_X2;
   1550     if (PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(an_ability->cl37bam_cap))
   1551         value.cl37_adv.an_bam_speed |= 1 << TEMOD16_CL37_BAM_12p7GBASE_X2;
   1552     if (PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(an_ability->cl37bam_cap))
   1553         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_20GBASE_X2_CX4;
   1554     if (PHYMOD_BAM_CL37_CAP_20G_X2_GET(an_ability->cl37bam_cap))
   1555         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_20GBASE_X2;
   1556     if (PHYMOD_BAM_CL37_CAP_13G_X4_GET(an_ability->cl37bam_cap))
   1557         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_13GBASE_X4;
   1558     if (PHYMOD_BAM_CL37_CAP_15G_X4_GET(an_ability->cl37bam_cap))
   1559         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_15GBASE_X4;
   1560     if (PHYMOD_BAM_CL37_CAP_16G_X4_GET(an_ability->cl37bam_cap))
   1561         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_16GBASE_X4;
   1562     if (PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(an_ability->cl37bam_cap))
   1563         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_20GBASE_X4_CX4;
   1564     if (PHYMOD_BAM_CL37_CAP_20G_X4_GET(an_ability->cl37bam_cap))
   1565         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_20GBASE_X4;
   1566     if (PHYMOD_BAM_CL37_CAP_21G_X4_GET(an_ability->cl37bam_cap))
   1567         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_21GBASE_X4;
   1568     if (PHYMOD_BAM_CL37_CAP_25P455G_GET(an_ability->cl37bam_cap))
   1569         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_25p455GBASE_X4;
   1570     if (PHYMOD_BAM_CL37_CAP_31P5G_GET(an_ability->cl37bam_cap))
   1571         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_31p5GBASE_X4;
   1572     if (PHYMOD_BAM_CL37_CAP_32P7G_GET(an_ability->cl37bam_cap))
   1573         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_32p7GBASE_X4;
   1574     if (PHYMOD_BAM_CL37_CAP_40G_GET(an_ability->cl37bam_cap))
   1575         value.cl37_adv.an_bam_speed1 |= 1 << TEMOD16_CL37_BAM_40GBASE_X4;
   1576 
   1577     PHYMOD_IF_ERR_RETURN
   1578         (temod16_autoneg_set(&phy_copy.access, &value));
   1579 
   1580     return PHYMOD_E_NONE;
   1581 }
   1582 
   1583 int tsce16_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) {
   1584     temod16_an_ability_t value;
   1585     phymod_phy_access_t phy_copy;
   1586     int start_lane, num_lane;
   1587     temod16_an_control_t an_control;
   1588     int an_complete = 0;
   1589     int an_fec = 0;
   1590 
   1591     PHYMOD_IF_ERR_RETURN
   1592         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1593     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1594     phy_copy.access.lane_mask = 0x1 << start_lane;
   1595     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   1596 
   1597     PHYMOD_IF_ERR_RETURN
   1598         (temod16_autoneg_local_ability_get(&phy_copy.access, &value));
   1599     PHYMOD_IF_ERR_RETURN
   1600         (temod16_autoneg_control_get(&phy_copy.access, &an_control, &an_complete));
   1601     an_ability_get_type->an_cl72 = value.cl37_adv.an_cl72 | value.cl73_adv.an_cl72;
   1602     an_ability_get_type->an_hg2 = value.cl37_adv.an_hg2;
   1603 
   1604     an_fec = value.cl37_adv.an_fec | value.cl73_adv.an_fec;
   1605     an_ability_get_type->an_fec = 0;
   1606     if (an_fec == TEMOD16_FEC_CL74_SUPRTD_REQSTD) {
   1607         PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec);
   1608     } else {
   1609         PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec);
   1610     }
   1611 
   1612     /* get AN Clause */
   1613     switch (an_control.an_type) {
   1614         case TEMOD16_AN_MODE_CL73:
   1615             PHYMOD_AN_CAP_CL73_SET(an_ability_get_type);
   1616             break;
   1617         case TEMOD16_AN_MODE_CL37:
   1618             PHYMOD_AN_CAP_CL37_SET(an_ability_get_type);
   1619             break;
   1620         case TEMOD16_AN_MODE_CL73BAM:
   1621             PHYMOD_AN_CAP_CL73BAM_SET(an_ability_get_type);
   1622             break;
   1623         case TEMOD16_AN_MODE_CL37BAM:
   1624             PHYMOD_AN_CAP_CL37BAM_SET(an_ability_get_type);
   1625             break;
   1626         case TEMOD16_AN_MODE_HPAM:
   1627             PHYMOD_AN_CAP_HPAM_SET(an_ability_get_type);
   1628             break;
   1629         case TEMOD16_AN_MODE_SGMII:
   1630             PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type);
   1631             break;
   1632         case TEMOD16_AN_MODE_CL37_SGMII:
   1633             PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type);
   1634             break;
   1635         default:
   1636             break;
   1637     }
   1638 
   1639     if ((value.cl37_adv.an_pause == TEMOD16_ASYM_PAUSE)||(value.cl73_adv.an_pause == TEMOD16_ASYM_PAUSE)) {
   1640         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1641     } else if ((value.cl37_adv.an_pause == TEMOD16_SYMM_PAUSE)||(value.cl73_adv.an_pause == TEMOD16_SYMM_PAUSE)) {
   1642         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1643     } else if ((value.cl37_adv.an_pause == TEMOD16_ASYM_SYMM_PAUSE)||(value.cl73_adv.an_pause == TEMOD16_ASYM_SYMM_PAUSE)) {
   1644         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1645         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1646     }
   1647 
   1648     /* get the cl37 sgmii speed */
   1649     switch (value.cl37_adv.cl37_sgmii_speed) {
   1650     case TEMOD16_CL37_SGMII_10M:
   1651         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M;
   1652         break;
   1653     case TEMOD16_CL37_SGMII_100M:
   1654         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M;
   1655         break;
   1656     case TEMOD16_CL37_SGMII_1000M:
   1657         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M;
   1658         break;
   1659     default:
   1660         break;
   1661     }
   1662     /* first check cl73 ability */
   1663     if (value.cl73_adv.an_base_speed &  1 << TEMOD16_CL73_100GBASE_CR10)
   1664         PHYMOD_AN_CAP_100G_CR10_SET(an_ability_get_type->an_cap);
   1665     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_40GBASE_CR4)
   1666         PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   1667     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_40GBASE_KR4)
   1668         PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   1669     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_10GBASE_KR)
   1670         PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   1671     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_10GBASE_KX4)
   1672         PHYMOD_AN_CAP_10G_KX4_SET(an_ability_get_type->an_cap);
   1673     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_1000BASE_KX)
   1674         PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   1675 
   1676     /* next check cl73 bam ability */
   1677     if (value.cl73_adv.an_bam_speed & 1 << TEMOD16_CL73_BAM_20GBASE_KR2)
   1678         PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   1679     if (value.cl73_adv.an_bam_speed & 1 << TEMOD16_CL73_BAM_20GBASE_CR2)
   1680         PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   1681 
   1682     /* check cl37 bam ability */
   1683     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_2p5GBASE_X)
   1684         PHYMOD_BAM_CL37_CAP_2P5G_SET(an_ability_get_type->cl37bam_cap);
   1685     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_5GBASE_X4)
   1686         PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_ability_get_type->cl37bam_cap);
   1687     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_6GBASE_X4)
   1688         PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_ability_get_type->cl37bam_cap);
   1689     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X4)
   1690         PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_ability_get_type->cl37bam_cap);
   1691     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X4_CX4)
   1692         PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_ability_get_type->cl37bam_cap);
   1693     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X2)
   1694         PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1695     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X2_CX4)
   1696         PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_ability_get_type->cl37bam_cap);
   1697     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_BAM_10p5GBASE_X2)
   1698         PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1699     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12GBASE_X4)
   1700         PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_ability_get_type->cl37bam_cap);
   1701     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12p5GBASE_X4)
   1702         PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_ability_get_type->cl37bam_cap);
   1703     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12p7GBASE_X2)
   1704         PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1705 
   1706     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_13GBASE_X4)
   1707         PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_ability_get_type->cl37bam_cap);
   1708     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_15GBASE_X4)
   1709         PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_ability_get_type->cl37bam_cap);
   1710     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_15p75GBASE_X2)
   1711         PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1712     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_16GBASE_X4)
   1713         PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_ability_get_type->cl37bam_cap);
   1714     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X4_CX4)
   1715         PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_ability_get_type->cl37bam_cap);
   1716     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X4)
   1717         PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_ability_get_type->cl37bam_cap);
   1718     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X2)
   1719         PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_ability_get_type->cl37bam_cap);
   1720     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X2_CX4)
   1721         PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_ability_get_type->cl37bam_cap);
   1722     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_21GBASE_X4)
   1723         PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_ability_get_type->cl37bam_cap);
   1724     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_25p455GBASE_X4)
   1725         PHYMOD_BAM_CL37_CAP_25P455G_SET(an_ability_get_type->cl37bam_cap);
   1726     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_31p5GBASE_X4)
   1727         PHYMOD_BAM_CL37_CAP_31P5G_SET(an_ability_get_type->cl37bam_cap);
   1728     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_32p7GBASE_X4)
   1729         PHYMOD_BAM_CL37_CAP_32P7G_SET(an_ability_get_type->cl37bam_cap);
   1730     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_40GBASE_X4)
   1731         PHYMOD_BAM_CL37_CAP_40G_SET(an_ability_get_type->cl37bam_cap);
   1732 
   1733     return PHYMOD_E_NONE;
   1734 }
   1735 
   1736 int tsce16_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
   1737 {
   1738     temod16_an_ability_t value;
   1739     temod16_an_control_t an_control;
   1740     phymod_phy_access_t phy_copy;
   1741     int an_complete = 0;
   1742     int start_lane, num_lane;
   1743 
   1744     PHYMOD_IF_ERR_RETURN
   1745         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1746     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1747     phy_copy.access.lane_mask = 0x1 << start_lane;
   1748     PHYMOD_MEMSET(&value, 0x0, sizeof(value));
   1749     PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control));
   1750 
   1751     PHYMOD_IF_ERR_RETURN
   1752         (temod16_autoneg_remote_ability_get(&phy_copy.access, &value));
   1753     an_ability_get_type->an_cl72 = value.cl37_adv.an_cl72 | value.cl73_adv.an_cl72;
   1754     an_ability_get_type->an_hg2 = value.cl37_adv.an_hg2;
   1755     an_ability_get_type->an_fec = value.cl37_adv.an_fec | value.cl73_adv.an_fec;
   1756     PHYMOD_IF_ERR_RETURN
   1757         (temod16_autoneg_control_get(&phy_copy.access, &an_control, &an_complete));
   1758 
   1759     if (an_control.an_type == TEMOD16_AN_MODE_CL73 || an_control.an_type == TEMOD16_AN_MODE_CL73BAM) {
   1760       if (value.cl73_adv.an_pause == TEMOD16_ASYM_PAUSE) {
   1761           PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1762       } else if (value.cl73_adv.an_pause == TEMOD16_SYMM_PAUSE) {
   1763           PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1764       } else if (value.cl73_adv.an_pause == TEMOD16_ASYM_SYMM_PAUSE) {
   1765           PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1766           PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1767       }
   1768     } else {
   1769       if (value.cl37_adv.an_pause == TEMOD16_ASYM_PAUSE) {
   1770           PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1771       } else if (value.cl37_adv.an_pause == TEMOD16_SYMM_PAUSE) {
   1772           PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1773       } else if (value.cl37_adv.an_pause == TEMOD16_ASYM_SYMM_PAUSE) {
   1774           PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type);
   1775           PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type);
   1776       }
   1777     }
   1778 
   1779     if (an_control.an_type == TEMOD16_AN_MODE_CL37) {
   1780         PHYMOD_AN_CAP_CL37_SET(an_ability_get_type);
   1781     }
   1782 
   1783     /* get the cl37 sgmii speed */
   1784     switch (value.cl37_adv.cl37_sgmii_speed) {
   1785     case TEMOD16_CL37_SGMII_10M:
   1786         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M;
   1787         break;
   1788     case TEMOD16_CL37_SGMII_100M:
   1789         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M;
   1790         break;
   1791     case TEMOD16_CL37_SGMII_1000M:
   1792         an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M;
   1793         break;
   1794     default:
   1795         break;
   1796     }
   1797 
   1798     /* first check cl73 ability */
   1799     if (value.cl73_adv.an_base_speed &  1 << TEMOD16_CL73_100GBASE_CR10)
   1800         PHYMOD_AN_CAP_100G_CR10_SET(an_ability_get_type->an_cap);
   1801     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_40GBASE_CR4)
   1802         PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap);
   1803     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_40GBASE_KR4)
   1804         PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap);
   1805     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_10GBASE_KR)
   1806         PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap);
   1807     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_10GBASE_KX4)
   1808         PHYMOD_AN_CAP_10G_KX4_SET(an_ability_get_type->an_cap);
   1809     if (value.cl73_adv.an_base_speed & 1 << TEMOD16_CL73_1000BASE_KX)
   1810         PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap);
   1811 
   1812     /* next check cl73 bam ability */
   1813     if (value.cl73_adv.an_bam_speed & 1 << TEMOD16_CL73_BAM_20GBASE_KR2)
   1814         PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap);
   1815     if (value.cl73_adv.an_bam_speed & 1 << TEMOD16_CL73_BAM_20GBASE_CR2)
   1816         PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap);
   1817 
   1818     /* check cl37 bam ability */
   1819     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_2p5GBASE_X)
   1820         PHYMOD_BAM_CL37_CAP_2P5G_SET(an_ability_get_type->cl37bam_cap);
   1821     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_5GBASE_X4)
   1822         PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_ability_get_type->cl37bam_cap);
   1823     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_6GBASE_X4)
   1824         PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_ability_get_type->cl37bam_cap);
   1825     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X4)
   1826         PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_ability_get_type->cl37bam_cap);
   1827     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X4_CX4)
   1828         PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_ability_get_type->cl37bam_cap);
   1829     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X2)
   1830         PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1831     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_10GBASE_X2_CX4)
   1832         PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_ability_get_type->cl37bam_cap);
   1833     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_BAM_10p5GBASE_X2)
   1834         PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1835     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12GBASE_X4)
   1836         PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_ability_get_type->cl37bam_cap);
   1837     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12p5GBASE_X4)
   1838         PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_ability_get_type->cl37bam_cap);
   1839     if (value.cl37_adv.an_bam_speed & 1 << TEMOD16_CL37_BAM_12p7GBASE_X2)
   1840         PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1841 
   1842     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_13GBASE_X4)
   1843         PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_ability_get_type->cl37bam_cap);
   1844     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_15GBASE_X4)
   1845         PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_ability_get_type->cl37bam_cap);
   1846     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_15p75GBASE_X2)
   1847         PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap);
   1848     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_16GBASE_X4)
   1849         PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_ability_get_type->cl37bam_cap);
   1850     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X4_CX4)
   1851         PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_ability_get_type->cl37bam_cap);
   1852     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X4)
   1853         PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_ability_get_type->cl37bam_cap);
   1854     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X2)
   1855         PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_ability_get_type->cl37bam_cap);
   1856     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_20GBASE_X2_CX4)
   1857         PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_ability_get_type->cl37bam_cap);
   1858     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_21GBASE_X4)
   1859         PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_ability_get_type->cl37bam_cap);
   1860     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_25p455GBASE_X4)
   1861         PHYMOD_BAM_CL37_CAP_25P455G_SET(an_ability_get_type->cl37bam_cap);
   1862     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_31p5GBASE_X4)
   1863         PHYMOD_BAM_CL37_CAP_31P5G_SET(an_ability_get_type->cl37bam_cap);
   1864     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_32p7GBASE_X4)
   1865         PHYMOD_BAM_CL37_CAP_32P7G_SET(an_ability_get_type->cl37bam_cap);
   1866     if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD16_CL37_BAM_40GBASE_X4)
   1867         PHYMOD_BAM_CL37_CAP_40G_SET(an_ability_get_type->cl37bam_cap);
   1868 
   1869     return PHYMOD_E_NONE;
   1870 }
   1871 
   1872 int tsce16_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
   1873 {
   1874     int num_lane_adv_encoded;
   1875     phymod_firmware_lane_config_t firmware_lane_config;
   1876     phymod_firmware_core_config_t firmware_core_config_tmp;
   1877     int start_lane, num_lane, i;
   1878     phymod_phy_access_t phy_copy;
   1879     temod16_an_control_t an_control;
   1880     int single_port = 0 ;
   1881 
   1882     PHYMOD_IF_ERR_RETURN
   1883         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   1884 
   1885     PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config));
   1886     PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control));
   1887     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   1888     phy_copy.access.lane_mask = 0x1 << start_lane;
   1889 
   1890     switch (an->num_lane_adv) {
   1891         case 1:
   1892             num_lane_adv_encoded = 0;
   1893             break;
   1894         case 2:
   1895             num_lane_adv_encoded = 1;
   1896             break;
   1897         case 4:
   1898             num_lane_adv_encoded = 2;
   1899             break;
   1900         case 10:
   1901             num_lane_adv_encoded = 3;
   1902             break;
   1903         default:
   1904             return PHYMOD_E_PARAM;
   1905     }
   1906 
   1907     if(PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) {
   1908         an_control.pd_kx_en = 1;
   1909     } else {
   1910         an_control.pd_kx_en = 0;
   1911     }
   1912     if(PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_GET(an)) {
   1913         an_control.pd_kx4_en = 1;
   1914     } else {
   1915         an_control.pd_kx4_en = 0;
   1916     }
   1917     an_control.num_lane_adv = num_lane_adv_encoded;
   1918     an_control.enable       = an->enable;
   1919     an_control.an_property_type = 0x0;
   1920 
   1921     switch (an->an_mode) {
   1922     case phymod_AN_MODE_CL73:
   1923         an_control.an_type = TEMOD16_AN_MODE_CL73;
   1924         break;
   1925     case phymod_AN_MODE_CL37:
   1926         an_control.an_type = TEMOD16_AN_MODE_CL37;
   1927         break;
   1928     case phymod_AN_MODE_CL73BAM:
   1929         an_control.an_type = TEMOD16_AN_MODE_CL73BAM;
   1930         break;
   1931     case phymod_AN_MODE_CL37BAM:
   1932         an_control.an_type = TEMOD16_AN_MODE_CL37BAM;
   1933         break;
   1934     case phymod_AN_MODE_HPAM:
   1935         an_control.an_type = TEMOD16_AN_MODE_HPAM;
   1936         break;
   1937     case phymod_AN_MODE_SGMII:
   1938         an_control.an_type = TEMOD16_AN_MODE_SGMII;
   1939         break;
   1940     default:
   1941         if(an->an_mode ==(phymod_AN_MODE_CL37_SGMII)) {
   1942             an_control.an_type = TEMOD16_AN_MODE_CL37_SGMII ;
   1943         } else {
   1944             an_control.an_type = TEMOD16_AN_MODE_CL73;
   1945         }
   1946         break;
   1947     }
   1948 
   1949     PHYMOD_IF_ERR_RETURN
   1950         (temod16_disable_set(&phy->access));
   1951 
   1952     if (an->num_lane_adv == 4) {
   1953         phy_copy.access.lane_mask = 0x1 << start_lane;
   1954         PHYMOD_IF_ERR_RETURN
   1955             (tsce16_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp));
   1956         PHYMOD_IF_ERR_RETURN
   1957             (merlin16_core_soft_reset_release(&phy_copy.access, 0));
   1958 
   1959         if (an->enable) {
   1960             firmware_core_config_tmp.CoreConfigFromPCS = 1;
   1961         } else {
   1962             firmware_core_config_tmp.CoreConfigFromPCS = 0;
   1963         }
   1964 
   1965         PHYMOD_IF_ERR_RETURN
   1966             (tsce16_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp));
   1967         PHYMOD_IF_ERR_RETURN
   1968             (merlin16_core_soft_reset_release(&phy_copy.access, 1));
   1969     }
   1970 
   1971 
   1972     for (i = 0; i < num_lane; i++) {
   1973         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   1974             continue;
   1975         }
   1976         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   1977         PHYMOD_IF_ERR_RETURN
   1978             (merlin16_lane_soft_reset_release(&phy_copy.access, 0));
   1979     }
   1980 
   1981     PHYMOD_IF_ERR_RETURN
   1982         (tsce16_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config));
   1983 
   1984     if (!PHYMOD_AN_F_IGNORE_MEDIUM_CHECK_GET(an)) {
   1985         if(an_control.an_type == TEMOD16_AN_MODE_CL37) {
   1986             firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics;
   1987         }
   1988     }
   1989 
   1990     if (an->enable) {
   1991         firmware_lane_config.AnEnabled = 1;
   1992         firmware_lane_config.LaneConfigFromPCS = 1;
   1993         firmware_lane_config.Cl72RestTO = 0;
   1994     } else {
   1995         firmware_lane_config.AnEnabled = 0;
   1996         firmware_lane_config.LaneConfigFromPCS = 0;
   1997         firmware_lane_config.Cl72RestTO = 1;
   1998     }
   1999 
   2000     for (i = 0; i < num_lane; i++) {
   2001         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2002             continue;
   2003         }
   2004         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2005         PHYMOD_IF_ERR_RETURN
   2006             (_tsce16_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config));
   2007     }
   2008 
   2009     for (i = 0; i < num_lane; i++) {
   2010         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2011             continue;
   2012         }
   2013         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2014         PHYMOD_IF_ERR_RETURN
   2015             (merlin16_lane_soft_reset_release(&phy_copy.access, 1));
   2016     }
   2017 
   2018     phy_copy.access.lane_mask = 0x1 << start_lane;
   2019     if (!an->enable) {
   2020         PHYMOD_IF_ERR_RETURN
   2021             (temod16_trigger_speed_change(&phy_copy.access));
   2022     }
   2023 
   2024     if (an->enable) {
   2025         if (an->num_lane_adv == 4) {
   2026             single_port = 1 ;
   2027         } else {
   2028             single_port = 0 ;
   2029         }
   2030         PHYMOD_IF_ERR_RETURN
   2031             (temod16_set_an_port_mode(&phy->access, an->enable, num_lane_adv_encoded, start_lane, single_port));
   2032     } else {
   2033         single_port = 0;
   2034         PHYMOD_IF_ERR_RETURN
   2035             (temod16_set_an_port_mode(&phy->access, an->enable, num_lane_adv_encoded, start_lane, single_port));
   2036     }
   2037 
   2038 
   2039     PHYMOD_IF_ERR_RETURN
   2040         (temod16_autoneg_control(&phy_copy.access, &an_control));
   2041 
   2042     return PHYMOD_E_NONE;
   2043 }
   2044 
   2045 int tsce16_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
   2046 {
   2047     temod16_an_control_t an_control;
   2048     phymod_phy_access_t phy_copy;
   2049     int start_lane, num_lane;
   2050     int an_complete = 0;
   2051 
   2052     PHYMOD_IF_ERR_RETURN
   2053         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2054 
   2055     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2056     phy_copy.access.lane_mask = 0x1 << start_lane;
   2057 
   2058     PHYMOD_MEMSET(&an_control, 0x0,  sizeof(temod16_an_control_t));
   2059     PHYMOD_IF_ERR_RETURN
   2060         (temod16_autoneg_control_get(&phy_copy.access, &an_control, &an_complete));
   2061 
   2062     if (an_control.enable) {
   2063         an->enable = 1;
   2064         *an_done = an_complete;
   2065     } else {
   2066         an->enable = 0;
   2067         *an_done   = 0;
   2068     }
   2069     if(an_control.pd_kx_en) {
   2070         PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an);
   2071     } else {
   2072         PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_CLR(an);
   2073     }
   2074     if(an_control.pd_kx4_en) {
   2075         PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_SET(an);
   2076     } else {
   2077         PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_CLR(an);
   2078     }
   2079 
   2080     switch (an_control.an_type) {
   2081         case TEMOD16_AN_MODE_CL73:
   2082             an->an_mode = phymod_AN_MODE_CL73;
   2083             break;
   2084         case TEMOD16_AN_MODE_CL37:
   2085             an->an_mode = phymod_AN_MODE_CL37;
   2086             break;
   2087         case TEMOD16_AN_MODE_CL73BAM:
   2088             an->an_mode = phymod_AN_MODE_CL73BAM;
   2089             break;
   2090         case TEMOD16_AN_MODE_CL37BAM:
   2091             an->an_mode = phymod_AN_MODE_CL37BAM;
   2092             break;
   2093         case TEMOD16_AN_MODE_HPAM:
   2094             an->an_mode = phymod_AN_MODE_HPAM;
   2095             break;
   2096         case TEMOD16_AN_MODE_SGMII:
   2097             an->an_mode = phymod_AN_MODE_SGMII;
   2098             break;
   2099         default:
   2100             an->an_mode = phymod_AN_MODE_NONE;
   2101             break;
   2102     }
   2103 
   2104     return PHYMOD_E_NONE;
   2105 }
   2106 
   2107 
   2108 /*
   2109  * There is a significant change from TSCE 28nm to 16nm in terms of the
   2110  * PMD programming sequence. Please be aware that the underlying PMD changed
   2111  * from eagle to merlin16. The PCS programming sequence remained the same.
   2112  * Some comments are added below to highlight the PMD programming changes.
   2113  */
   2114 STATIC
   2115 int _tsce16_core_init_pass1(const phymod_core_access_t* core,
   2116                           const phymod_core_init_config_t* init_config,
   2117                           const phymod_core_status_t* core_status)
   2118 {
   2119     phymod_phy_access_t phy_access, phy_access_copy;
   2120     phymod_core_access_t  core_copy;
   2121     uint32_t  uc_active = 0;
   2122     int i, start_lane, num_lane;
   2123 
   2124     TSCE16_CORE_TO_PHY_ACCESS(&phy_access, core);
   2125     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   2126     core_copy.access.lane_mask = 0x1;
   2127 
   2128     phy_access_copy = phy_access;
   2129     phy_access_copy.access = core->access;
   2130     phy_access_copy.access.lane_mask = 0x1;
   2131     phy_access_copy.type = core->type;
   2132 
   2133     /*
   2134      * First step to program merlin16 is to do power reset. That is to
   2135      * program field POR_H_RSTB and CORE_DP_H_RSTB in register PMD_X1_CTL
   2136      */
   2137     PHYMOD_IF_ERR_RETURN
   2138         (temod16_pmd_reset_seq(&core_copy.access, core_status->pmd_active));
   2139 
   2140     PHYMOD_IF_ERR_RETURN
   2141         (phymod_util_lane_config_get(&phy_access.access, &start_lane, &num_lane));
   2142 
   2143     /*
   2144      * Before programming the PMD lane address map register, the PMD lanes
   2145      * have to be reset. Without do this, writing the PMD lane address map
   2146      * regsiter will not take effect, meaning the reading value != writing
   2147      * value.
   2148      */
   2149     for (i = 0; i < num_lane; i++) {
   2150         phy_access.access.lane_mask = 1 << (start_lane + i);
   2151         PHYMOD_IF_ERR_RETURN
   2152             (temod16_pmd_x4_reset(&phy_access.access));
   2153     }
   2154 
   2155     PHYMOD_IF_ERR_RETURN(merlin16_uc_active_get(&core_copy.access, &uc_active));
   2156     if (uc_active) {
   2157         return(PHYMOD_E_NONE);
   2158     }
   2159 
   2160     /* need to set the heart beat default is for 156.25M */
   2161     PHYMOD_IF_ERR_RETURN (temod16_refclk_set(&core_copy.access,
   2162                           init_config->interface.ref_clock));
   2163 
   2164     /*
   2165      * In 28nm TSCE code the lane map programming was done in core_init_pass2.
   2166      * Now it is moved to pass1 because merlin16 requires that PMD lane address
   2167      * map be done before loading the uCode. Notice that before programming the
   2168      * PMD lane address map, lane and lane DP has to be reset by calling
   2169      * temod16_pmd_x4_reset().
   2170      */
   2171     PHYMOD_IF_ERR_RETURN
   2172         (tsce16_core_lane_map_set(&core_copy, &init_config->lane_map));
   2173 
   2174     PHYMOD_IF_ERR_RETURN
   2175         (merlin16_uc_reset(&phy_access_copy.access, 1));
   2176 
   2177     if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   2178         if (_tsce16_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader)) {
   2179             PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask));
   2180             PHYMOD_IF_ERR_RETURN (PHYMOD_E_INIT);
   2181         }
   2182 
   2183     }
   2184 
   2185     PHYMOD_IF_ERR_RETURN
   2186         (merlin16_pmd_ln_h_rstb_pkill_override(&phy_access_copy.access, 0x1));
   2187     PHYMOD_IF_ERR_RETURN
   2188         (merlin16_uc_reset(&phy_access_copy.access, 0));
   2189     PHYMOD_IF_ERR_RETURN
   2190         (merlin16_wait_uc_active(&phy_access_copy.access));
   2191 
   2192     /* Initialize software information table for the micro */
   2193     PHYMOD_IF_ERR_RETURN
   2194         (merlin16_init_merlin16_info(&core_copy.access));
   2195 
   2196     if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   2197         if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   2198             PHYMOD_IF_ERR_RETURN
   2199                 (merlin16_start_ucode_crc_calc(&core_copy.access, merlin16_ucode_len));
   2200         }
   2201     }
   2202 
   2203     return (PHYMOD_E_NONE);
   2204 }
   2205 
   2206 STATIC
   2207 int _tsce16_core_init_pass2(const phymod_core_access_t* core,
   2208                             const phymod_core_init_config_t* init_config,
   2209                             const phymod_core_status_t* core_status)
   2210 {
   2211     phymod_phy_access_t phy_access, phy_access_copy;
   2212     phymod_core_access_t  core_copy;
   2213     phymod_firmware_core_config_t  firmware_core_config_tmp;
   2214 
   2215     TSCE16_CORE_TO_PHY_ACCESS(&phy_access, core);
   2216     PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy));
   2217     core_copy.access.lane_mask = 0x1;
   2218 
   2219     phy_access_copy = phy_access;
   2220     phy_access_copy.access = core->access;
   2221     phy_access_copy.access.lane_mask = 0x1;
   2222     phy_access_copy.type = core->type;
   2223 
   2224     if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) {
   2225         if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) {
   2226             PHYMOD_IF_ERR_RETURN
   2227                 (merlin16_check_ucode_crc(&core_copy.access, merlin16_ucode_crc, 250));
   2228         }
   2229     }
   2230 
   2231     PHYMOD_IF_ERR_RETURN(
   2232         merlin16_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0));
   2233 
   2234     /* next check if in pcs-bypass mode */
   2235     if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) {
   2236         phy_access_copy.access.lane_mask = 0xf;
   2237         PHYMOD_IF_ERR_RETURN(
   2238             temod16_pcs_ilkn_mode_set(&phy_access_copy.access));
   2239         phy_access_copy.access.lane_mask = 0x1;
   2240     }
   2241 
   2242     PHYMOD_IF_ERR_RETURN
   2243         (temod16_autoneg_timer_init(&core->access));
   2244 
   2245     phy_access_copy.access.lane_mask = 0x1;
   2246 
   2247     PHYMOD_IF_ERR_RETURN
   2248         (temod16_master_port_num_set(&core->access, 0));
   2249 
   2250     PHYMOD_IF_ERR_RETURN
   2251         (merlin16_core_soft_reset_release(&core_copy.access, 0));
   2252 
   2253     /* After loading the PMD uCode, PLL needs to be configured. */
   2254     PHYMOD_IF_ERR_RETURN
   2255         (merlin16_configure_pll_refclk_div(&phy_access_copy.access, MERLIN16_PLL_REFCLK_156P25MHZ,
   2256                                                MERLIN16_PLL_DIV_66));
   2257 
   2258     PHYMOD_IF_ERR_RETURN
   2259         (tsce16_phy_firmware_core_config_get(&phy_access_copy, &firmware_core_config_tmp));
   2260     firmware_core_config_tmp.CoreConfigFromPCS = 0;
   2261 
   2262     PHYMOD_IF_ERR_RETURN
   2263         (tsce16_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp));
   2264 
   2265 
   2266     PHYMOD_IF_ERR_RETURN
   2267         (temod16_cl74_chng_default (&core_copy.access));
   2268 
   2269     /*
   2270      * After programming the PMD PLL, we need to release the core reset and lane reset.
   2271      * Core reset is done below, and lane reset is done in tsce16_phy_init() by calling
   2272      * temod16_pmd_x4_reset().
   2273      */
   2274     PHYMOD_IF_ERR_RETURN
   2275         (merlin16_core_soft_reset_release(&core_copy.access, 1));
   2276 
   2277     return PHYMOD_E_NONE;
   2278 }
   2279 
   2280 int tsce16_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
   2281 {
   2282     if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   2283           !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   2284         PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   2285         PHYMOD_IF_ERR_RETURN
   2286             (_tsce16_core_init_pass1(core, init_config, core_status));
   2287 
   2288         if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
   2289             return PHYMOD_E_NONE;
   2290         }
   2291     }
   2292 
   2293     if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) &&
   2294           !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) ||
   2295         PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) {
   2296         PHYMOD_IF_ERR_RETURN
   2297             (_tsce16_core_init_pass2(core, init_config, core_status));
   2298     }
   2299 
   2300     return PHYMOD_E_NONE;
   2301 
   2302 }
   2303 
   2304 int tsce16_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
   2305 {
   2306     int pll_restart = 0;
   2307     const phymod_access_t *pm_acc = &phy->access;
   2308     phymod_phy_access_t pm_phy_copy;
   2309     int start_lane, num_lane, i;
   2310     int lane_bkup;
   2311     phymod_polarity_t tmp_pol;
   2312 #ifdef PHYMOD_DIAG
   2313     PHYMOD_VDBG(DBG_CFG, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32"\n",
   2314                 __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask));
   2315 #endif
   2316     PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol));
   2317     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   2318 
   2319     /* next program the tx fir taps and driver current based on the input */
   2320     PHYMOD_IF_ERR_RETURN
   2321         (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane));
   2322     /* per lane based reset release */
   2323     PHYMOD_IF_ERR_RETURN
   2324         (temod16_pmd_x4_reset(pm_acc));
   2325 
   2326     /* poll for per lane uc_dsc_ready */
   2327     lane_bkup = pm_phy_copy.access.lane_mask;
   2328     for (i = 0; i < num_lane; i++) {
   2329         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2330             continue;
   2331         }
   2332         pm_phy_copy.access.lane_mask = 1 << (start_lane + i);
   2333         PHYMOD_IF_ERR_RETURN
   2334             (merlin16_lane_soft_reset_release(&pm_phy_copy.access, 1));
   2335     }
   2336     pm_phy_copy.access.lane_mask = lane_bkup;
   2337 
   2338     /* program the rx/tx polarity */
   2339     for (i = 0; i < num_lane; i++) {
   2340         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2341             continue;
   2342         }
   2343         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2344         tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1;
   2345         tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1;
   2346         PHYMOD_IF_ERR_RETURN
   2347             (tsce16_phy_polarity_set(&pm_phy_copy, &tmp_pol));
   2348     }
   2349 
   2350     for (i = 0; i < num_lane; i++) {
   2351         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2352             continue;
   2353         }
   2354         pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane);
   2355         PHYMOD_IF_ERR_RETURN
   2356             (tsce16_phy_tx_set(&pm_phy_copy, &init_config->tx[i]));
   2357     }
   2358 
   2359     /* next check if pcs-bypass mode  */
   2360     if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) {
   2361         PHYMOD_IF_ERR_RETURN
   2362             (merlin16_pmd_tx_disable_pin_dis_set(&phy->access, 1));
   2363         PHYMOD_IF_ERR_RETURN
   2364           (temod16_init_pcs_ilkn(&phy->access));
   2365     }
   2366 
   2367 
   2368     pm_phy_copy.access.lane_mask = 0x1;
   2369 
   2370     PHYMOD_IF_ERR_RETURN
   2371         (temod16_update_port_mode(pm_acc, &pll_restart));
   2372 
   2373     PHYMOD_IF_ERR_RETURN
   2374         (temod16_rx_lane_control_set(pm_acc, 1));
   2375     PHYMOD_IF_ERR_RETURN
   2376         (temod16_tx_lane_control_set(pm_acc, TEMOD16_TX_LANE_RESET_TRAFFIC_ENABLE));         /* TX_LANE_CONTROL */
   2377 
   2378     return PHYMOD_E_NONE;
   2379 }
   2380 
   2381 int tsce16_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
   2382 {
   2383     struct merlin16_uc_lane_config_st serdes_firmware_config;
   2384 #ifdef PHYMOD_DIAG
   2385     const phymod_access_t *pm_acc;
   2386     pm_acc = &phy->access;
   2387     PHYMOD_VDBG(DBG_CL72, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" cl72_en=%d\n",
   2388                 __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, (int)cl72_en));
   2389 #endif
   2390 
   2391     PHYMOD_IF_ERR_RETURN(merlin16_get_uc_lane_cfg(&phy->access, &serdes_firmware_config));
   2392 
   2393     if (serdes_firmware_config.field.dfe_on == 0) {
   2394       PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72 with no DFE\n"));
   2395       return PHYMOD_E_CONFIG;
   2396     }
   2397 
   2398     PHYMOD_IF_ERR_RETURN
   2399         (temod16_clause72_control(&phy->access, cl72_en));
   2400     return PHYMOD_E_NONE;
   2401 }
   2402 
   2403 int tsce16_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
   2404 {
   2405     uint32_t local_status;
   2406     PHYMOD_IF_ERR_RETURN
   2407         (merlin16_pmd_cl72_receiver_status(&phy->access, &local_status));
   2408     status->locked = local_status;
   2409     return PHYMOD_E_NONE;
   2410 }
   2411 
   2412 int tsce16_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable)
   2413 {
   2414     uint32_t lpi_bypass;
   2415     int rv = PHYMOD_E_NONE;
   2416 
   2417     lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable);
   2418     enable &= 0x1;
   2419     if (lpi_bypass) {
   2420         rv = temod16_eee_control_set(&phy->access,enable);
   2421     } else {
   2422         return PHYMOD_E_UNAVAIL;
   2423     }
   2424 
   2425     return rv;
   2426 }
   2427 
   2428 int tsce16_phy_eee_get(const phymod_phy_access_t* phy, uint32_t* enable)
   2429 {
   2430     if (PHYMOD_LPI_BYPASS_GET(*enable)) {
   2431         PHYMOD_IF_ERR_RETURN(temod16_eee_control_get(&phy->access, enable));
   2432         PHYMOD_LPI_BYPASS_SET(*enable);
   2433     } else {
   2434         return PHYMOD_E_UNAVAIL;
   2435     }
   2436 
   2437     return PHYMOD_E_NONE;
   2438 }
   2439 
   2440 int tsce16_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
   2441 {
   2442     uint32_t local_en;;
   2443     PHYMOD_IF_ERR_RETURN
   2444         (merlin16_pmd_cl72_enable_get(&phy->access, &local_en));
   2445     *cl72_en = local_en;
   2446     return PHYMOD_E_NONE;
   2447 }
   2448 
   2449 int tsce16_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
   2450 {
   2451 
   2452     int start_lane, num_lane;
   2453     uint32_t cl72_en;
   2454     phymod_phy_access_t phy_copy;
   2455     const phymod_access_t *pm_acc;
   2456 
   2457     pm_acc = &phy->access;
   2458 #ifdef PHYMOD_DIAG
   2459     PHYMOD_VDBG(DBG_LPK, pm_acc, ("%-22s: p=%p adr=%0"PRIx32" lmask=%0"PRIx32" lpbk=%0d(%s) en=%0d\n",
   2460               __func__, (void *)pm_acc, pm_acc->addr, pm_acc->lane_mask, loopback,
   2461                             phymod_loopback_mode_t_mapping[loopback].key, enable));
   2462 #endif
   2463     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2464 
   2465     /* next figure out the lane num and start_lane based on the input */
   2466     PHYMOD_IF_ERR_RETURN
   2467         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2468 
   2469     switch (loopback) {
   2470     case phymodLoopbackGlobal:
   2471         PHYMOD_IF_ERR_RETURN
   2472             (tsce16_phy_cl72_get(phy, &cl72_en));
   2473         if ((cl72_en == 1) && (enable == 1)) {
   2474              PHYMOD_DEBUG_ERROR(("adr=%0"PRIx32",lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n",  pm_acc->addr, start_lane));
   2475              break;
   2476         }
   2477         PHYMOD_IF_ERR_RETURN(temod16_tx_loopback_control(&phy->access, enable, start_lane, num_lane));
   2478         break;
   2479     case phymodLoopbackGlobalPMD:
   2480         PHYMOD_IF_ERR_RETURN(temod16_tx_squelch_set(&phy_copy.access, enable));
   2481         PHYMOD_IF_ERR_RETURN(merlin16_pmd_loopback_set(&phy->access, enable));
   2482 
   2483         break;
   2484     case phymodLoopbackRemotePMD:
   2485         PHYMOD_IF_ERR_RETURN(merlin16_rmt_lpbk(&phy->access, enable));
   2486         break;
   2487     case phymodLoopbackRemotePCS:
   2488         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   2489                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   2490         break;
   2491     default:
   2492         break;
   2493     }
   2494 
   2495     return PHYMOD_E_NONE;
   2496 }
   2497 
   2498 int tsce16_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   2499 {
   2500     uint32_t enable_core;
   2501     int start_lane, num_lane;
   2502 
   2503     *enable = 0;
   2504 
   2505     /* next figure out the lane num and start_lane based on the input */
   2506     PHYMOD_IF_ERR_RETURN
   2507         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2508 
   2509     switch (loopback) {
   2510     case phymodLoopbackGlobal :
   2511         PHYMOD_IF_ERR_RETURN(temod16_tx_loopback_get(&phy->access, &enable_core));
   2512         *enable = (enable_core >> start_lane) & 0x1;
   2513         break;
   2514     case phymodLoopbackGlobalPMD :
   2515         PHYMOD_IF_ERR_RETURN(merlin16_pmd_loopback_get(&phy->access, enable));
   2516         break;
   2517     case phymodLoopbackRemotePMD :
   2518         PHYMOD_IF_ERR_RETURN(merlin16_rmt_lpbk_get(&phy->access, enable));
   2519         break;
   2520     case phymodLoopbackRemotePCS :
   2521         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   2522                                (_PHYMOD_MSG("PCS Remote LoopBack not supported")));
   2523         break;
   2524     default :
   2525         break;
   2526     }
   2527     return PHYMOD_E_NONE;
   2528 }
   2529 
   2530 int tsce16_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
   2531 {
   2532     PHYMOD_IF_ERR_RETURN(temod16_get_pcs_latched_link_status(&phy->access, link_status));
   2533 
   2534     return PHYMOD_E_NONE;
   2535 }
   2536 
   2537 int tsce16_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t *val)
   2538 {
   2539     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val));
   2540     return PHYMOD_E_NONE;
   2541 }
   2542 
   2543 int tsce16_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
   2544 {
   2545     PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val));
   2546     return PHYMOD_E_NONE;
   2547 }
   2548 
   2549 int tsce16_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
   2550 {
   2551     return PHYMOD_E_UNAVAIL;
   2552 }
   2553 
   2554 int tsce16_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
   2555 {
   2556     int8_t value = 0;
   2557 
   2558     PHYMOD_IF_ERR_RETURN
   2559         (merlin16_read_tx_afe(&phy->access, TX_AFE_PRE, &value));
   2560     tx->pre = value;
   2561     PHYMOD_IF_ERR_RETURN
   2562         (merlin16_read_tx_afe(&phy->access, TX_AFE_MAIN, &value));
   2563     tx->main = value;
   2564     PHYMOD_IF_ERR_RETURN
   2565         (merlin16_read_tx_afe(&phy->access, TX_AFE_POST1, &value));
   2566     tx->post = value;
   2567     PHYMOD_IF_ERR_RETURN
   2568         (merlin16_read_tx_afe(&phy->access, TX_AFE_POST2, &value));
   2569     tx->post2 = value;
   2570 
   2571     return PHYMOD_E_NONE;
   2572 }
   2573 
   2574 int tsce16_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
   2575 {
   2576     return PHYMOD_E_UNAVAIL;
   2577 }
   2578 
   2579 int tsce16_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
   2580 {
   2581     int i, start_lane, num_lane;
   2582     phymod_phy_access_t phy_copy;
   2583 
   2584     PHYMOD_IF_ERR_RETURN
   2585         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2586     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2587 
   2588     for (i = 0; i < num_lane; i++) {
   2589         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
   2590             continue;
   2591         }
   2592         phy_copy.access.lane_mask = 1 << (start_lane + i);
   2593         PHYMOD_IF_ERR_RETURN(temod16_fecmode_set(&phy_copy.access, enable));
   2594     }
   2595 
   2596     return PHYMOD_E_NONE;
   2597 }
   2598 
   2599 int tsce16_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
   2600 {
   2601     PHYMOD_IF_ERR_RETURN(temod16_fecmode_get(&phy->access, enable));
   2602 
   2603     return PHYMOD_E_NONE;
   2604 }
   2605 
   2606 int tsce16_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
   2607 {
   2608     PHYMOD_IF_ERR_RETURN(temod16_pmd_lock_get(&phy->access, rx_pmd_locked));
   2609 
   2610     return PHYMOD_E_NONE;
   2611 }
   2612 
   2613 int tsce16_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm)
   2614 {
   2615     int start_lane, num_lane;
   2616     phymod_phy_access_t pm_phy_copy;
   2617 
   2618     PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy));
   2619 
   2620     PHYMOD_IF_ERR_RETURN
   2621         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2622 
   2623     pm_phy_copy.access.lane_mask = 1 << start_lane;
   2624     PHYMOD_IF_ERR_RETURN
   2625         (merlin16_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm));
   2626 
   2627     return PHYMOD_E_NONE;
   2628 }
   2629 
   2630 int tsce16_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy,
   2631                                   phymod_synce_clk_ctrl_t cfg)
   2632 {
   2633     phymod_phy_access_t phy_copy;
   2634     int start_lane, num_lane;
   2635 
   2636     PHYMOD_IF_ERR_RETURN
   2637         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
   2638 
   2639     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
   2640     phy_copy.access.lane_mask = 0x1 << start_lane;
   2641 
   2642     PHYMOD_IF_ERR_RETURN
   2643         (temod16_synce_stg0_mode_set(&phy_copy.access, cfg.stg0_mode));
   2644 
   2645     PHYMOD_IF_ERR_RETURN
   2646         (temod16_synce_stg1_mode_set(&phy_copy.access, cfg.stg1_mode));
   2647 
   2648     PHYMOD_IF_ERR_RETURN
   2649         (temod16_synce_clk_ctrl_set(&phy_copy.access, cfg.sdm_val));
   2650 
   2651     return PHYMOD_E_NONE;
   2652 }
   2653 
   2654 int tsce16_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy,
   2655                                   phymod_synce_clk_ctrl_t *cfg)
   2656 {
   2657     PHYMOD_IF_ERR_RETURN
   2658         (temod16_synce_stg0_mode_get(&phy->access, &(cfg->stg0_mode)));
   2659 
   2660     PHYMOD_IF_ERR_RETURN
   2661         (temod16_synce_stg1_mode_get(&phy->access, &(cfg->stg1_mode)));
   2662 
   2663     PHYMOD_IF_ERR_RETURN
   2664         (temod16_synce_clk_ctrl_get(&phy->access, &(cfg->sdm_val)));
   2665 
   2666     return PHYMOD_E_NONE;
   2667 }