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

tbhmod_cfg_seq.c (208596B)


      1 /*----------------------------------------------------------------------
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * $Copyright: (c) 2014 Broadcom Corporation All Rights Reserved.$
      8  * Broadcom Corporation
      9  * Proprietary and Confidential information
     10  * All rights reserved
     11  * This source file is the property of Broadcom Corporation, and
     12  * may not be copied or distributed in any isomorphic form without the
     13  * prior written consent of Broadcom Corporation.
     14  *---------------------------------------------------------------------
     15  * File       : tbhmod_cfg_seq.c
     16  * Description: c functions implementing Tier1s for TEFMod Serdes Driver
     17  *---------------------------------------------------------------------*/
     18 
     19 #ifndef _DV_TB_
     20  #define _SDK_TBHMOD_ 1
     21 #endif
     22 
     23 #ifdef _DV_TB_
     24 #include <stdint.h>
     25 #include "tbhmod_main.h"
     26 #include "tbhmod_defines.h"
     27 #include "tbhmod_spd_ctrl.h"
     28 #include "tbhmod.h"
     29 #include "tbhPCSRegEnums.h"
     30 #include "tbhPMDRegEnums.h"
     31 #include "phy_tsc_iblk.h"
     32 #include "bcmi_tscbh_xgxs_defs.h"
     33 
     34 #endif /* _DV_TB_ */
     35 
     36 #ifdef _SDK_TBHMOD_
     37 #include <phymod/phymod.h>
     38 #include <phymod/phymod_system.h>
     39 #include <phymod/phymod_util.h>
     40 #include <phymod/phymod_debug.h>
     41 #include <phymod/chip/bcmi_tscbh_xgxs_defs.h>
     42 #include <phymod/chip/bcmi_tscbh_gen2_xgxs_defs.h>
     43 #include "blackhawk/tier1/blackhawk_cfg_seq.h"
     44 #include "blackhawk/tier1/blackhawk_tsc_enum.h"
     45 #include "blackhawk/tier1/blackhawk_tsc_common.h"
     46 #include "blackhawk/tier1/blackhawk_tsc_interface.h"
     47 #include "blackhawk/tier1/blackhawk_tsc_dependencies.h"
     48 #include "blackhawk/tier1/blackhawk_tsc_internal.h"
     49 #include "blackhawk/tier1/public/blackhawk_api_uc_vars_rdwr_defns_public.h"
     50 #include "blackhawk/tier1/blackhawk_tsc_access.h"
     51 #include "tbhmod_enum_defines.h"
     52 #include "tbhmod_spd_ctrl.h"
     53 #include "tbhmod.h"
     54 #include "tbhmod_sc_lkup_table.h"
     55 #include "tbhPCSRegEnums.h"
     56 #endif /* _SDK_TBHMOD_ */
     57 
     58 #ifndef _SDK_TBHMOD_
     59 #define PHYMOD_ST const phymod_access_t
     60 #endif
     61 
     62 #ifdef _SDK_TBHMOD_
     63   #define TBHMOD_DBG_IN_FUNC_INFO(pc) \
     64     PHYMOD_VDBG(TBHMOD_DBG_FUNC,pc,("-22%s: Adr:%08x Ln:%02d\n", __func__, pc->addr, pc->lane_mask))
     65   #define TBHMOD_DBG_IN_FUNC_VIN_INFO(pc,_print_) \
     66     PHYMOD_VDBG(TBHMOD_DBG_FUNCVALIN,pc,_print_)
     67   #define TBHMOD_DBG_IN_FUNC_VOUT_INFO(pc,_print_) \
     68     PHYMOD_VDBG(TBHMOD_DBG_FUNCVALOUT,pc,_print_)
     69 #endif
     70 
     71 #ifdef _DV_TB_
     72   #define TBHMOD_DBG_IN_FUNC_INFO(pc) \
     73     PHYMOD_VDBG(TBHMOD_DBG_FUNC, pc, \
     74       ("TBHMOD IN Function : %s Port Add : %d Lane No: %d\n", \
     75       __func__, pc->prt_ad, pc->this_lane))
     76   #define TBHMOD_DBG_IN_FUNC_VIN_INFO(pc,_print_) \
     77     PHYMOD_VDBG(TBHMOD_DBG_FUNCVALIN,pc,_print_)
     78   #define TBHMOD_DBG_IN_FUNC_VOUT_INFO(pc,_print_) \
     79     PHYMOD_VDBG(TBHMOD_DBG_FUNCVALOUT,pc,_print_)
     80 int phymod_debug_check(uint32_t flags, tbhmod_st *pc);
     81 #endif
     82 
     83 #define TSCBH_GEN1           0x25 /* 0x9008 Main0_serdesID - Serdes ID Register */
     84 #define TSCBH_GEN2           0x26 /* 0x9008 Main0_serdesID - Serdes ID Register */
     85 
     86 /* This function will return model num for the core */
     87 int tbhmod_model_num_get(PHYMOD_ST* pc, uint32_t* model_num)
     88 {
     89     MAIN0_SERDESIDr_t MAIN0_SERDESIDr_reg;
     90 
     91     PHYMOD_IF_ERR_RETURN(READ_MAIN0_SERDESIDr(pc, &MAIN0_SERDESIDr_reg));
     92     *model_num = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(MAIN0_SERDESIDr_reg);
     93 
     94     return PHYMOD_E_NONE;
     95 }
     96 
     97 
     98 int tbhmod_pmd_reset_seq(PHYMOD_ST* pc, int pmd_touched) /* PMD_RESET_SEQ */
     99 {
    100     PMD_X1_CTLr_t reg_pmd_x1_ctrl;
    101     MAIN0_SETUP_GEN2r_t main0_reg;
    102     uint32_t model_num;
    103 
    104     PMD_X1_CTLr_CLR(reg_pmd_x1_ctrl);
    105     MAIN0_SETUP_GEN2r_CLR(main0_reg);
    106 
    107     /* first read the model number */
    108     /* for tscbh gen1, the fclk is hardwired to PLL1 */
    109     /* in Gen2, flck selection needs to be programmed the same as the tvco  PLL index */
    110     pc->lane_mask = 0x1 << 0;
    111     PHYMOD_IF_ERR_RETURN(tbhmod_model_num_get(pc, &model_num));
    112 
    113     if (pmd_touched == 0) {
    114         PMD_X1_CTLr_POR_H_RSTBf_SET(reg_pmd_x1_ctrl,1);
    115         PMD_X1_CTLr_CORE_DP_H_RSTBf_SET(reg_pmd_x1_ctrl,1);
    116         PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X1_CTLr(pc,reg_pmd_x1_ctrl));
    117         if (model_num == TSCBH_GEN2) {
    118             /* need to prgram the fclock source based on the tvco index */
    119             MAIN0_SETUP_GEN2r_FCLK_SELf_SET(main0_reg, pc->tvco_pll_index);
    120             PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUP_GEN2r(pc, main0_reg));
    121         }
    122 
    123         /* next change the MPP index to 1 */
    124         pc->lane_mask = 0x1 << 4;
    125         PMD_X1_CTLr_CLR(reg_pmd_x1_ctrl);
    126         PMD_X1_CTLr_POR_H_RSTBf_SET(reg_pmd_x1_ctrl,1);
    127         PMD_X1_CTLr_CORE_DP_H_RSTBf_SET(reg_pmd_x1_ctrl,1);
    128         PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X1_CTLr(pc,reg_pmd_x1_ctrl));
    129 
    130         if (model_num == TSCBH_GEN2) {
    131             /* need to prgram the fclock source based on the tvco index */
    132             MAIN0_SETUP_GEN2r_FCLK_SELf_SET(main0_reg, pc->tvco_pll_index);
    133             PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUP_GEN2r(pc, main0_reg));
    134         }
    135     }
    136     return PHYMOD_E_NONE;
    137 }
    138 
    139 
    140 /*!
    141 @brief   get  port speed id configured
    142 @param   pc handle to current TSCBH context (#tbhmod_st)
    143 @param   speed_id Receives the resolved speed cfg in the speed_id
    144 @returns The value PHYMOD_E_NONE upon successful completion.
    145 @details get  port speed configured
    146 */
    147 int tbhmod_speed_id_get(PHYMOD_ST* pc, int *speed_id)
    148 {
    149   SC_X4_RSLVD_SPDr_t sc_final_resolved_speed;
    150 
    151   SC_X4_RSLVD_SPDr_CLR(sc_final_resolved_speed);
    152   PHYMOD_IF_ERR_RETURN(READ_SC_X4_RSLVD_SPDr(pc,&sc_final_resolved_speed));
    153   *speed_id = SC_X4_RSLVD_SPDr_SPEEDf_GET(sc_final_resolved_speed);
    154 
    155   return PHYMOD_E_NONE;
    156 }
    157 
    158 
    159 
    160 /**
    161 @brief   Get the Port status
    162 @param   pc handle to current TSCBH context (#tbhmod_st)
    163 @param   disabled  Receives status on port disabledness
    164 @returns The value PHYMOD_E_NONE upon successful completion
    165 @details Ports can be disabled in several ways. In this function we simply write
    166 0 to the speed change which will bring the PCS down for that lane.
    167 
    168 */
    169 int tbhmod_enable_get(PHYMOD_ST* pc, uint32_t* enable)
    170 {
    171   SC_X4_CTLr_t reg_sc_ctrl;
    172 
    173   SC_X4_CTLr_CLR(reg_sc_ctrl);
    174 
    175   PHYMOD_IF_ERR_RETURN(READ_SC_X4_CTLr(pc,&reg_sc_ctrl));
    176   *enable = SC_X4_CTLr_SW_SPEED_CHANGEf_GET(reg_sc_ctrl);
    177 
    178   return PHYMOD_E_NONE;
    179 }
    180 /**
    181 @brief   Get info on Disable status of the Port
    182 @param   pc handle to current TSCBH context (#tbhmod_st)
    183 @returns The value PHYMOD_E_NONE upon successful completion
    184 @details Disables the port by writing 0 to the speed config logic in PCS.
    185 This makes the PCS to bring down the PCS blocks and also apply lane datapath
    186 reset to the PMD. There is no control input to this function since it only does
    187 one thing.
    188 */
    189 int tbhmod_disable_set(PHYMOD_ST* pc)
    190 {
    191   SC_X4_CTLr_t reg_sc_ctrl;
    192 
    193   SC_X4_CTLr_CLR(reg_sc_ctrl);
    194 
    195   SC_X4_CTLr_SW_SPEED_CHANGEf_SET(reg_sc_ctrl, 0);
    196   PHYMOD_IF_ERR_RETURN(MODIFY_SC_X4_CTLr(pc,reg_sc_ctrl));
    197 
    198   return PHYMOD_E_NONE;
    199 }
    200 
    201 int tbhmod_enable_set(PHYMOD_ST* pc)
    202 {
    203   SC_X4_CTLr_t reg_sc_ctrl;
    204 
    205   SC_X4_CTLr_CLR(reg_sc_ctrl);
    206 
    207   SC_X4_CTLr_SW_SPEED_CHANGEf_SET(reg_sc_ctrl, 1);
    208   PHYMOD_IF_ERR_RETURN(MODIFY_SC_X4_CTLr(pc,reg_sc_ctrl));
    209 
    210   return PHYMOD_E_NONE;
    211 }
    212 
    213 /**
    214 @brief   rx lane reset and enable of any particular lane
    215 @param   pc handle to current TSCBH context (#tbhmod_st)
    216 @param   Get the configured reset lane.
    217 @returns The value PHYMOD_E_NONE upon successful completion.
    218 @details
    219           This function read back control bit
    220 */
    221 int tbhmod_rx_lane_control_get(PHYMOD_ST* pc, int *enable)         /* RX_LANE_CONTROL */
    222 {
    223   RX_X4_PMA_CTL0r_t    reg_pma_ctrl;
    224 
    225   RX_X4_PMA_CTL0r_CLR(reg_pma_ctrl);
    226   PHYMOD_IF_ERR_RETURN (READ_RX_X4_PMA_CTL0r(pc, &reg_pma_ctrl));
    227   *enable =   RX_X4_PMA_CTL0r_RSTB_LANEf_GET( reg_pma_ctrl);
    228 
    229   return PHYMOD_E_NONE;
    230 }
    231 
    232 /*!
    233 @brief Override TX lane output.
    234 @param  pc handle to current TSCBH context (#tbhmod_st)
    235 @param  tx control lanes to disable
    236 @returns PHYMOD_E_NONE if no errors. PHYMOD_ERROR else.
    237 @details This function enables/disables, via override, transmission on a specific lane. No reset is
    238 required to restart the transmission. Lane control is done through 'ovrr' and 'value' inputs.
    239 <B>Set ovrr=0 & value=0 : No override of tx_disable to PMD lanes 0/1/2/3</B>
    240 <B>Set ovrr=0 & value=1 : No override of tx_disable to PMD lanes 0/1/2/3</B>
    241 <B>Set ovrr=1 & value=0 : Override tx_disable to inactive for PMD lanes 0/1/2/3</B>
    242 <B>Set ovrr=1 & value=1 : Override tx_disable to active for PMD lanes 0/1/2/3</B>
    243 */
    244 
    245 /* FCSN */
    246 int tbhmod_tx_lane_disable (PHYMOD_ST* pc, uint16_t ovrr, uint16_t value)
    247 
    248 {
    249   PMD_X4_CTLr_t  PMD_X4_PMD_X4_CONTROLr_reg;
    250   PMD_X4_OVRRr_t PMD_X4_PMD_X4_OVERRIDEr_reg;
    251 
    252   #ifdef _DV_TB_
    253   PHYMOD_DEBUG_ERROR(("FCSN_Info : tbhmod_tx_lane_disable : port %0d : ovrr %0d : value %0d\n", pc.this_lane, ovrr, value));
    254   #endif
    255 
    256   if(ovrr) {
    257     PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
    258     PMD_X4_CTLr_TX_DISABLEf_SET(PMD_X4_PMD_X4_CONTROLr_reg, value);
    259     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
    260 
    261     PMD_X4_OVRRr_CLR(PMD_X4_PMD_X4_OVERRIDEr_reg);
    262     PMD_X4_OVRRr_TX_DISABLE_OENf_SET(PMD_X4_PMD_X4_OVERRIDEr_reg, ovrr);
    263     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_PMD_X4_OVERRIDEr_reg));
    264   }
    265   else { /* remove the override first then set the "don't care" value - prevents glitches */
    266     PMD_X4_OVRRr_CLR(PMD_X4_PMD_X4_OVERRIDEr_reg);
    267     PMD_X4_OVRRr_TX_DISABLE_OENf_SET(PMD_X4_PMD_X4_OVERRIDEr_reg, ovrr);
    268     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_PMD_X4_OVERRIDEr_reg));
    269 
    270     PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
    271     PMD_X4_CTLr_TX_DISABLEf_SET(PMD_X4_PMD_X4_CONTROLr_reg, value);
    272     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
    273   }
    274   return PHYMOD_E_NONE;
    275 }
    276 
    277 /* ------------------------------------------------------------------------- */
    278 
    279 /* FCSN */
    280 int tbhmod_rx_lock_ovrd(PHYMOD_ST* pc, uint16_t ovrd)
    281 {
    282   PMD_X4_OVRRr_t PMD_X4_PMD_X4_OVERRIDEr_reg;
    283 
    284 
    285   PMD_X4_OVRRr_CLR(PMD_X4_PMD_X4_OVERRIDEr_reg);
    286   PMD_X4_OVRRr_RX_LOCK_OVRDf_SET(PMD_X4_PMD_X4_OVERRIDEr_reg, ovrd);
    287   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_PMD_X4_OVERRIDEr_reg));
    288 
    289 
    290   return PHYMOD_E_NONE;
    291 }
    292 
    293 /* ------------------------------------------------------------------------- */
    294 
    295 /* FCSN */
    296 int tbhmod_rx_sigdet_ovrd(PHYMOD_ST* pc, uint16_t ovrd)
    297 {
    298   PMD_X4_OVRRr_t PMD_X4_PMD_X4_OVERRIDEr_reg;
    299 
    300 
    301   PMD_X4_OVRRr_CLR(PMD_X4_PMD_X4_OVERRIDEr_reg);
    302   PMD_X4_OVRRr_SIGNAL_DETECT_OVRDf_SET(PMD_X4_PMD_X4_OVERRIDEr_reg, ovrd);
    303   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_PMD_X4_OVERRIDEr_reg));
    304 
    305   return PHYMOD_E_NONE;
    306 }
    307 
    308 
    309 
    310 
    311 int tbhmod_pcs_set_ilkn_wm(PHYMOD_ST* pc,int ilkn_wm)
    312 {
    313   ILKN_CTL0r_t ILKN_CONTROL0r_reg;
    314 
    315 
    316   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
    317   ILKN_CTL0r_SOFT_RST_RXf_SET(ILKN_CONTROL0r_reg, 1);
    318   ILKN_CTL0r_SOFT_RST_TXf_SET(ILKN_CONTROL0r_reg, 1);
    319   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
    320 
    321   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
    322   ILKN_CTL0r_WMf_SET(ILKN_CONTROL0r_reg, ilkn_wm);
    323   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
    324 
    325   return PHYMOD_E_NONE;
    326 }
    327 
    328 #ifdef _DV_TB_
    329 /*!
    330 @brief Controls PMD reset pins irrespective of PCS is in Speed Control mode or not
    331 aram  pc handle to current TSCBH context (#tbhmod_st)
    332 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
    333 @details Set the ::tbhmod_st::per_lane_control field of #tbhmod_st to <B>0 to
    334 disable</B> PCS  <B>1 to enable</B>.
    335 */
    336 
    337 /* Ensure that tier2 and phymod control exist to access this function */
    338 int tbhmod_pmd_lane_reset_bypass (PHYMOD_ST* pc, int pmd_reset_control)     /* PMD_LANE_RESET_BYPASS */
    339 {
    340   int cntl;
    341   PMD_X4_OVRRr_t PMD_X4_OVERRIDEr_reg;
    342   PMD_X4_CTLr_t PMD_X4_PMD_X4_CONTROLr_reg;
    343 
    344 
    345   cntl = pmd_reset_control & 0x10;
    346 
    347   if (cntl) {
    348     PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
    349     PMD_X4_CTLr_LN_DP_H_RSTBf_SET(PMD_X4_PMD_X4_CONTROLr_reg,1);
    350     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
    351 
    352     PMD_X4_OVRRr_CLR(PMD_X4_OVERRIDEr_reg);
    353     PMD_X4_OVRRr_LN_DP_H_RSTB_OENf_SET(PMD_X4_OVERRIDEr_reg, 1);
    354     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_OVERRIDEr_reg));
    355 
    356   } else {
    357     PMD_X4_OVRRr_CLR(PMD_X4_OVERRIDEr_reg);
    358     PMD_X4_OVRRr_LN_DP_H_RSTB_OENf_SET(PMD_X4_OVERRIDEr_reg,0);
    359     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, PMD_X4_OVERRIDEr_reg));
    360 
    361     PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
    362     PMD_X4_CTLr_LN_DP_H_RSTBf_SET(PMD_X4_PMD_X4_CONTROLr_reg,0);
    363     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
    364   }
    365 
    366 
    367   return PHYMOD_E_NONE;
    368 } /* PMD_RESET_BYPASS */
    369 
    370 
    371 
    372 #endif
    373 
    374 
    375 int tbhmod_set_sw_mgmt_glb_mask(PHYMOD_ST* pc, int mask)
    376 {
    377   AN_X1_GLB_MASKr_t AN_X1_GLB_MASKr_reg;
    378   AN_X1_GLB_MASKr_SET(AN_X1_GLB_MASKr_reg, mask);
    379   PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_GLB_MASKr(pc, AN_X1_GLB_MASKr_reg));
    380 
    381   return PHYMOD_E_NONE;
    382 }
    383 
    384 
    385 /*!
    386 @brief Controls the setting/resetting of autoneg advertisement registers.
    387 @param  pc handle to current TSCBH context (#tbhmod_st)
    388 @param  cl73_adv struct of type  #tbhmod_an_adv_ability_t
    389 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
    390 @details
    391 TBD
    392 */
    393 
    394 #ifdef _DV_TB_
    395 int tbhmod_sw_autoneg_set(PHYMOD_ST* pc, sw_autoneg_st* an_st)               /* SW_AUTONEG_SET */
    396 {
    397   AN_X4_INT_ENr_t AN_X4_INT_ENr_reg;
    398   AN_X4_WAIT_ACK_COMPLETEr_t AN_X4_WAIT_ACK_COMPLETEr_reg;
    399 
    400 
    401   AN_X4_INT_ENr_CLR(AN_X4_INT_ENr_reg);
    402   AN_X4_INT_ENr_AN_COMPLETED_SW_ENf_SET(AN_X4_INT_ENr_reg, an_st->sw_an_completed_en);
    403   AN_X4_INT_ENr_LP_PAGE_RDY_ENf_SET(AN_X4_INT_ENr_reg, an_st->lp_page_rdy_en);
    404   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_INT_ENr(pc, AN_X4_INT_ENr_reg));
    405 
    406   AN_X4_WAIT_ACK_COMPLETEr_CLR(AN_X4_WAIT_ACK_COMPLETEr_reg);
    407   AN_X4_WAIT_ACK_COMPLETEr_WAIT_FOR_ACK_ENf_SET(AN_X4_WAIT_ACK_COMPLETEr_reg, an_st->sw_an_wait_for_ack);
    408   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_WAIT_ACK_COMPLETEr(pc, AN_X4_WAIT_ACK_COMPLETEr_reg));
    409 
    410   tbhmod_set_sw_mgmt_glb_mask(dv_st, 0xf);
    411 
    412   return PHYMOD_E_NONE;
    413 }
    414 
    415 #endif
    416 
    417 /*!
    418  * @brief   Controls the setting/resetting of autoneg advertisement registers.
    419  * @param   pc handle to current TSCBH context (#PHYMOD_ST)
    420  * @returns PHYMOD_E_NONE if no errors. PHYMOD_E_FAIL else.
    421  * @details
    422  *   Get aneg features via an_ability_st and write the pages
    423  *   This does not start the autoneg. That is done in tbhmod_autoneg_control
    424 */
    425 int tbhmod_autoneg_ability_set(PHYMOD_ST* pc,
    426                                const phymod_autoneg_advert_abilities_t* autoneg_abilities)
    427 {
    428   AN_X4_LD_BASE_ABIL1r_t AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg;
    429   AN_X4_LD_BASE_ABIL2r_t AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg;
    430   AN_X4_LD_BASE_ABIL3r_t AN_X4_ABILITIES_LD_BASE_ABILITIES_3r_reg;
    431   AN_X4_LD_UP1_ABIL_0_GEN2r_t AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg;
    432   AN_X4_LD_UP1_ABIL_1_GEN2r_t AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg;
    433   AN_X4_CL73_CFGr_t      AN_X4_CL73_CFGr_reg;
    434   phymod_autoneg_advert_ability_t *an_ability;
    435   uint32_t i;
    436   uint8_t fec_is_shared, no_baser_support;
    437   AN_X4_LD_CTLr_t an_x4_ctrl_reg;
    438 
    439   TBHMOD_DBG_IN_FUNC_INFO(pc);
    440 
    441   AN_X4_LD_BASE_ABIL1r_CLR(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg);
    442   AN_X4_LD_BASE_ABIL2r_CLR(AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg);
    443   AN_X4_LD_BASE_ABIL3r_CLR(AN_X4_ABILITIES_LD_BASE_ABILITIES_3r_reg);
    444   AN_X4_LD_UP1_ABIL_0_GEN2r_CLR(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg);
    445   AN_X4_LD_UP1_ABIL_1_GEN2r_CLR(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg);
    446   AN_X4_CL73_CFGr_CLR(AN_X4_CL73_CFGr_reg);
    447   AN_X4_LD_CTLr_CLR(an_x4_ctrl_reg);
    448 
    449   /* Write base page bit position for 50GKR_CR, 100GKR2_CR2, 200GKR4_CR4 */
    450   /* Bit position need revisit after IEEE SPEC finialized */
    451   AN_X4_LD_BASE_ABIL2r_BASE_50G_KR_CR_SELf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg, TBHMOD_CL73_ABILITY_50G_KR1_CR1_POSITION);
    452   AN_X4_LD_BASE_ABIL2r_BASE_100G_KR2_CR2_SELf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg, TBHMOD_CL73_ABILITY_100G_KR2_CR2_POSITION);
    453   AN_X4_LD_BASE_ABIL3r_BASE_200G_KR4_CR4_SELf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_3r_reg, TBHMOD_CL73_ABILITY_200G_KR4_CR4_POSITION);
    454 
    455   /* Set default value */
    456   AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, 0);
    457   AN_X4_LD_BASE_ABIL1r_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 0x1);
    458   AN_X4_LD_UP1_ABIL_1_GEN2r_RS_FEC_REQf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 0x1);
    459   AN_X4_LD_UP1_ABIL_1_GEN2r_CL74_REQf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 0x1);
    460 
    461   no_baser_support = 0;
    462 
    463   for (i = 0; i < autoneg_abilities->num_abilities; i++) {
    464       an_ability = &autoneg_abilities->autoneg_abilities[i];
    465       fec_is_shared = 0;
    466       switch (an_ability->speed) {
    467           case 10000:
    468               /* CL73-10G-1lane */
    469               AN_X4_LD_BASE_ABIL1r_BASE_10G_KR1f_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    470               fec_is_shared = 1;
    471               break;
    472           case 20000:
    473               /* CL73BAM-20G-1lane */
    474               if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    475                   AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_20G_CR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    476               } else {
    477                   AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_20G_KR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    478               }
    479               fec_is_shared = 1;
    480               break;
    481           case 25000:
    482               if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    483                   /* CL73 */
    484                   if (an_ability->channel == phymod_channel_short) {
    485                       AN_X4_LD_BASE_ABIL1r_BASE_25G_CRS_KRSf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    486                   } else {
    487                       AN_X4_LD_BASE_ABIL1r_BASE_25G_CR_KRf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    488                   }
    489               } else {
    490                   /* MSA and CL73BAM share the same speed ability fields */
    491                   if (an_ability->an_mode == phymod_AN_MODE_MSA) {
    492                       AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, 1);
    493                   }
    494                   if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    495                       AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_CR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    496                   } else {
    497                       AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_KR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    498                   }
    499               }
    500               fec_is_shared = 1;
    501               break;
    502           case 40000:
    503               if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    504                   /* CL73-40G-4lanes */
    505                   if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    506                       AN_X4_LD_BASE_ABIL1r_BASE_40G_CR4f_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    507                   } else {
    508                       AN_X4_LD_BASE_ABIL1r_BASE_40G_KR4f_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    509                   }
    510               } else {
    511                   /* CL73BAM-40G-2lanes */
    512                   if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    513                       AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_40G_CR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    514                   } else {
    515                       AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_40G_KR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    516                   }
    517               }
    518               fec_is_shared = 1;
    519               break;
    520           case 50000:
    521               if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    522                   /* CL73-50G-1lane */
    523                   AN_X4_LD_BASE_ABIL2r_BASE_50G_KR_CR_ENf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg, 1);
    524               } else if (an_ability->an_mode == phymod_AN_MODE_CL73BAM) {
    525                   if (an_ability->resolved_num_lanes == 1) {
    526                       /* CL73BAM-50G-1lane */
    527                       if (an_ability->fec == phymod_fec_None) {
    528                           AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_NO_FEC_CR1_KR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    529                       } else {
    530                           AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_FEC_528_CR1_KR1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    531                       }
    532                   } else {
    533                       /* CL73BAM-50G-2lanes */
    534                       if (an_ability->fec == phymod_fec_RS544) {
    535                           AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_FEC_544_CR2_KR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    536                       } else {
    537                           if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    538                               AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_CR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    539                           } else {
    540                               AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_KR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    541                           }
    542                           fec_is_shared = 1;
    543                           no_baser_support = 1;
    544                       }
    545                   }
    546               } else {
    547                   AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, 1);
    548                   /* first check 50G  RS272 1 lane MSA ability*/
    549                   if ((an_ability->resolved_num_lanes == 1) && (an_ability->fec == phymod_fec_RS272)) {
    550                       /* first need to set the  MSA_LFR bit */
    551                       AN_X4_LD_UP1_ABIL_1_GEN2r_MSA_LFRf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    552                       AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_KR4_CR4_MSA_LF1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    553                   } else if (an_ability->resolved_num_lanes == 2) {
    554                       /* MSA-50G-2lanes */
    555                       if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    556                           AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_CR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    557                       } else {
    558                           AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_KR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    559                       }
    560                       fec_is_shared = 1;
    561                       no_baser_support = 1;
    562                   }
    563               }
    564               break;
    565           case 100000:
    566               if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    567                   if (an_ability->resolved_num_lanes == 2) {
    568                       /* CL73-100G-2lanes */
    569                       AN_X4_LD_BASE_ABIL2r_BASE_100G_KR2_CR2_ENf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg,1);
    570                   } else {
    571                       /* CL73_100G-4lanes */
    572                       if (an_ability->medium == phymodFirmwareMediaTypeCopperCable) {
    573                           AN_X4_LD_BASE_ABIL1r_BASE_100G_CR4f_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    574                       } else {
    575                           AN_X4_LD_BASE_ABIL1r_BASE_100G_KR4f_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    576                       }
    577                   }
    578               } else if (an_ability->an_mode == phymod_AN_MODE_MSA) {
    579                   if ((an_ability->resolved_num_lanes == 2) && (an_ability->fec == phymod_fec_RS272)) {
    580                       /* first need to set MSA FEC mapping bit */
    581                       AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, 1);
    582                       /* then need to set the  MSA_LFR bit */
    583                       AN_X4_LD_UP1_ABIL_1_GEN2r_MSA_LFRf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    584                       AN_X4_LD_UP1_ABIL_0_GEN2r_SPEED_SPARE_22_MSA_LF2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    585                   }
    586               } else {
    587                   /*below ability is for CL73BAM */
    588                   if (an_ability->resolved_num_lanes == 2) {
    589                       /* CL73BAM-100G-2lanes */
    590                       if (an_ability->fec == phymod_fec_None) {
    591                           AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_NO_FEC_KR2_CR2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    592                       } else {
    593                           AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_FEC_528_KR2_CR2_LF3f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    594                       }
    595                   } else {
    596                       /* CL73BAM-100G-4lanes */
    597                       if (an_ability->fec == phymod_fec_None) {
    598                           AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_NO_FEC_X4f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    599                       } else {
    600                           AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_KR4_CR4_MSA_LF1f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    601                       }
    602                   }
    603               }
    604               break;
    605           case 200000:
    606               if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    607                   /* CL73-200G-4lanes */
    608                   AN_X4_LD_BASE_ABIL3r_BASE_200G_KR4_CR4_ENf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_3r_reg, 1);
    609               } else if (an_ability->an_mode == phymod_AN_MODE_MSA) {
    610                   if ((an_ability->resolved_num_lanes == 4) && (an_ability->fec == phymod_fec_RS272_2XN)) {
    611                       /* first need to set MSA FEC mapping bit */
    612                       AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, 1);
    613                       /* then need to set the  MSA_LFR bit */
    614                       AN_X4_LD_UP1_ABIL_1_GEN2r_MSA_LFRf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    615                       AN_X4_LD_UP1_ABIL_0_GEN2r_SPEED_SPARE_22_MSA_LF2f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    616                   }
    617               } else {
    618                   /* CL73BAM-200G-4lanes */
    619                   if (an_ability->fec == phymod_fec_None) {
    620                       AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_200G_BRCM_NO_FEC_KR4_CR4f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    621                   } else {
    622                       AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_200G_BRCM_KR4_CR4f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 1);
    623                   }
    624               }
    625               break;
    626           case 400000:
    627           {
    628               AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_400G_BRCM_FEC_KR8_CR8f_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg, 1);
    629               AN_X4_LD_CTLr_AN_HCD_RES_DISABLEf_SET(an_x4_ctrl_reg, 1);
    630               break;
    631           }
    632           default:
    633               break;
    634       }
    635 
    636       if (fec_is_shared) {
    637           if (an_ability->an_mode == phymod_AN_MODE_CL73) {
    638               /****** Base FEC Settings ********/
    639               if (an_ability->speed == 25000) {
    640                   if (an_ability->fec == phymod_fec_CL91) {
    641                       AN_X4_LD_BASE_ABIL1r_BASE_25G_RS_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    642                   } else if (an_ability->fec == phymod_fec_CL74) {
    643                       AN_X4_LD_BASE_ABIL1r_BASE_25G_BASE_R_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    644                   }
    645               } else {
    646                   if (an_ability->fec == phymod_fec_CL74) {
    647                       AN_X4_LD_BASE_ABIL1r_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 3);
    648                   } else {
    649                       AN_X4_LD_BASE_ABIL1r_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    650                   }
    651               }
    652           } else {
    653               /****** BAM FEC ******/
    654               if (an_ability->fec == phymod_fec_CL91) {
    655                   AN_X4_LD_UP1_ABIL_1_GEN2r_RS_FEC_REQf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 0x3);
    656               } else if(an_ability->fec == phymod_fec_CL74) {
    657                   AN_X4_LD_UP1_ABIL_1_GEN2r_CL74_REQf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 0x3);
    658               }
    659           }
    660       }
    661 
    662       /******* Pause Settings ********/
    663       if(an_ability->pause == phymod_pause_none)
    664         AN_X4_LD_BASE_ABIL1r_CL73_PAUSEf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 0);
    665       if(an_ability->pause == phymod_pause_symm)
    666         AN_X4_LD_BASE_ABIL1r_CL73_PAUSEf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 1);
    667       if(an_ability->pause == phymod_pause_asym)
    668         AN_X4_LD_BASE_ABIL1r_CL73_PAUSEf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 2);
    669       if(an_ability->pause == phymod_pause_asym_symm)
    670         AN_X4_LD_BASE_ABIL1r_CL73_PAUSEf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 3);
    671   }
    672 
    673   /* 50G-2 lane does not support Base-R.
    674    * Need to make sure Base-R bits are cleared in both Base and UP page */
    675   if (no_baser_support) {
    676       AN_X4_LD_BASE_ABIL1r_FEC_REQf_SET(AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg, 0x0);
    677       AN_X4_LD_UP1_ABIL_1_GEN2r_CL74_REQf_SET(AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg, 0x0);
    678   }
    679 
    680   /***** Setting AN_X4_ABILITIES_cl73_cfg 0xC1C0 *********/
    681   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_CL73_CFGr_reg));
    682   /***** Setting AN_X4_ABILITIES_ld_base_abilities_1 0xC1C4 *******/
    683   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_BASE_ABIL1r(pc, AN_X4_ABILITIES_LD_BASE_ABILITIES_1r_reg));
    684   /***** Setting AN_X4_ABILITIES_ld_base_abilities_1 0xC1C7 *******/
    685   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_BASE_ABIL2r(pc, AN_X4_ABILITIES_LD_BASE_ABILITIES_2r_reg ));
    686   /***** Setting AN_X4_ABILITIES_ld_base_abilities_1 0xC1C8 *******/
    687   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_BASE_ABIL3r(pc, AN_X4_ABILITIES_LD_BASE_ABILITIES_3r_reg ));
    688   /******** Setting AN_X4_ABILITIES_ld_up1_abilities_0 0xC1C1******/
    689   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_UP1_ABIL_0_GEN2r(pc, AN_X4_ABILITIES_LD_UP1_ABILITIES_0r_reg));
    690   /******** Setting AN_X4_ABILITIES_ld_up1_abilities_0 0xC1C2******/
    691   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_UP1_ABIL_1_GEN2r(pc, AN_X4_ABILITIES_LD_UP1_ABILITIES_1r_reg));
    692   /******** Setting AN_X4_CTRL 0xC1e7******/
    693   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_CTLr(pc, an_x4_ctrl_reg));
    694 
    695 
    696   return PHYMOD_E_NONE;
    697 }
    698 
    699 int _an_ability_construct(phymod_autoneg_advert_ability_t* an_ability,
    700                           uint32_t speed,
    701                           int num_lanes,
    702                           phymod_fec_type_t fec,
    703                           uint32_t pause,
    704                           int channel,
    705                           phymod_an_mode_type_t an_mode)
    706 {
    707   an_ability->speed = speed;
    708   an_ability->resolved_num_lanes = num_lanes;
    709   an_ability->fec = fec;
    710   an_ability->pause = pause;
    711   an_ability->channel = channel;
    712   an_ability->an_mode = an_mode;
    713   /* We get medium type from FW lane config in tier 2 */
    714   an_ability->medium = 0;
    715 
    716   return PHYMOD_E_NONE;
    717 }
    718 
    719 /**
    720  * @brief   To get local autoneg advertisement registers.
    721  * @param   pc handle to current TSCBH context (#PHYMOD_ST)
    722  * @param   an_ability_st receives autoneg info. #tefmod16_an_adv_ability_t)
    723  * @returns PHYMOD_E_NONE if no errors. PHYMOD_E_FAIL else.
    724  * @details Upper layer software calls this function to get local autoneg
    725  *          info. This function is currently not implemented
    726  */
    727 int tbhmod_autoneg_ability_get(PHYMOD_ST* pc, phymod_autoneg_advert_abilities_t* autoneg_abilities)
    728 {
    729   AN_X4_LD_BASE_ABIL1r_t        AN_X4_LD_BASE_ABIL1r_reg;
    730   AN_X4_LD_UP1_ABIL_0_GEN2r_t   AN_X4_LD_UP1_ABIL0r_reg;
    731   AN_X4_LD_UP1_ABIL_1_GEN2r_t   AN_X4_LD_UP1_ABIL1r_reg;
    732   AN_X4_LD_BASE_ABIL2r_t        AN_X4_LD_BASE_ABIL2r_reg;
    733   AN_X4_LD_BASE_ABIL3r_t        AN_X4_LD_BASE_ABIL3r_reg;
    734   AN_X4_CL73_CFGr_t             AN_X4_CL73_CFGr_reg;
    735   uint32_t pause, fec_cl74, fec_cl91, model_num;
    736   int i = 0;
    737   PHYMOD_ST phy_copy;
    738 
    739 
    740   TBHMOD_DBG_IN_FUNC_INFO(pc);
    741   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
    742 
    743   /*first read serdes model number */
    744   phy_copy.lane_mask = 0x1 << 0;
    745   PHYMOD_IF_ERR_RETURN(tbhmod_model_num_get(&phy_copy, &model_num));
    746 
    747   /***** AN_X4_ABILITIES_ld_base_abilities_1 0xC1C4 *******/
    748   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL1r(pc, &AN_X4_LD_BASE_ABIL1r_reg));
    749   /***** AN_X4_ABILITIES_ld_base_abilities_2 0xC1C7 ******/
    750   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL2r(pc, &AN_X4_LD_BASE_ABIL2r_reg));
    751   /***** AN_X4_ABILITIES_ld_base_abilities_3 0xC1C8 ******/
    752   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL3r(pc, &AN_X4_LD_BASE_ABIL3r_reg));
    753   /***** AN_X4_ABILITIES_ld_up0_abilities_1 0xC1C1 *******/
    754   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_UP1_ABIL_0_GEN2r(pc, &AN_X4_LD_UP1_ABIL0r_reg));
    755   /***** AN_X4_ABILITIES_ld_up1_abilities_1 0xC1C2 *******/
    756   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_UP1_ABIL_1_GEN2r(pc, &AN_X4_LD_UP1_ABIL1r_reg));
    757   /***** AN_X4_ABILITIES_cl73_cfg 0xC1C0 *******/
    758   PHYMOD_IF_ERR_RETURN(READ_AN_X4_CL73_CFGr(pc, &AN_X4_CL73_CFGr_reg));
    759 
    760   pause = AN_X4_LD_BASE_ABIL1r_CL73_PAUSEf_GET(AN_X4_LD_BASE_ABIL1r_reg);
    761 
    762   /* Get CL73 base abilities */
    763   fec_cl74 = AN_X4_LD_BASE_ABIL1r_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg);
    764 
    765   if (AN_X4_LD_BASE_ABIL3r_BASE_200G_KR4_CR4_ENf_GET(AN_X4_LD_BASE_ABIL3r_reg)) {
    766       PHYMOD_IF_ERR_RETURN(
    767           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    768                                 200000, 4, phymod_fec_RS544_2XN, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    769       
    770       i++;
    771   }
    772   if (AN_X4_LD_BASE_ABIL2r_BASE_100G_KR2_CR2_ENf_GET(AN_X4_LD_BASE_ABIL2r_reg)) {
    773       PHYMOD_IF_ERR_RETURN(
    774           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    775                                 100000, 2, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    776       i++;
    777   }
    778   if (AN_X4_LD_BASE_ABIL1r_BASE_100G_KR4f_GET(AN_X4_LD_BASE_ABIL1r_reg)
    779       || AN_X4_LD_BASE_ABIL1r_BASE_100G_CR4f_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    780       PHYMOD_IF_ERR_RETURN(
    781           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    782                                 100000, 4, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    783       i++;
    784   }
    785   if (AN_X4_LD_BASE_ABIL2r_BASE_50G_KR_CR_ENf_GET(AN_X4_LD_BASE_ABIL2r_reg)) {
    786       PHYMOD_IF_ERR_RETURN(
    787           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    788                                 50000, 1, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    789       i++;
    790   }
    791   if (AN_X4_LD_BASE_ABIL1r_BASE_40G_KR4f_GET(AN_X4_LD_BASE_ABIL1r_reg)
    792        || AN_X4_LD_BASE_ABIL1r_BASE_40G_CR4f_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    793       if (fec_cl74 == 0x3) {
    794           PHYMOD_IF_ERR_RETURN(
    795               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    796                                    40000, 4, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    797       } else {
    798           PHYMOD_IF_ERR_RETURN(
    799               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    800                                    40000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    801       }
    802       i++;
    803   }
    804   if (AN_X4_LD_BASE_ABIL1r_BASE_25G_CR_KRf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    805       if (AN_X4_LD_BASE_ABIL1r_BASE_25G_RS_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg)
    806           || AN_X4_LD_BASE_ABIL1r_BASE_25G_BASE_R_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    807           if (AN_X4_LD_BASE_ABIL1r_BASE_25G_RS_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    808               PHYMOD_IF_ERR_RETURN(
    809                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    810                                         25000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    811               i++;
    812           }
    813           if (AN_X4_LD_BASE_ABIL1r_BASE_25G_BASE_R_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    814               PHYMOD_IF_ERR_RETURN(
    815                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    816                                         25000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    817               i++;
    818           }
    819       } else {
    820           PHYMOD_IF_ERR_RETURN(
    821               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    822                                     25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    823           i++;
    824       }
    825   }
    826   if (AN_X4_LD_BASE_ABIL1r_BASE_25G_CRS_KRSf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    827       /* Short channel does not support RS FEC */
    828       if (AN_X4_LD_BASE_ABIL1r_BASE_25G_BASE_R_FEC_REQf_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    829           PHYMOD_IF_ERR_RETURN(
    830               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    831                                     25000, 1, phymod_fec_CL74, pause, phymod_channel_short, phymod_AN_MODE_CL73));
    832       } else {
    833           PHYMOD_IF_ERR_RETURN(
    834               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    835                                     25000, 1, phymod_fec_None, pause, phymod_channel_short, phymod_AN_MODE_CL73));
    836       }
    837       i++;
    838   }
    839   if (AN_X4_LD_BASE_ABIL1r_BASE_10G_KR1f_GET(AN_X4_LD_BASE_ABIL1r_reg)) {
    840       if (fec_cl74 == 0x3) {
    841           PHYMOD_IF_ERR_RETURN(
    842               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    843                                    10000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    844       } else {
    845           PHYMOD_IF_ERR_RETURN(
    846               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    847                                    10000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
    848       }
    849       i++;
    850   }
    851 
    852   /* first check 400G AN MSA */
    853   if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_400G_BRCM_FEC_KR8_CR8f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    854       PHYMOD_IF_ERR_RETURN(
    855          _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    856                                 400000, 8, phymod_fec_RS544_2XN, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    857       i++;
    858   }
    859 
    860   /* Get UP page abilities */
    861   fec_cl74 = AN_X4_LD_UP1_ABIL_1_GEN2r_CL74_REQf_GET(AN_X4_LD_UP1_ABIL1r_reg);
    862   fec_cl91 = AN_X4_LD_UP1_ABIL_1_GEN2r_RS_FEC_REQf_GET(AN_X4_LD_UP1_ABIL1r_reg);
    863 
    864   if (AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_GET(AN_X4_CL73_CFGr_reg)) {
    865       /* UP page is MSA page */
    866       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_CR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)
    867           || AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_KR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    868           if (!(fec_cl74 == 0x3 || fec_cl91 == 0x3)) {
    869               PHYMOD_IF_ERR_RETURN(
    870                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    871                                         50000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    872               i++;
    873           } else {
    874               if (fec_cl74 == 0x3) {
    875                   PHYMOD_IF_ERR_RETURN(
    876                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    877                                             50000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    878                   i++;
    879               }
    880               if (fec_cl91 == 0x3) {
    881                   PHYMOD_IF_ERR_RETURN(
    882                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    883                                             50000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    884                   i++;
    885               }
    886           }
    887       }
    888       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_CR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)
    889           || AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_KR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    890           if (!(fec_cl74 == 0x3 || fec_cl91 == 0x3)) {
    891               PHYMOD_IF_ERR_RETURN(
    892                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    893                                         25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    894               i++;
    895           } else {
    896               if (fec_cl74 == 0x3) {
    897                   PHYMOD_IF_ERR_RETURN(
    898                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    899                                             25000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    900                   i++;
    901               }
    902               if (fec_cl91 == 0x3) {
    903                   PHYMOD_IF_ERR_RETURN(
    904                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    905                                             25000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    906                   i++;
    907               }
    908           }
    909       }
    910       /* next check gen2 version */
    911       if ((model_num == TSCBH_GEN2) && AN_X4_LD_UP1_ABIL_1_GEN2r_MSA_LFRf_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    912           /* first check 50G 1 lane */
    913           if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_KR4_CR4_MSA_LF1f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    914               PHYMOD_IF_ERR_RETURN(
    915                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    916                                         50000, 1, phymod_fec_RS272, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    917               i++;
    918           }
    919           /* next check 100G 2 lane */
    920           if (AN_X4_LD_UP1_ABIL_0_GEN2r_SPEED_SPARE_22_MSA_LF2f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    921               PHYMOD_IF_ERR_RETURN(
    922                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    923                                         100000, 2, phymod_fec_RS272, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    924               i++;
    925           }
    926           /* first check 200G 4 lane */
    927           if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_FEC_528_KR2_CR2_LF3f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    928               PHYMOD_IF_ERR_RETURN(
    929                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    930                                         200000, 4, phymod_fec_RS272_2XN, pause, phymod_channel_long, phymod_AN_MODE_MSA));
    931               i++;
    932           }
    933       }
    934 
    935   } else {
    936       /* UP page is BAM page */
    937       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_200G_BRCM_KR4_CR4f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    938           PHYMOD_IF_ERR_RETURN(
    939               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    940                                     200000, 4, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    941           i++;
    942       }
    943       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_200G_BRCM_NO_FEC_KR4_CR4f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    944           PHYMOD_IF_ERR_RETURN(
    945              _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    946                                    200000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    947          i++;
    948       }
    949       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_FEC_528_KR2_CR2_LF3f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    950           PHYMOD_IF_ERR_RETURN(
    951              _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    952                                    100000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    953           i++;
    954       }
    955       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_NO_FEC_KR2_CR2f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    956           PHYMOD_IF_ERR_RETURN(
    957               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    958                                     100000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    959           i++;
    960       }
    961       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_KR4_CR4_MSA_LF1f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    962           PHYMOD_IF_ERR_RETURN(
    963               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    964                                     100000, 4, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    965           i++;
    966       }
    967       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_100G_BRCM_NO_FEC_X4f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
    968           PHYMOD_IF_ERR_RETURN(
    969               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    970                                     100000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    971           i++;
    972       }
    973       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_FEC_528_CR1_KR1f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    974           PHYMOD_IF_ERR_RETURN(
    975               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    976                                     50000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    977           i++;
    978       }
    979       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_NO_FEC_CR1_KR1f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    980           PHYMOD_IF_ERR_RETURN(
    981              _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    982                                     50000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    983           i++;
    984       }
    985       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_BRCM_FEC_544_CR2_KR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    986           PHYMOD_IF_ERR_RETURN(
    987              _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    988                                     50000, 2, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    989           i++;
    990       }
    991       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_CR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)
    992           || AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_50G_KR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
    993           if (!(fec_cl74 == 0x3 || fec_cl91 == 0x3)) {
    994               PHYMOD_IF_ERR_RETURN(
    995                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
    996                                         50000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
    997               i++;
    998           } else {
    999               if (fec_cl74 == 0x3) {
   1000                   PHYMOD_IF_ERR_RETURN(
   1001                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1002                                             50000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1003                   i++;
   1004               }
   1005               if (fec_cl91 == 0x3) {
   1006                   PHYMOD_IF_ERR_RETURN(
   1007                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1008                                             50000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1009                   i++;
   1010               }
   1011           }
   1012       }
   1013       if (AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_40G_CR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)
   1014           || AN_X4_LD_UP1_ABIL_0_GEN2r_BAM_40G_KR2f_GET(AN_X4_LD_UP1_ABIL0r_reg)) {
   1015           if (fec_cl74 == 0x3) {
   1016               PHYMOD_IF_ERR_RETURN(
   1017                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1018                                         40000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1019           } else {
   1020               PHYMOD_IF_ERR_RETURN(
   1021                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1022                                         40000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1023           }
   1024           i++;
   1025       }
   1026       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_CR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)
   1027           || AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_25G_KR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
   1028           if (!(fec_cl74 == 0x3 || fec_cl91 == 0x3)) {
   1029               PHYMOD_IF_ERR_RETURN(
   1030                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1031                                         25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1032               i++;
   1033           } else {
   1034               if (fec_cl74 == 0x3) {
   1035                   PHYMOD_IF_ERR_RETURN(
   1036                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1037                                             25000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1038                   i++;
   1039               }
   1040               if (fec_cl91 == 0x3) {
   1041                   PHYMOD_IF_ERR_RETURN(
   1042                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1043                                             25000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1044                   i++;
   1045               }
   1046           }
   1047       }
   1048       if (AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_20G_CR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)
   1049           || AN_X4_LD_UP1_ABIL_1_GEN2r_BAM_20G_KR1f_GET(AN_X4_LD_UP1_ABIL1r_reg)) {
   1050           if (fec_cl74 == 0x3) {
   1051               PHYMOD_IF_ERR_RETURN(
   1052                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1053                                         20000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1054           } else {
   1055               PHYMOD_IF_ERR_RETURN(
   1056                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1057                                         20000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1058           }
   1059           i++;
   1060       }
   1061   }
   1062 
   1063   autoneg_abilities->num_abilities = i;
   1064 
   1065   return PHYMOD_E_NONE;
   1066 }
   1067 
   1068 
   1069 
   1070 /*!
   1071 @brief Enable/disable AN
   1072 @param pc handle to current TSCBH context ($tbhmod_st)
   1073 @returns PHYMOD_E_NONE if no errors. PHYMOD_E_ERROR else.
   1074 @details
   1075 This function programs auto-negotiation (AN) modes for the TEF. It can
   1076 enable/disable clause37/clause73/BAM autonegotiation capabilities. Call this
   1077 function once for combo mode and once per lane in independent lane mode.
   1078 The autonegotiation mode is indicated by setting an_control as required.
   1079 */
   1080 int tbhmod_autoneg_control(PHYMOD_ST* pc, tbhmod_an_control_t *an_control)
   1081 {
   1082   phymod_access_t pa_copy;
   1083   uint16_t num_advertised_lanes;
   1084   int start_lane, num_of_lane;
   1085   uint16_t cl73_enable, cl73_bam_enable;
   1086   uint16_t cl73_next_page;
   1087   uint16_t cl73_restart;
   1088   uint16_t cl73_bam_code;
   1089   uint16_t msa_overrides;
   1090   uint32_t oui;
   1091   AN_X4_CL73_CFGr_t      AN_X4_CL73_CFGr_reg;
   1092   AN_X4_LD_BASE_ABIL1r_t AN_X4_LD_BASE_ABIL1r_reg;
   1093   AN_X4_LD_BAM_ABILr_t   AN_X4_ABILITIES_LD_BAM_ABILITIESr_reg;
   1094   AN_X1_OUI_UPRr_t       AN_X1_OUI_UPRr_reg;
   1095   AN_X1_OUI_LWRr_t       AN_X1_OUI_LWRr_reg;
   1096 
   1097   PHYMOD_IF_ERR_RETURN
   1098       (phymod_util_lane_config_get(pc, &start_lane, &num_of_lane));
   1099   PHYMOD_MEMCPY(&pa_copy, pc, sizeof(pa_copy));
   1100 
   1101   TBHMOD_DBG_IN_FUNC_INFO(pc);
   1102   num_advertised_lanes          = an_control->num_lane_adv;
   1103   cl73_bam_code                 = 0x0;
   1104   cl73_bam_enable               = 0x0;
   1105   cl73_enable                   = 0x0;
   1106   cl73_next_page                = 0x0;
   1107   cl73_restart                  = 0x0;
   1108   msa_overrides                 = 0x0;
   1109   oui                           = 0x0;
   1110 
   1111   switch (an_control->an_type) {
   1112     case TBHMOD_AN_MODE_CL73:
   1113       cl73_restart                = an_control->enable;
   1114       cl73_enable                 = an_control->enable;
   1115       break;
   1116     case TBHMOD_AN_MODE_CL73_BAM:
   1117       cl73_restart                = an_control->enable;
   1118       cl73_enable                 = an_control->enable;
   1119       cl73_bam_enable             = an_control->enable;
   1120       cl73_bam_code               = 0x3;
   1121       cl73_next_page              = 0x1;
   1122       break;
   1123     case TBHMOD_AN_MODE_CL73_MSA:
   1124       cl73_restart                = an_control->enable;
   1125       cl73_enable                 = an_control->enable;
   1126       cl73_bam_enable             = an_control->enable;
   1127       cl73_bam_code               = 0x3;
   1128       cl73_next_page              = 0x1;
   1129       msa_overrides               = 0x1;
   1130       oui                         = MSA_OUI;
   1131       break;
   1132     default:
   1133       return PHYMOD_E_FAIL;
   1134       break;
   1135   }
   1136 
   1137   /*need to set cl73 BAM next page 0xc1c4 probably*/
   1138   AN_X4_LD_BASE_ABIL1r_CLR(AN_X4_LD_BASE_ABIL1r_reg);
   1139   AN_X4_LD_BASE_ABIL1r_NEXT_PAGEf_SET(AN_X4_LD_BASE_ABIL1r_reg, cl73_next_page & 1);
   1140   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_LD_BASE_ABIL1r(pc, AN_X4_LD_BASE_ABIL1r_reg));
   1141 
   1142   /* Writing bam_code 0xc1c5*/
   1143   AN_X4_LD_BAM_ABILr_CLR(AN_X4_ABILITIES_LD_BAM_ABILITIESr_reg);
   1144   AN_X4_LD_BAM_ABILr_CL73_BAM_CODEf_SET(AN_X4_ABILITIES_LD_BAM_ABILITIESr_reg, cl73_bam_code);
   1145   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_BAM_ABILr(pc, AN_X4_ABILITIES_LD_BAM_ABILITIESr_reg));
   1146 
   1147   /* Set OUI */
   1148   if (an_control->an_type != TBHMOD_AN_MODE_CL73) {
   1149     AN_X1_OUI_UPRr_CLR(AN_X1_OUI_UPRr_reg);
   1150     AN_X1_OUI_UPRr_SET(AN_X1_OUI_UPRr_reg, (oui >> 16) & 0xff);
   1151     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_OUI_UPRr(pc, AN_X1_OUI_UPRr_reg));
   1152 
   1153     AN_X1_OUI_LWRr_CLR(AN_X1_OUI_LWRr_reg);
   1154     AN_X1_OUI_LWRr_SET(AN_X1_OUI_LWRr_reg, oui & 0xffff);
   1155     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_OUI_LWRr(pc, AN_X1_OUI_LWRr_reg));
   1156   }
   1157   /* Clear AN enable bit in 0xc1c0 */
   1158   AN_X4_CL73_CFGr_CLR(AN_X4_CL73_CFGr_reg);
   1159   AN_X4_CL73_CFGr_CL73_ENABLEf_SET(AN_X4_CL73_CFGr_reg,0);
   1160   AN_X4_CL73_CFGr_CL73_AN_RESTARTf_SET(AN_X4_CL73_CFGr_reg,0);
   1161   PHYMOD_IF_ERR_RETURN (MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_CL73_CFGr_reg));
   1162 
   1163   /*Setting X4 abilities*/
   1164   AN_X4_CL73_CFGr_CLR(AN_X4_CL73_CFGr_reg);
   1165   AN_X4_CL73_CFGr_CL73_BAM_ENABLEf_SET(AN_X4_CL73_CFGr_reg,cl73_bam_enable);
   1166   AN_X4_CL73_CFGr_CL73_ENABLEf_SET(AN_X4_CL73_CFGr_reg,cl73_enable);
   1167   AN_X4_CL73_CFGr_CL73_AN_RESTARTf_SET(AN_X4_CL73_CFGr_reg,cl73_restart);
   1168   AN_X4_CL73_CFGr_NUM_ADVERTISED_LANESf_SET(AN_X4_CL73_CFGr_reg,num_advertised_lanes);
   1169   AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_CL73_CFGr_reg, msa_overrides);
   1170   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_CL73_CFGr_reg));
   1171 
   1172  /* if an is enabled, the restart bit needs to be cleared */
   1173  if (an_control->enable) {
   1174       AN_X4_CL73_CFGr_CLR(AN_X4_CL73_CFGr_reg);
   1175       AN_X4_CL73_CFGr_CL73_AN_RESTARTf_SET(AN_X4_CL73_CFGr_reg,0);
   1176       PHYMOD_IF_ERR_RETURN (MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_CL73_CFGr_reg));
   1177  }
   1178 
   1179   return PHYMOD_E_NONE;
   1180 }
   1181 
   1182 /*
   1183   @brief   To get autoneg control registers.
   1184   @param   pc handle to current TBHMOD context (#PHYMOD_ST)
   1185   @param   an_control reference to struct with autoneg parms #tefmod16_an_control_t
   1186   @param   an_complete status of AN completion
   1187   @returns PHYMOD_E_NONE if no errors. PHYMOD_E_FAIL else.
   1188   @details Upper layer software calls this function to get autoneg
   1189            info.
   1190 
   1191              <B>How to call:</B><br>
   1192              <p>Call directly </p>
   1193  */
   1194 int tbhmod_autoneg_control_get(PHYMOD_ST* pc, tbhmod_an_control_t *an_control, int *an_complete)
   1195 {
   1196   AN_X4_CL73_CFGr_t      AN_X4_CL73_CFGr_reg;
   1197   AN_X4_AN_MISC_STSr_t   AN_X4_AN_MISC_STSr_reg;
   1198   AN_X4_LD_BASE_ABIL1r_t AN_X4_LD_BASE_ABIL1r_reg;
   1199   AN_X4_LD_BASE_ABIL2r_t AN_X4_LD_BASE_ABIL2r_reg;
   1200   AN_X4_LD_BASE_ABIL3r_t AN_X4_LD_BASE_ABIL3r_reg;
   1201   uint32_t   base_ability1, base_ability2, base_ability3;
   1202 
   1203   TBHMOD_DBG_IN_FUNC_INFO(pc);
   1204 
   1205   /* CL73 AN CONFIG 0xC1C0 */
   1206   PHYMOD_IF_ERR_RETURN(READ_AN_X4_CL73_CFGr(pc, &AN_X4_CL73_CFGr_reg));
   1207   if (AN_X4_CL73_CFGr_CL73_BAM_ENABLEf_GET(AN_X4_CL73_CFGr_reg) == 1) {
   1208     if (AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_GET(AN_X4_CL73_CFGr_reg) == 1) {
   1209         PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL1r(pc, &AN_X4_LD_BASE_ABIL1r_reg));
   1210         PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL2r(pc, &AN_X4_LD_BASE_ABIL2r_reg));
   1211         PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_BASE_ABIL3r(pc, &AN_X4_LD_BASE_ABIL3r_reg));
   1212         base_ability1 =  AN_X4_LD_BASE_ABIL1r_GET(AN_X4_LD_BASE_ABIL1r_reg) & 0xc01f;
   1213         base_ability2 = AN_X4_LD_BASE_ABIL2r_GET(AN_X4_LD_BASE_ABIL2r_reg) & 0x41;
   1214         base_ability3 = AN_X4_LD_BASE_ABIL3r_GET(AN_X4_LD_BASE_ABIL3r_reg) & 0x1;
   1215 
   1216         if (!(base_ability1) && !(base_ability2) && !(base_ability3)) {
   1217             an_control->an_type = TBHMOD_AN_MODE_MSA;
   1218             an_control->enable = 1;
   1219         } else {
   1220             an_control->an_type = TBHMOD_AN_MODE_CL73_MSA;
   1221             an_control->enable = 1;
   1222         }
   1223     } else {
   1224         an_control->an_type = TBHMOD_AN_MODE_CL73_BAM;
   1225         an_control->enable = 1;
   1226     }
   1227   } else if (AN_X4_CL73_CFGr_CL73_ENABLEf_GET(AN_X4_CL73_CFGr_reg) == 1) {
   1228      an_control->an_type = TBHMOD_AN_MODE_CL73;
   1229      an_control->enable = 1;
   1230   } else {
   1231      an_control->an_type = TBHMOD_AN_MODE_NONE;
   1232      an_control->enable = 0;
   1233   }
   1234 
   1235   an_control->num_lane_adv = AN_X4_CL73_CFGr_NUM_ADVERTISED_LANESf_GET(AN_X4_CL73_CFGr_reg);
   1236 
   1237   /* an_complete status 0xC1E9 */
   1238   AN_X4_AN_MISC_STSr_CLR(AN_X4_AN_MISC_STSr_reg);
   1239   PHYMOD_IF_ERR_RETURN (READ_AN_X4_AN_MISC_STSr(pc, &AN_X4_AN_MISC_STSr_reg));
   1240   *an_complete = AN_X4_AN_MISC_STSr_AN_COMPLETEf_GET(AN_X4_AN_MISC_STSr_reg);
   1241 
   1242   return PHYMOD_E_NONE;
   1243 }
   1244 
   1245 int tbhmod_autoneg_status_get(PHYMOD_ST* pc, int *an_en, int *an_done)
   1246 {
   1247   AN_X4_CL73_CFGr_t  AN_X4_CL73_CFGr_reg;
   1248   AN_X4_AN_MISC_STSr_t  AN_X4_AN_MISC_STSr_reg;
   1249 
   1250   AN_X4_CL73_CFGr_CLR(AN_X4_CL73_CFGr_reg);
   1251   AN_X4_AN_MISC_STSr_CLR(AN_X4_AN_MISC_STSr_reg);
   1252 
   1253   PHYMOD_IF_ERR_RETURN(READ_AN_X4_CL73_CFGr(pc, &AN_X4_CL73_CFGr_reg));
   1254   PHYMOD_IF_ERR_RETURN(READ_AN_X4_AN_MISC_STSr(pc, &AN_X4_AN_MISC_STSr_reg));
   1255 
   1256   *an_en = AN_X4_CL73_CFGr_CL73_ENABLEf_GET(AN_X4_CL73_CFGr_reg);
   1257   *an_done = AN_X4_AN_MISC_STSr_AN_COMPLETEf_GET(AN_X4_AN_MISC_STSr_reg);
   1258 
   1259   return PHYMOD_E_NONE;
   1260 }
   1261 
   1262 int tbhmod_autoneg_fec_status_get(PHYMOD_ST* pc, uint8_t *fec_status)
   1263 {
   1264   AN_X4_AN_ABIL_RESOLUTION_STSr_t an_fec_status_reg;
   1265 
   1266   AN_X4_AN_ABIL_RESOLUTION_STSr_CLR(an_fec_status_reg);
   1267 
   1268   PHYMOD_IF_ERR_RETURN(READ_AN_X4_AN_ABIL_RESOLUTION_STSr(pc, &an_fec_status_reg));
   1269   *fec_status = AN_X4_AN_ABIL_RESOLUTION_STSr_AN_HCD_FEC_ARCHf_GET(an_fec_status_reg);
   1270 
   1271   return PHYMOD_E_NONE;
   1272 }
   1273 
   1274 
   1275 int tbhmod_autoneg_remote_ability_get(PHYMOD_ST* pc, phymod_autoneg_advert_abilities_t *autoneg_abilities)
   1276 {
   1277   AN_X4_LP_BASE1r_t   AN_X4_LP_BASE1r_reg;
   1278   AN_X4_LP_BASE2r_t   AN_X4_LP_BASE2r_reg;
   1279   AN_X4_LP_BASE3r_t   AN_X4_LP_BASE3r_reg;
   1280   AN_X4_LP_MP5_LWRr_t  AN_X4_LP_MP5_LWRr_reg;
   1281   AN_X4_LP_MP5_MIDDLEr_t AN_X4_LP_MP5_MIDDLEr_reg;
   1282   AN_X4_LP_MP5_UPRr_t AN_X4_LP_MP5_UPRr_reg;
   1283   AN_X4_LP_UP_LWRr_t AN_X4_LP_UP_LWRr_reg;
   1284   AN_X4_LP_UP_MIDDLEr_t AN_X4_LP_UP_MIDDLEr_reg;
   1285   AN_X4_LP_UP_UPRr_t AN_X4_LP_UP_UPRr_reg;
   1286   uint32_t base_0, base_1, base_2;
   1287   uint32_t mp5_1, mp5_2;
   1288   uint32_t up1_0, up1_1, up1_2;
   1289   uint32_t msa_code_13_23 = 0, msa_code_2_12 = 0, msa_code_0_1 = 0;
   1290   uint32_t bam_code = 0, i = 0;
   1291   uint32_t pause, fec_cl74, fec_cl91;
   1292 
   1293   AN_X4_LP_BASE1r_CLR(AN_X4_LP_BASE1r_reg);
   1294   AN_X4_LP_BASE2r_CLR(AN_X4_LP_BASE2r_reg);
   1295   AN_X4_LP_BASE3r_CLR(AN_X4_LP_BASE3r_reg);
   1296   AN_X4_LP_MP5_LWRr_CLR(AN_X4_LP_MP5_LWRr_reg);
   1297   AN_X4_LP_MP5_MIDDLEr_CLR(AN_X4_LP_MP5_MIDDLEr_reg);
   1298   AN_X4_LP_MP5_UPRr_CLR(AN_X4_LP_MP5_UPRr_reg);
   1299   AN_X4_LP_UP_LWRr_CLR(AN_X4_LP_UP_LWRr_reg);
   1300   AN_X4_LP_UP_MIDDLEr_CLR(AN_X4_LP_UP_MIDDLEr_reg);
   1301   AN_X4_LP_UP_UPRr_CLR(AN_X4_LP_UP_UPRr_reg);
   1302 
   1303   /**** 0xC1D3 ****/
   1304   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_BASE1r(pc,  &AN_X4_LP_BASE1r_reg));
   1305   /**** 0xC1D4 ****/
   1306   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_BASE2r(pc,  &AN_X4_LP_BASE2r_reg));
   1307   /**** 0xC1D5 ****/
   1308   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_BASE3r(pc,  &AN_X4_LP_BASE3r_reg));
   1309   /**** 0xC1D6 ****/
   1310   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_MP5_LWRr(pc, &AN_X4_LP_MP5_LWRr_reg));
   1311   /**** 0xC1D7 ****/
   1312   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_MP5_MIDDLEr(pc, &AN_X4_LP_MP5_MIDDLEr_reg));
   1313   /**** 0xC1D8 ****/
   1314   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_MP5_UPRr(pc, &AN_X4_LP_MP5_UPRr_reg));
   1315   /**** 0xC1D9 ****/
   1316   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_UP_LWRr(pc, &AN_X4_LP_UP_LWRr_reg));
   1317   /**** 0xC1DA ****/
   1318   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_UP_MIDDLEr(pc, &AN_X4_LP_UP_MIDDLEr_reg));
   1319   /**** 0xC1DB ****/
   1320   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_UP_UPRr(pc, &AN_X4_LP_UP_UPRr_reg));
   1321 
   1322   base_0 = AN_X4_LP_BASE1r_GET(AN_X4_LP_BASE1r_reg);
   1323   base_1 = AN_X4_LP_BASE2r_GET(AN_X4_LP_BASE2r_reg);
   1324   base_2 = AN_X4_LP_BASE3r_GET(AN_X4_LP_BASE3r_reg);
   1325   mp5_1  = AN_X4_LP_MP5_MIDDLEr_GET(AN_X4_LP_MP5_MIDDLEr_reg);
   1326   mp5_2  = AN_X4_LP_MP5_UPRr_GET(AN_X4_LP_MP5_UPRr_reg);
   1327   up1_0  = AN_X4_LP_UP_LWRr_GET(AN_X4_LP_UP_LWRr_reg);
   1328   up1_1  = AN_X4_LP_UP_MIDDLEr_GET(AN_X4_LP_UP_MIDDLEr_reg);
   1329   up1_2  = AN_X4_LP_UP_UPRr_GET(AN_X4_LP_UP_UPRr_reg);
   1330 
   1331   /* Get Pause Ability */
   1332   pause = (base_0 >> AN_BASE0_PAGE_PAUSE_OFFSET) & AN_BASE0_PAGE_PAUSE_MASK;
   1333   fec_cl74 = (base_2 >> AN_BASE2_CL74_ABILITY_REQ_SUP_OFFSET) & AN_BASE2_CL74_ABILITY_REQ_SUP_MASK;
   1334 
   1335   /* Get Base Abilities */
   1336   if ((base_2 >> AN_BASE2_TECH_ABILITY_200G_KR4_CR4_OFFSET) & AN_BASE2_TECH_ABILITY_200G_KR4_CR4_MASK) {
   1337       PHYMOD_IF_ERR_RETURN(
   1338           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1339                                 200000, 4, phymod_fec_RS544_2XN, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1340      i++;
   1341   }
   1342   if ((base_2 >> AN_BASE2_TECH_ABILITY_100G_KR2_CR2_OFFSET) & AN_BASE2_TECH_ABILITY_100G_KR2_CR2_MASK) {
   1343       PHYMOD_IF_ERR_RETURN(
   1344           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1345                                 100000, 2, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1346       i++;
   1347   }
   1348   if (((base_1 >> AN_BASE1_TECH_ABILITY_100G_KR4_OFFSET) & AN_BASE1_TECH_ABILITY_100G_KR4_MASK)
   1349       || ((base_1 >> AN_BASE1_TECH_ABILITY_100G_CR4_OFFSET) & AN_BASE1_TECH_ABILITY_100G_CR4_MASK)) {
   1350       PHYMOD_IF_ERR_RETURN(
   1351           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1352                                 100000, 4, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1353       if ((base_1 >> AN_BASE1_TECH_ABILITY_100G_CR4_OFFSET) & AN_BASE1_TECH_ABILITY_100G_CR4_MASK) {
   1354           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1355       }
   1356       i++;
   1357   }
   1358   if ((base_2 >> AN_BASE2_TECH_ABILITY_50G_KR1_CR1_OFFSET) & AN_BASE2_TECH_ABILITY_50G_KR1_CR1_MASK) {
   1359       PHYMOD_IF_ERR_RETURN(
   1360           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1361                                 50000, 1, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1362       i++;
   1363   }
   1364   if (((base_1 >> AN_BASE1_TECH_ABILITY_40G_KR4_OFFSET) & AN_BASE1_TECH_ABILITY_40G_KR4_MASK)
   1365       || ((base_1 >> AN_BASE1_TECH_ABILITY_40G_CR4_OFFSET) & AN_BASE1_TECH_ABILITY_40G_CR4_MASK)) {
   1366       if (fec_cl74 == 0x3) {
   1367           PHYMOD_IF_ERR_RETURN(
   1368               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1369                                    40000, 4, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1370       } else {
   1371           PHYMOD_IF_ERR_RETURN(
   1372               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1373                                    40000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1374       }
   1375       if ((base_1 >> AN_BASE1_TECH_ABILITY_40G_CR4_OFFSET) & AN_BASE1_TECH_ABILITY_40G_CR4_MASK) {
   1376           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1377       }
   1378       i++;
   1379   }
   1380   fec_cl74 = (base_2 >> AN_BASE2_25G_BASE_R_FEC_ABILITY_REQ_OFFSET) & AN_BASE2_25G_BASE_R_FEC_ABILITY_REQ_MASK;
   1381   fec_cl91 = (base_2 >> AN_BASE2_25G_RS_FEC_ABILITY_REQ_OFFSET) & AN_BASE2_25G_RS_FEC_ABILITY_REQ_MASK;
   1382   if ((base_1 >> AN_BASE1_TECH_ABILITY_25G_KR1_CR1_OFFSET) & AN_BASE1_TECH_ABILITY_25G_KR1_CR1_MASK) {
   1383       if (fec_cl74 || fec_cl91) {
   1384           if (fec_cl74) {
   1385               PHYMOD_IF_ERR_RETURN(
   1386                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1387                                         25000, 1, phymod_fec_CL74, pause, 1, phymod_AN_MODE_CL73));
   1388               i++;
   1389           }
   1390           if (fec_cl91) {
   1391               PHYMOD_IF_ERR_RETURN(
   1392                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1393                                         25000, 1, phymod_fec_CL91, pause, 1, phymod_AN_MODE_CL73));
   1394               i++;
   1395           }
   1396       } else {
   1397           PHYMOD_IF_ERR_RETURN(
   1398               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1399                                     25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1400           i++;
   1401       }
   1402   }
   1403   if ((base_1 >> AN_BASE1_TECH_ABILITY_25G_KRS1_CRS1_OFFSET) & AN_BASE1_TECH_ABILITY_25G_KRS1_CRS1_MASK) {
   1404       if (fec_cl74) {
   1405           PHYMOD_IF_ERR_RETURN(
   1406               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1407                                     25000, 1, phymod_fec_CL74, pause, 1, phymod_AN_MODE_CL73));
   1408       } else {
   1409           PHYMOD_IF_ERR_RETURN(
   1410               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1411                                     25000, 1, phymod_fec_None, pause, 1, phymod_AN_MODE_CL73));
   1412       }
   1413       i++;
   1414   }
   1415   fec_cl74 = (base_2 >> AN_BASE2_CL74_ABILITY_REQ_SUP_OFFSET) & AN_BASE2_CL74_ABILITY_REQ_SUP_MASK;
   1416   if ((base_1 >> AN_BASE1_TECH_ABILITY_10G_KR1_OFFSET) & AN_BASE1_TECH_ABILITY_10G_KR1_MASK) {
   1417       if (fec_cl74 == 0x3) {
   1418           PHYMOD_IF_ERR_RETURN(
   1419               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1420                                    10000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1421       } else {
   1422           PHYMOD_IF_ERR_RETURN(
   1423               _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1424                                    10000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73));
   1425       }
   1426       i++;
   1427   }
   1428 
   1429   /* Check if Next_Page bit is set in base page, if yes, need to check MSA/BAM abilities */
   1430   if ((base_0 >> AN_BASE0_PAGE_NP_OFFSET) & AN_BASE0_PAGE_NP_MASK) {
   1431       msa_code_13_23 = (mp5_1 >> AN_MSG_PAGE1_OUI_13to23_OFFSET) & AN_MSG_PAGE1_OUI_13to23_MASK;
   1432       msa_code_2_12 = (mp5_2 >> AN_MSG_PAGE2_OUI_2to12_OFFSET) & AN_MSG_PAGE2_OUI_2to12_MASK;
   1433       msa_code_0_1 = (up1_0 >> AN_UF_PAGE0_OUI_OFFSET) & AN_UF_PAGE0_OUI_MASK;
   1434       bam_code = (up1_0 >> AN_UF_PAGE0_UD_0to8_OFFSET) & AN_UF_PAGE0_UD_0to8_MASK;
   1435 
   1436       if ((msa_code_13_23 == MSA_OUI_13to23) && (msa_code_2_12 == MSA_OUI_2to12) && (msa_code_0_1 == MSA_OUI_0to1)) {
   1437           /* UF page is MSA page */
   1438           fec_cl74 = (up1_2 >> AN_UF_PAGE2_MSA_CL74_REQ_OFFSET) & AN_UF_PAGE2_MSA_CL74_REQ_MASK;
   1439           fec_cl91 = (up1_2 >> AN_UF_PAGE2_MSA_CL91_REQ_OFFSET) & AN_UF_PAGE2_MSA_CL91_REQ_MASK;
   1440           if (((up1_1 >> AN_UF_PAGE1_MSA_50G_CR2_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_50G_CR2_ABILITY_MASK)
   1441               || ((up1_1 >> AN_UF_PAGE1_MSA_50G_KR2_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_50G_KR2_ABILITY_MASK)) {
   1442               if (fec_cl74 || fec_cl91) {
   1443                   if(fec_cl74) {
   1444                       PHYMOD_IF_ERR_RETURN(
   1445                            _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1446                                                  50000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1447                       if ((up1_1 >> AN_UF_PAGE1_MSA_50G_CR2_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_50G_CR2_ABILITY_MASK) {
   1448                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1449                       }
   1450                       i++;
   1451                   }
   1452                   if (fec_cl91) {
   1453                       PHYMOD_IF_ERR_RETURN(
   1454                            _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1455                                                  50000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1456                       if ((up1_1 >> AN_UF_PAGE1_MSA_50G_CR2_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_50G_CR2_ABILITY_MASK) {
   1457                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1458                       }
   1459                       i++;
   1460                   }
   1461               } else {
   1462                   PHYMOD_IF_ERR_RETURN(
   1463                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1464                                             50000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1465                   if ((up1_1 >> AN_UF_PAGE1_MSA_50G_CR2_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_50G_CR2_ABILITY_MASK) {
   1466                       autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1467                   }
   1468                   i++;
   1469               }
   1470           }
   1471           if (((up1_1 >> AN_UF_PAGE1_MSA_25G_KR1_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_25G_KR1_ABILITY_MASK)
   1472               || ((up1_1 >> AN_UF_PAGE1_MSA_25G_CR1_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_25G_CR1_ABILITY_MASK)) {
   1473               if (fec_cl74 || fec_cl91) {
   1474                   if(fec_cl74) {
   1475                       PHYMOD_IF_ERR_RETURN(
   1476                            _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1477                                                  25000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1478                       if ((up1_1 >> AN_UF_PAGE1_MSA_25G_CR1_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_25G_CR1_ABILITY_MASK) {
   1479                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1480                       }
   1481                       i++;
   1482                   }
   1483                   if (fec_cl91) {
   1484                       PHYMOD_IF_ERR_RETURN(
   1485                            _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1486                                                  25000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1487                       if ((up1_1 >> AN_UF_PAGE1_MSA_25G_CR1_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_25G_CR1_ABILITY_MASK) {
   1488                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1489                       }
   1490                       i++;
   1491                   }
   1492               } else {
   1493                   PHYMOD_IF_ERR_RETURN(
   1494                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1495                                             25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_MSA));
   1496                   if ((up1_1 >> AN_UF_PAGE1_MSA_25G_CR1_ABILITY_OFFSET) & AN_UF_PAGE1_MSA_25G_CR1_ABILITY_MASK) {
   1497                       autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1498                   }
   1499                   i++;
   1500               }
   1501           }
   1502       } else if (bam_code == BRCM_BAM_CODE) {
   1503           /* UF page is BAM page */
   1504           fec_cl74 = (up1_2 >> AN_UF_PAGE2_BAM_CL74_REQ_OFFSET) & AN_UF_PAGE2_BAM_CL74_REQ_MASK;
   1505           fec_cl91 = (up1_2 >> AN_UF_PAGE2_BAM_CL91_REQ_OFFSET) & AN_UF_PAGE2_BAM_CL91_REQ_MASK;
   1506           if ((up1_2 >> AN_UF_PAGE2_BAM_200G_BRCM_KR4_CR4_OFFSET) & AN_UF_PAGE2_BAM_200G_BRCM_KR4_CR4_MASK) {
   1507               PHYMOD_IF_ERR_RETURN(
   1508                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1509                                         200000, 4, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1510               i++;
   1511           }
   1512           if ((up1_2 >> AN_UF_PAGE2_BAM_200G_BRCM_NO_FEC_KR4_CR4_OFFSET) & AN_UF_PAGE2_BAM_200G_BRCM_NO_FEC_KR4_CR4_MASK) {
   1513               PHYMOD_IF_ERR_RETURN(
   1514                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1515                                         200000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1516               i++;
   1517           }
   1518           if ((up1_2 >> AN_UF_PAGE2_BAM_100G_BRCM_FEC_528_KR2_CR2_OFFSET) & AN_UF_PAGE2_BAM_100G_BRCM_FEC_528_KR2_CR2_MASK) {
   1519               PHYMOD_IF_ERR_RETURN(
   1520                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1521                                         100000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1522               i++;
   1523           }
   1524           if ((up1_2 >> AN_UF_PAGE2_BAM_100G_BRCM_NO_FEC_KR2_CR2_OFFSET) & AN_UF_PAGE2_BAM_100G_BRCM_NO_FEC_KR2_CR2_MASK) {
   1525               PHYMOD_IF_ERR_RETURN(
   1526                    _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1527                                          100000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1528               i++;
   1529           }
   1530           if ((up1_2 >> AN_UF_PAGE2_BAM_100G_BRCM_KR4_CR4_OFFSET) & AN_UF_PAGE2_BAM_100G_BRCM_KR4_CR4_MASK) {
   1531               PHYMOD_IF_ERR_RETURN(
   1532                    _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1533                                          100000, 4, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1534               i++;
   1535           }
   1536           if ((up1_2 >> AN_UF_PAGE2_BAM_100G_BRCM_NO_FEC_X4_OFFSET) & AN_UF_PAGE2_BAM_100G_BRCM_NO_FEC_X4_MASK) {
   1537               PHYMOD_IF_ERR_RETURN(
   1538                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1539                                         100000, 4, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1540               i++;
   1541           }
   1542           if ((up1_1 >> AN_UF_PAGE1_BAM_50G_BRCM_FEC_528_CR1_KR1_OFFSET) & AN_UF_PAGE1_BAM_50G_BRCM_FEC_528_CR1_KR1_MASK) {
   1543               PHYMOD_IF_ERR_RETURN(
   1544                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1545                                         50000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1546               i++;
   1547           }
   1548           if ((up1_1 >> AN_UF_PAGE1_BAM_50G_BRCM_NO_FEC_CR1_KR1_OFFSET) & AN_UF_PAGE1_BAM_50G_BRCM_NO_FEC_CR1_KR1_MASK) {
   1549               PHYMOD_IF_ERR_RETURN(
   1550                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1551                                         50000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1552               i++;
   1553           }
   1554           if ((up1_1 >> AN_UF_PAGE1_BAM_50G_BRCM_FEC_544_CR2_KR2_OFFSET) & AN_UF_PAGE1_BAM_50G_BRCM_FEC_544_CR2_KR2_MASK) {
   1555               PHYMOD_IF_ERR_RETURN(
   1556                   _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1557                                         50000, 2, phymod_fec_RS544, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1558               i++;
   1559           }
   1560           if (((up1_1 >> AN_UF_PAGE1_BAM_50G_KR2_OFFSET) & AN_UF_PAGE1_BAM_50G_KR2_MASK)
   1561               || ((up1_1 >> AN_UF_PAGE1_BAM_50G_CR2_OFFSET) & AN_UF_PAGE1_BAM_50G_CR2_MASK)) {
   1562               if (fec_cl74 || fec_cl91) {
   1563                   if (fec_cl74) {
   1564                       PHYMOD_IF_ERR_RETURN(
   1565                           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1566                                                 50000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1567                       if ((up1_1 >> AN_UF_PAGE1_BAM_50G_CR2_OFFSET) & AN_UF_PAGE1_BAM_50G_CR2_MASK) {
   1568                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1569                       }
   1570                       i++;
   1571                   }
   1572                   if (fec_cl91) {
   1573                       PHYMOD_IF_ERR_RETURN(
   1574                           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1575                                                 50000, 2, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1576                       if ((up1_1 >> AN_UF_PAGE1_BAM_50G_CR2_OFFSET) & AN_UF_PAGE1_BAM_50G_CR2_MASK) {
   1577                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1578                       }
   1579                       i++;
   1580                   }
   1581               } else {
   1582                   PHYMOD_IF_ERR_RETURN(
   1583                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1584                                             50000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1585                   if ((up1_1 >> AN_UF_PAGE1_BAM_50G_CR2_OFFSET) & AN_UF_PAGE1_BAM_50G_CR2_MASK) {
   1586                       autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1587                   }
   1588                   i++;
   1589               }
   1590           }
   1591           if (((up1_1 >> AN_UF_PAGE1_BAM_40G_KR2_OFFSET) & AN_UF_PAGE1_BAM_40G_KR2_MASK)
   1592               || ((up1_1 >> AN_UF_PAGE1_BAM_40G_CR2_OFFSET) & AN_UF_PAGE1_BAM_40G_CR2_MASK)) {
   1593               if (fec_cl74) {
   1594                   PHYMOD_IF_ERR_RETURN(
   1595                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1596                                             40000, 2, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1597               } else {
   1598                   PHYMOD_IF_ERR_RETURN(
   1599                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1600                                             40000, 2, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1601               }
   1602               if ((up1_1 >> AN_UF_PAGE1_BAM_40G_CR2_OFFSET) & AN_UF_PAGE1_BAM_40G_CR2_MASK) {
   1603                   autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1604               }
   1605               i++;
   1606           }
   1607           if (((up1_1 >> AN_UF_PAGE1_BAM_25G_KR1_OFFSET) & AN_UF_PAGE1_BAM_25G_KR1_MASK)
   1608               ||((up1_1 >> AN_UF_PAGE1_BAM_25G_CR1_OFFSET) & AN_UF_PAGE1_BAM_25G_CR1_MASK)) {
   1609               if (fec_cl74 || fec_cl91) {
   1610                   if (fec_cl74) {
   1611                       PHYMOD_IF_ERR_RETURN(
   1612                           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1613                                                 25000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1614                       if ((up1_1 >> AN_UF_PAGE1_BAM_25G_CR1_OFFSET) & AN_UF_PAGE1_BAM_25G_CR1_MASK) {
   1615                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1616                       }
   1617                       i++;
   1618                   }
   1619                   if (fec_cl91) {
   1620                       PHYMOD_IF_ERR_RETURN(
   1621                           _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1622                                                 25000, 1, phymod_fec_CL91, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1623                       if ((up1_1 >> AN_UF_PAGE1_BAM_25G_CR1_OFFSET) & AN_UF_PAGE1_BAM_25G_CR1_MASK) {
   1624                           autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1625                       }
   1626                       i++;
   1627                   }
   1628               } else {
   1629                   PHYMOD_IF_ERR_RETURN(
   1630                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1631                                             25000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1632                   if ((up1_1 >> AN_UF_PAGE1_BAM_25G_CR1_OFFSET) & AN_UF_PAGE1_BAM_25G_CR1_MASK) {
   1633                       autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1634                   }
   1635                   i++;
   1636               }
   1637           }
   1638           if (((up1_1 >> AN_UF_PAGE1_BAM_20G_KR1_OFFSET) & AN_UF_PAGE1_BAM_20G_KR1_MASK)
   1639               ||((up1_1 >> AN_UF_PAGE1_BAM_20G_CR1_OFFSET) & AN_UF_PAGE1_BAM_20G_CR1_MASK)) {
   1640               if (fec_cl74) {
   1641                   PHYMOD_IF_ERR_RETURN(
   1642                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1643                                             20000, 1, phymod_fec_CL74, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1644               } else {
   1645                   PHYMOD_IF_ERR_RETURN(
   1646                       _an_ability_construct(&(autoneg_abilities->autoneg_abilities[i]),
   1647                                             20000, 1, phymod_fec_None, pause, phymod_channel_long, phymod_AN_MODE_CL73BAM));
   1648               }
   1649               if ((up1_1 >> AN_UF_PAGE1_BAM_20G_CR1_OFFSET) & AN_UF_PAGE1_BAM_20G_CR1_MASK) {
   1650                   autoneg_abilities->autoneg_abilities[i].medium = phymodFirmwareMediaTypeCopperCable;
   1651               }
   1652               i++;
   1653           }
   1654       }
   1655   }
   1656 
   1657   autoneg_abilities->num_abilities = i;
   1658 
   1659   return PHYMOD_E_NONE;
   1660 }
   1661 
   1662 
   1663 #ifdef DV_AN_SUPPORT
   1664 
   1665 /*!
   1666 @brief To get autoneg advertisement registers.
   1667 @param  pc handle to current TSCBH context (#tbhmod_st)
   1668 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   1669 @details
   1670 */
   1671 int tbhmod_autoneg_get(tbhmod_st* pc)               /* AUTONEG_GET */
   1672 {
   1673   TBHMOD_DBG_IN_FUNC_INFO(pc);
   1674   /* TBD */
   1675   return PHYMOD_E_NONE;
   1676 }
   1677 
   1678 /*!
   1679 @brief Programs the SW AN local device pages
   1680 @param  pc handle to current TSCBH context (#tbhmod_st)
   1681 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   1682 
   1683 @details
   1684 This function programs SW AN local device pages.
   1685 per_lane_control bits [17:16] indicate
   1686 the page its trying to write, per_lane_control bits [15:0]
   1687 has the actual page contents
   1688 */
   1689 int tbhmod_sw_an_ld_page_load(PHYMOD_ST* pc, int is_base_page, int page_descriptor)
   1690 {
   1691   uint16_t page_num, page;
   1692   AN_X4_LD_PAGE0r_t  AN_X4_LD_PAGE0r_reg;
   1693   AN_X4_LD_PAGE1r_t  AN_X4_LD_PAGE1r_reg;
   1694   AN_X4_LD_PAGE2r_t  AN_X4_LD_PAGE2r_reg;
   1695 
   1696   AN_X4_SW_AN_BASE_PAGE0r_t AN_X4_SW_AN_BASE_PAGE0r_reg;
   1697   AN_X4_SW_AN_BASE_PAGE1r_t AN_X4_SW_AN_BASE_PAGE1r_reg;
   1698   AN_X4_SW_AN_BASE_PAGE2r_t AN_X4_SW_AN_BASE_PAGE2r_reg;
   1699 
   1700 
   1701   page_num = (page_descriptor>>16) & 0x3;
   1702   page     = page_descriptor & 0xffff;
   1703 
   1704   if(is_base_page) {
   1705     if(page_num == 0) {
   1706       AN_X4_SW_AN_BASE_PAGE0r_CLR(AN_X4_SW_AN_BASE_PAGE0r_reg);
   1707       AN_X4_SW_AN_BASE_PAGE0r_SET(AN_X4_SW_AN_BASE_PAGE0r_reg, page);
   1708       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_SW_AN_BASE_PAGE0r(pc, AN_X4_SW_AN_BASE_PAGE0r_reg));
   1709     }
   1710     else if(page_num == 1) {
   1711       AN_X4_SW_AN_BASE_PAGE1r_CLR(AN_X4_SW_AN_BASE_PAGE1r_reg);
   1712       AN_X4_SW_AN_BASE_PAGE1r_SET(AN_X4_SW_AN_BASE_PAGE1r_reg, page);
   1713       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_SW_AN_BASE_PAGE1r(pc, AN_X4_SW_AN_BASE_PAGE1r_reg));
   1714     }
   1715     else if(page_num == 2) {
   1716       AN_X4_SW_AN_BASE_PAGE2r_CLR(AN_X4_SW_AN_BASE_PAGE2r_reg);
   1717       AN_X4_SW_AN_BASE_PAGE2r_SET(AN_X4_SW_AN_BASE_PAGE2r_reg, page);
   1718       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_SW_AN_BASE_PAGE2r(pc, AN_X4_SW_AN_BASE_PAGE2r_reg));
   1719     }
   1720   }
   1721   else {
   1722     if(page_num == 0) {
   1723       AN_X4_LD_PAGE0r_CLR(AN_X4_LD_PAGE0r_reg);
   1724       AN_X4_LD_PAGE0r_LD_PAGE_0f_SET(AN_X4_LD_PAGE0r_reg, page);
   1725       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_PAGE0r(pc, AN_X4_LD_PAGE0r_reg));
   1726     }
   1727     else if(page_num == 1) {
   1728       AN_X4_LD_PAGE1r_CLR(AN_X4_LD_PAGE1r_reg);
   1729       AN_X4_LD_PAGE1r_LD_PAGE_1f_SET(AN_X4_LD_PAGE1r_reg, page);
   1730       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_PAGE1r(pc, AN_X4_LD_PAGE1r_reg));
   1731     }
   1732     else if(page_num == 2) {
   1733       AN_X4_LD_PAGE2r_CLR(AN_X4_LD_PAGE2r_reg);
   1734       AN_X4_LD_PAGE2r_LD_PAGE_2f_SET(AN_X4_LD_PAGE2r_reg, page);
   1735       PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_LD_PAGE2r(pc, AN_X4_LD_PAGE2r_reg));
   1736     }
   1737   }
   1738 
   1739   return PHYMOD_E_NONE;
   1740 
   1741 } /*tbhmod_sw_an_ld_page_load(tbhmod_st* pc)*/
   1742 
   1743 /*!
   1744 @brief Reads the SW AN link partner pages
   1745 @param  pc handle to current TSCBH context (#tbhmod_st)
   1746 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   1747 
   1748 @details
   1749 This function reads SW AN link partner pages. The HW
   1750 requires you to read page0 register last.
   1751 
   1752 */
   1753 int tbhmod_sw_an_lp_page_read(tbhmod_st* pc)
   1754 {
   1755   AN_X4_LP_PAGE0r_t AN_X4_LP_PAGE0r_reg;
   1756   AN_X4_LP_PAGE1r_t AN_X4_LP_PAGE1r_reg;
   1757   AN_X4_LP_PAGE2r_t AN_X4_LP_PAGE2r_reg;
   1758 
   1759   AN_X4_LP_PAGE2r_CLR(AN_X4_LP_PAGE2r_reg);
   1760   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_PAGE2r(pc, &AN_X4_LP_PAGE2r_reg));
   1761   pc->lp_page2 = AN_X4_LP_PAGE2r_LP_PAGE_2f_GET(AN_X4_LP_PAGE2r_reg);
   1762 
   1763   AN_X4_LP_PAGE1r_CLR(AN_X4_LP_PAGE1r_reg);
   1764   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_PAGE1r(pc, &AN_X4_LP_PAGE1r_reg));
   1765   pc->lp_page1 = AN_X4_LP_PAGE1r_LP_PAGE_1f_GET(AN_X4_LP_PAGE1r_reg);
   1766 
   1767   AN_X4_LP_PAGE0r_CLR(AN_X4_LP_PAGE0r_reg);
   1768   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LP_PAGE0r(pc, &AN_X4_LP_PAGE0r_reg));
   1769   pc->lp_page0 = AN_X4_LP_PAGE0r_LP_PAGE_0f_GET(AN_X4_LP_PAGE0r_reg);
   1770 
   1771 
   1772   return PHYMOD_E_NONE;
   1773 
   1774 } /*tbhmod_sw_an_lp_page_read(tbhmod_st* pc)*/
   1775 
   1776 
   1777 int tbhmod_sw_an_set_ack(PHYMOD_ST* pc)
   1778 {
   1779   AN_X4_WAIT_ACK_COMPLETEr_t AN_X4_WAIT_ACK_COMPLETEr_reg;
   1780 
   1781 
   1782 
   1783   AN_X4_WAIT_ACK_COMPLETEr_CLR(AN_X4_WAIT_ACK_COMPLETEr_reg);
   1784   AN_X4_WAIT_ACK_COMPLETEr_SEND_ACKf_SET(AN_X4_WAIT_ACK_COMPLETEr_reg, 1);
   1785   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_WAIT_ACK_COMPLETEr(pc, AN_X4_WAIT_ACK_COMPLETEr_reg));
   1786 
   1787   return PHYMOD_E_NONE;
   1788 }
   1789 
   1790 
   1791 int tbhmod_sw_an_control(PHYMOD_ST* pc, int sw_an_en)
   1792 {
   1793   AN_X4_LD_CTLr_t   AN_X4_LD_CTLr_reg;
   1794   AN_X4_CL73_CFGr_t AN_X4_ABILITIES_CL73_CFGr_reg;
   1795 
   1796 
   1797 
   1798 /** Enabling SW AN if sw_an is set **/
   1799   AN_X4_LD_CTLr_CLR(AN_X4_LD_CTLr_reg);
   1800   AN_X4_LD_CTLr_AN_TYPE_SWf_SET(AN_X4_LD_CTLr_reg, sw_an_en);
   1801   AN_X4_LD_CTLr_AN_HCD_RES_DISABLEf_SET(AN_X4_LD_CTLr_reg, 0);
   1802   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_LD_CTLr(pc, AN_X4_LD_CTLr_reg));
   1803 
   1804   AN_X4_CL73_CFGr_CLR(AN_X4_ABILITIES_CL73_CFGr_reg);
   1805   AN_X4_CL73_CFGr_CL73_ENABLEf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, sw_an_en);
   1806   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_ABILITIES_CL73_CFGr_reg));
   1807 
   1808   return PHYMOD_E_NONE;
   1809 }
   1810 
   1811 
   1812 /*!
   1813 @brief Controls the setting/resetting of autoneg ability and enabling/disabling
   1814 @param  pc handle to current TSCBH context (#tbhmod_st)
   1815 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   1816 
   1817 @details
   1818 This function programs auto-negotiation (AN) modes for the TEF. It can
   1819 enable/disable clause37/clause73/BAM autonegotiation capabilities. Call this
   1820 function once for combo mode and once per lane in independent lane mode.
   1821 
   1822 The autonegotiation mode is indicated by setting an_control as required.
   1823 */
   1824 
   1825 #ifdef _DV_TB_
   1826 int tbhmod_autoneg_control(PHYMOD_ST* pc, autoneg_control_st* an_st)
   1827 {
   1828   uint16_t cl73_bam_enable, cl73_enable;
   1829   uint16_t cl73_nonce_match_over, cl73_nonce_match_val ;
   1830   uint16_t num_advertised_lanes;
   1831   AN_X4_CL73_CFGr_t AN_X4_ABILITIES_CL73_CFGr_reg;
   1832 
   1833 
   1834 
   1835   cl73_enable                   = an_st->cl73_enable;
   1836   cl73_nonce_match_over         = an_st->nonce_match_override;
   1837   cl73_nonce_match_val          = an_st->nonce_match_val;
   1838   cl73_bam_enable               = an_st->cl73_bam_enable;
   1839 
   1840   num_advertised_lanes          = an_st->num_advertised_lanes;
   1841 
   1842 
   1843 
   1844   AN_X4_CL73_CFGr_CLR(AN_X4_ABILITIES_CL73_CFGr_reg);
   1845   AN_X4_CL73_CFGr_NUM_ADVERTISED_LANESf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, num_advertised_lanes);
   1846 
   1847   AN_X4_CL73_CFGr_CL73_NONCE_MATCH_VALf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, cl73_nonce_match_val);
   1848   AN_X4_CL73_CFGr_CL73_NONCE_MATCH_OVERf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, cl73_nonce_match_over);
   1849 
   1850   AN_X4_CL73_CFGr_CL73_ENABLEf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, cl73_enable);
   1851   AN_X4_CL73_CFGr_MSA_FEC_MAPPINGf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, an_st->an_msa_fec_mapping);
   1852   AN_X4_CL73_CFGr_CL73_BAM_ENABLEf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, cl73_bam_enable);
   1853 
   1854   /*********Setting AN_X4_ABILITIES_cl73_cfg 0xC180 ******/
   1855   PHYMOD_IF_ERR_RETURN(WRITE_AN_X4_CL73_CFGr(pc, AN_X4_ABILITIES_CL73_CFGr_reg));
   1856 
   1857   return PHYMOD_E_NONE;
   1858 
   1859 } /* tbhmod_autoneg_control(tbhmod_st* pc) */
   1860 #endif
   1861 
   1862 
   1863 
   1864 
   1865 
   1866 int tbhmod_autoneg_restart(tbhmod_st *pc)
   1867 {
   1868   AN_X4_CL73_CFGr_t AN_X4_ABILITIES_CL73_CFGr_reg;
   1869 
   1870   TBHMOD_DBG_IN_FUNC_INFO(pc);
   1871 
   1872   AN_X4_CL73_CFGr_CLR(AN_X4_ABILITIES_CL73_CFGr_reg);
   1873   AN_X4_CL73_CFGr_CL73_AN_RESTARTf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, 0);
   1874   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_ABILITIES_CL73_CFGr_reg));
   1875 
   1876   AN_X4_CL73_CFGr_CL73_AN_RESTARTf_SET(AN_X4_ABILITIES_CL73_CFGr_reg, 1);
   1877   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_CL73_CFGr(pc, AN_X4_ABILITIES_CL73_CFGr_reg));
   1878 
   1879   return PHYMOD_E_NONE;
   1880 }
   1881 
   1882 #endif /* DV_AN_SUPPORT */
   1883 
   1884 /**
   1885 @brief   getRevDetails , calls revid_read
   1886 @param   pc handle to current TSCBH context (#tbhmod_st)
   1887 @returns The value PHYMOD_E_NONE upon successful completion
   1888 @details
   1889 */
   1890 /* internal function */
   1891 int _tbhmod_getRevDetails(PHYMOD_ST* pc)
   1892 {
   1893  /* MAIN0_SERDESIDr_t MAIN0_SERDESIDr_reg;
   1894   MAIN0_SERDESIDr_CLR(MAIN0_SERDESIDr_reg);
   1895   PHYMOD_IF_ERR_RETURN(READ_MAIN0_SERDESIDr(pc, &MAIN0_SERDESIDr_reg));
   1896   if(MAIN0_SERDESIDr_GET(MAIN0_SERDESIDr_reg) != 0x42d4) {
   1897     return PHYMOD_E_FAIL;
   1898   } else {
   1899     return PHYMOD_E_NONE;
   1900   }*/
   1901  return PHYMOD_E_NONE;
   1902 }
   1903 
   1904 /*!
   1905 @brief Sets the core for autoneg
   1906 @param  pc handle to current TSCBH context (#tbhmod_st)
   1907 @returns The value PHYMOD_E_NONE upon successful completion
   1908 This function sets the tsc core for autoneg generic settings.
   1909 If per_lane_control=TBHMOD_CTL_AN_CHIP_INIT(0x1) PLL and RX path are reset.
   1910 If per_lane_control=TBHMOD_CTL_AN_MODE_INIT(0x2) PLL and RX path are not reset.
   1911 */
   1912 int tbhmod_set_an_port_mode(PHYMOD_ST* pc, int starting_lane)    /* SET_AN_PORT_MODE */
   1913 {
   1914   uint16_t new_port_mode_sel = 0;
   1915   uint16_t modify_port_mode = 0, is_octal_mode = 0;
   1916   uint16_t port_mode_sel_reg;
   1917   MAIN0_SETUPr_t MAIN0_SETUPr_reg;
   1918   PHYMOD_ST phy_copy;
   1919 
   1920   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   1921 
   1922   MAIN0_SETUPr_CLR(MAIN0_SETUPr_reg);
   1923 
   1924   PHYMOD_IF_ERR_RETURN (READ_MAIN0_SETUPr(pc, &MAIN0_SETUPr_reg));
   1925 
   1926   port_mode_sel_reg = MAIN0_SETUPr_PORT_MODE_SELf_GET(MAIN0_SETUPr_reg);
   1927 
   1928   if(port_mode_sel_reg == TBHMOD_DXGXS) {
   1929       modify_port_mode = 1;
   1930       if((starting_lane == 0) || (starting_lane == 4)) {
   1931           new_port_mode_sel = TBHMOD_TRI1_PORT;
   1932       }
   1933       else if((starting_lane == 2)  || (starting_lane == 6)) {
   1934           new_port_mode_sel = TBHMOD_TRI2_PORT;
   1935       }
   1936   }
   1937   if(port_mode_sel_reg == TBHMOD_TRI1_PORT) {
   1938       if((starting_lane == 2) || (starting_lane == 6)) {
   1939           modify_port_mode = 1;
   1940           new_port_mode_sel = TBHMOD_MULTI_PORT;
   1941       }
   1942   }
   1943   if(port_mode_sel_reg == TBHMOD_TRI2_PORT) {
   1944       if(starting_lane == 0 || (starting_lane == 4)  ) {
   1945           modify_port_mode = 1;
   1946           new_port_mode_sel = TBHMOD_MULTI_PORT;
   1947       }
   1948   }
   1949   if(port_mode_sel_reg == TBHMOD_SINGLE_PORT) {
   1950       modify_port_mode = 1;
   1951       new_port_mode_sel = TBHMOD_MULTI_PORT;
   1952   }
   1953   if(port_mode_sel_reg == TBHMOD_SINGLE_OCTAL_PORT) {
   1954       modify_port_mode = 1;
   1955       is_octal_mode = 1;
   1956       new_port_mode_sel = TBHMOD_MULTI_PORT;
   1957   }
   1958 
   1959   if (starting_lane < 4) {
   1960       phy_copy.lane_mask = 0x1;
   1961   } else {
   1962       phy_copy.lane_mask = 0x10;
   1963   }
   1964 
   1965 
   1966   if(modify_port_mode == 1) {
   1967     MAIN0_SETUPr_PORT_MODE_SELf_SET(MAIN0_SETUPr_reg, new_port_mode_sel);
   1968   }
   1969 
   1970   PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_SETUPr(&phy_copy, MAIN0_SETUPr_reg));
   1971 
   1972   if (is_octal_mode) {
   1973       phy_copy.lane_mask = 0x10;
   1974       PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_SETUPr(&phy_copy, MAIN0_SETUPr_reg));
   1975   }
   1976 
   1977   return PHYMOD_E_NONE;
   1978 }
   1979 
   1980 int tbhmod_set_an_timers(PHYMOD_ST* pc, phymod_ref_clk_t refclk, uint32_t *pam4_an_timer_value)    /* SET_AN_TIMERS */
   1981 {
   1982     AN_X1_IGNORE_LNK_TMRr_t AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg;
   1983     RX_X4_RS_FEC_TMRr_t RX_X4_RS_FEC_TMRr_reg;
   1984 
   1985     AN_X1_CL73_ERRr_t  AN_X1_CL73_ERRr_reg;
   1986     AN_X1_CL73_BRK_LNKr_t AN_X1_TIMERS_CL73_BREAK_LINKr_reg;
   1987     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg;
   1988     AN_X1_LNK_FAIL_INHBT_TMR_CL72r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg;
   1989 
   1990     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg;
   1991     AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg;
   1992     AN_X1_IGNORE_LNK_TMR_PAM4r_t AN_X1_IGNORE_LNK_TMR_PAM4r_reg;
   1993 
   1994     /* first program NRZ speed related timer value */
   1995     /*0x9250  65.04 ms */
   1996     AN_X1_CL73_BRK_LNKr_CLR(AN_X1_TIMERS_CL73_BREAK_LINKr_reg);
   1997     AN_X1_CL73_BRK_LNKr_SET(AN_X1_TIMERS_CL73_BREAK_LINKr_reg, 0x10f0);
   1998     PHYMOD_IF_ERR_RETURN (WRITE_AN_X1_CL73_BRK_LNKr(pc, AN_X1_TIMERS_CL73_BREAK_LINKr_reg));
   1999     /* 0x9251  25.02 ms */
   2000     AN_X1_CL73_ERRr_CLR(AN_X1_CL73_ERRr_reg);
   2001     AN_X1_CL73_ERRr_SET(AN_X1_CL73_ERRr_reg, 0x0);
   2002     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_CL73_ERRr(pc, AN_X1_CL73_ERRr_reg));
   2003     /* 0x9254 10.02 ms */
   2004     AN_X1_IGNORE_LNK_TMRr_CLR(AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg);
   2005     AN_X1_IGNORE_LNK_TMRr_SET(AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg, 0x29c);
   2006     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_IGNORE_LNK_TMRr(pc, AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg));
   2007     /* 0x9255 500.04 ms */
   2008     AN_X1_LNK_FAIL_INHBT_TMR_CL72r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg);
   2009     AN_X1_LNK_FAIL_INHBT_TMR_CL72r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg, 0x8236);
   2010     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg));
   2011     /* 0x9256 160.98 ms */
   2012     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg);
   2013     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg, 0x29ab);
   2014     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg));
   2015     /* 0xc130 60 ms */
   2016     RX_X4_RS_FEC_TMRr_CLR(RX_X4_RS_FEC_TMRr_reg);
   2017     RX_X4_RS_FEC_TMRr_SET(RX_X4_RS_FEC_TMRr_reg, 0xfa0);
   2018     PHYMOD_IF_ERR_RETURN(WRITE_RX_X4_RS_FEC_TMRr(pc, RX_X4_RS_FEC_TMRr_reg));
   2019 
   2020     /*next program PAM4 related timer */
   2021     if (pam4_an_timer_value == NULL) {
   2022         /*then default value */
   2023 		/* 0x9259 10.08 ms */
   2024         AN_X1_IGNORE_LNK_TMR_PAM4r_CLR(AN_X1_IGNORE_LNK_TMR_PAM4r_reg);
   2025         AN_X1_IGNORE_LNK_TMR_PAM4r_SET(AN_X1_IGNORE_LNK_TMR_PAM4r_reg, 0xa8);
   2026         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_IGNORE_LNK_TMR_PAM4r(pc, AN_X1_IGNORE_LNK_TMR_PAM4r_reg));
   2027         /*0x925a 2983.2 ms */
   2028         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg);
   2029         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg, 0xc238);
   2030         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg));
   2031         /*0x925b 1000.08 ms */
   2032         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg);
   2033         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg, 0x41aa);
   2034         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg));
   2035     } else {
   2036         /*then user passed value */
   2037         AN_X1_IGNORE_LNK_TMR_PAM4r_CLR(AN_X1_IGNORE_LNK_TMR_PAM4r_reg);
   2038         AN_X1_IGNORE_LNK_TMR_PAM4r_SET(AN_X1_IGNORE_LNK_TMR_PAM4r_reg, *pam4_an_timer_value);
   2039         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_IGNORE_LNK_TMR_PAM4r(pc, AN_X1_IGNORE_LNK_TMR_PAM4r_reg));
   2040         /*0x925a*/
   2041         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg);
   2042         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg, *(pam4_an_timer_value + 1));
   2043         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg));
   2044         /*0x925b*/
   2045         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg);
   2046         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg,  *(pam4_an_timer_value + 2));
   2047         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg));
   2048    }
   2049     return PHYMOD_E_NONE;
   2050 }
   2051 
   2052 #if 0
   2053 int tbhmod_set_an_timers(PHYMOD_ST* pc)    /* SET_AN_TIMERS */
   2054 {
   2055 #ifdef DV_AN_SUPPORT
   2056   uint16_t ignore_link_timer_period;
   2057   uint16_t tx_disable_timer_period;
   2058   uint16_t link_fail_inhibit_no_cl72_period ;
   2059   uint16_t link_fail_inhibit_cl72_period ;
   2060   uint16_t ignore_link_timer_period_pam4;
   2061   uint16_t link_fail_inhibit_no_cl72_period_pam4 ;
   2062   uint16_t link_fail_inhibit_cl72_period_pam4 ;
   2063 
   2064 
   2065   AN_X1_IGNORE_LNK_TMRr_t AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg;
   2066   AN_X1_IGNORE_LNK_TMR_PAM4r_t AN_X1_TIMERS_IGNORE_LINK_TIMER_PAM4r_reg;
   2067   MAIN0_TICK_CTL0r_t MAIN0_TICK_CONTROL_0r_reg;
   2068   MAIN0_TICK_CTL1r_t MAIN0_TICK_CONTROL_1r_reg;
   2069 
   2070   AN_X1_OUI_LWRr_t AN_X1_CONTROL_OUI_LOWERr_reg;
   2071   AN_X1_OUI_UPRr_t AN_X1_CONTROL_OUI_UPPERr_reg;
   2072   AN_X1_CL73_BRK_LNKr_t AN_X1_TIMERS_CL73_BREAK_LINKr_reg;
   2073   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg;
   2074   AN_X1_LNK_FAIL_INHBT_TMR_CL72r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg;
   2075 
   2076   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg;
   2077   AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_t AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg;
   2078 
   2079   TBHMOD_DBG_IN_FUNC_INFO(pc);
   2080 
   2081   ignore_link_timer_period         = 0xf;
   2082   link_fail_inhibit_no_cl72_period = 0x64;
   2083   link_fail_inhibit_cl72_period    = 0xfff;
   2084   ignore_link_timer_period_pam4    = ignore_link_timer_period/4 +1;
   2085   link_fail_inhibit_no_cl72_period_pam4 = link_fail_inhibit_no_cl72_period/4 +1;
   2086   link_fail_inhibit_cl72_period_pam4    = link_fail_inhibit_cl72_period/4 +1;
   2087 
   2088   pc->port_type = TBHMOD_MULTI_PORT;
   2089 
   2090   if(pc->ignore_link_timer_period !=0) ignore_link_timer_period = pc->ignore_link_timer_period;
   2091   AN_X1_IGNORE_LNK_TMRr_CLR(AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg);
   2092   AN_X1_IGNORE_LNK_TMRr_IGNORE_LINK_TIMER_PERIODf_SET(AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg, ignore_link_timer_period);
   2093   PHYMOD_IF_ERR_RETURN (MODIFY_AN_X1_IGNORE_LNK_TMRr(pc, AN_X1_TIMERS_IGNORE_LINK_TIMERr_reg));
   2094 
   2095   if(pc->ignore_link_timer_period_pam4 !=0) ignore_link_timer_period_pam4 = pc->ignore_link_timer_period_pam4;
   2096   AN_X1_IGNORE_LNK_TMR_PAM4r_CLR(AN_X1_TIMERS_IGNORE_LINK_TIMER_PAM4r_reg);
   2097   AN_X1_IGNORE_LNK_TMR_PAM4r_IGNORE_LINK_TIMER_PERIOD_PAM4f_SET(AN_X1_TIMERS_IGNORE_LINK_TIMER_PAM4r_reg, ignore_link_timer_period_pam4);
   2098   PHYMOD_IF_ERR_RETURN (MODIFY_AN_X1_IGNORE_LNK_TMR_PAM4r(pc, AN_X1_TIMERS_IGNORE_LINK_TIMER_PAM4r_reg));
   2099 
   2100 /* 9003/9004 main0_tick_control1/0 only used from mpp0 copy */
   2101   MAIN0_TICK_CTL0r_CLR(MAIN0_TICK_CONTROL_0r_reg);
   2102   MAIN0_TICK_CTL0r_TICK_DENOMINATORf_SET(MAIN0_TICK_CONTROL_0r_reg, pc->tick_denominator);
   2103   MAIN0_TICK_CTL0r_TICK_NUMERATOR_LOWERf_SET(MAIN0_TICK_CONTROL_0r_reg, pc->tick_numerator_lower);
   2104 
   2105   PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_TICK_CTL0r(pc, MAIN0_TICK_CONTROL_0r_reg));
   2106 
   2107   MAIN0_TICK_CTL1r_CLR(MAIN0_TICK_CONTROL_1r_reg);
   2108   MAIN0_TICK_CTL1r_TICK_OVERRIDEf_SET(MAIN0_TICK_CONTROL_1r_reg, pc->tick_override);
   2109   MAIN0_TICK_CTL1r_TICK_NUMERATOR_UPPERf_SET(MAIN0_TICK_CONTROL_1r_reg, pc->tick_numerator_upper);
   2110 
   2111 
   2112   PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_TICK_CTL1r(pc, MAIN0_TICK_CONTROL_1r_reg));
   2113   if(
   2114       (pc->tsc_touched_mpp0 ==0 && pc->this_lane < 4) ||
   2115       (pc->tsc_touched_mpp1 ==0 && pc->this_lane > 3 && pc->this_lane < 8)
   2116       ){
   2117     if(pc->tx_disable_timer_period !=0) tx_disable_timer_period = pc->tx_disable_timer_period;
   2118 
   2119     AN_X1_CL73_BRK_LNKr_CLR(AN_X1_TIMERS_CL73_BREAK_LINKr_reg);
   2120     AN_X1_CL73_BRK_LNKr_CL73_BREAK_TIMER_PERIODf_SET(AN_X1_TIMERS_CL73_BREAK_LINKr_reg, tx_disable_timer_period);
   2121     PHYMOD_IF_ERR_RETURN (MODIFY_AN_X1_CL73_BRK_LNKr(pc, AN_X1_TIMERS_CL73_BREAK_LINKr_reg));
   2122 
   2123     AN_X1_OUI_LWRr_CLR(AN_X1_CONTROL_OUI_LOWERr_reg);
   2124     AN_X1_OUI_LWRr_SET(AN_X1_CONTROL_OUI_LOWERr_reg, pc->oui & 0xffff);
   2125     /********Setting AN_X1_OUI_LWR 0x9241*****/
   2126     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_OUI_LWRr(pc, AN_X1_CONTROL_OUI_LOWERr_reg));
   2127 
   2128     AN_X1_OUI_UPRr_CLR(AN_X1_CONTROL_OUI_UPPERr_reg);
   2129     AN_X1_OUI_UPRr_SET(AN_X1_CONTROL_OUI_UPPERr_reg, (pc->oui >> 16) & 0xffff);
   2130     /********Setting AN_X1_OUI_UPR 0x9240*****/
   2131     PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_OUI_UPRr(pc, AN_X1_CONTROL_OUI_UPPERr_reg));
   2132   }
   2133 
   2134 
   2135   /**** 0x9256*******/
   2136   if(pc->link_fail_inhibit_no_cl72_period !=0) link_fail_inhibit_no_cl72_period = pc->link_fail_inhibit_no_cl72_period;
   2137   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg);
   2138   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_LINK_FAIL_INHIBIT_TIMER_NCL72_PERIODf_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg, link_fail_inhibit_no_cl72_period);
   2139 
   2140   PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72r_reg));
   2141 
   2142   /**** 0x9255*******/
   2143   if(pc->link_fail_inhibit_cl72_period !=0) link_fail_inhibit_cl72_period = pc->link_fail_inhibit_cl72_period;
   2144 
   2145   AN_X1_LNK_FAIL_INHBT_TMR_CL72r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg);
   2146   AN_X1_LNK_FAIL_INHBT_TMR_CL72r_LINK_FAIL_INHIBIT_TIMER_CL72_PERIODf_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg, link_fail_inhibit_cl72_period);
   2147   PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72r_reg));
   2148 
   2149 
   2150 /**** 0x925a*******/
   2151    if(pc->link_fail_inhibit_no_cl72_period_pam4 !=0) link_fail_inhibit_no_cl72_period_pam4 = pc->link_fail_inhibit_no_cl72_period_pam4;
   2152   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg);
   2153   AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_LINK_FAIL_INHIBIT_TIMER_NCL72_PERIOD_PAM4f_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg, link_fail_inhibit_no_cl72_period_pam4);
   2154 
   2155 
   2156   PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_NOT_CL72_PAM4r_reg));
   2157 
   2158   /**** 0x925b*******/
   2159    if(pc->link_fail_inhibit_cl72_period_pam4 !=0) link_fail_inhibit_cl72_period_pam4 = pc->link_fail_inhibit_cl72_period_pam4;
   2160 
   2161   AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_CLR(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg);
   2162   AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_LINK_FAIL_INHIBIT_TIMER_CL72_PERIOD_PAM4f_SET(AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg, link_fail_inhibit_cl72_period_pam4);
   2163 
   2164   PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r(pc, AN_X1_TIMERS_LINK_FAIL_INHIBIT_TIMER_CL72_PAM4r_reg));
   2165 
   2166 
   2167 #endif /* DV_AN_SUPPORT */
   2168   return PHYMOD_E_NONE;
   2169 } /* tbhmod_set_an_timers(tbhmod_st* pc) */
   2170 
   2171 #endif
   2172 
   2173 
   2174 
   2175 
   2176 #ifdef _DV_TB_
   2177 /*!
   2178 @brief Local Fault/Remote Fault signalling enable for Tx and RX
   2179 @param  pc handle to current TSCBH context (#tbhmod_st)
   2180 @returns The value PHYMOD_E_NONE upon successful completion.
   2181 @details
   2182 This function is used to enable/disable Link Interrupt, Local Fault and
   2183 Remote Fault signalling of any lane .
   2184 
   2185 \li #tbhmod_st::per_lane_control[3:0] represents the mode (CL49, CL48, CL82).
   2186 \li #tbhmod_st::per_lane_control[6]   is for li;
   2187 \li #tbhmod_st::per_lane_control[5]   is for lf;
   2188 \li #tbhmod_st::per_lane_control[4]   is for rf;
   2189 
   2190 This function reads/modifies the following registers:
   2191 
   2192 \li cl49_tx            :   0xc113
   2193 \li cl49_rx            :   0xc134
   2194 \li cl48_tx            :   0xa001
   2195 \li cl82_tx            :   0xa002
   2196 \li cl48_cl82_rx       :   0xa024
   2197 */
   2198 
   2199 int tbhmod_lf_rf_control(tbhmod_st* pc)         /* LF_RF_CONTROL */
   2200 {
   2201   TBHMOD_DBG_IN_FUNC_INFO(pc);
   2202   return PHYMOD_E_NONE;
   2203 }
   2204 #endif
   2205 
   2206 #if 0
   2207 
   2208 /**
   2209 @brief   Checks config valid status for the port
   2210 @param   pc handle to current TSCBH context (#tbhmod_st)
   2211 @returns The value PHYMOD_E_NONE upon successful completion
   2212 @details This register bit indicates that PCS is now programmed as required
   2213 by the HT entry for that speed
   2214 */
   2215 int _tbhmod_wait_sc_stats_set(tbhmod_st* pc)
   2216 {
   2217 #if defined(_DV_TB_) || defined(_SDK_TBHMOD_)
   2218   uint16_t data;
   2219   uint16_t i;
   2220   /*SC_X4_STSr_t reg_sc_ctrl_sts;
   2221 
   2222   SC_X4_STSr_CLR(reg_sc_ctrl_sts);*/
   2223   i = 0;
   2224   data = 0;
   2225 #endif /* _DV_TB_ || _SDK_TBHMOD_ */
   2226 
   2227 #ifdef _DV_TB_
   2228   while(1){
   2229    i=i+1; /* added only to eliminate compile warning */
   2230    /*PHYMOD_IF_ERR_RETURN(READ_SC_X4_STSr(pc, &reg_sc_ctrl_sts));
   2231    data = SC_X4_STSr_SW_SPEED_CONFIG_VLDf_GET(reg_sc_ctrl_sts);*/
   2232    if(data == 1)
   2233      break;
   2234   }
   2235 #endif /* _DV_TB_ */
   2236   return PHYMOD_E_NONE;
   2237 }
   2238 
   2239 #endif /* 0 */
   2240 
   2241 
   2242 
   2243 /*!
   2244 @brief tx lane reset and enable of any particular lane
   2245 @param  pc handle to current TSCBH context (#tbhmod_st)
   2246 @param  reset gets the configured tx rstb
   2247 @param  enable gets the configured tx enable
   2248 @returns The value PHYMOD_E_NONE upon successful completion.
   2249 @details
   2250 This function reads the following registers:
   2251 
   2252 \li rstb_tx_lane  :   0xc113[1]
   2253 \li enable_tx_lane:   0xc113[0]
   2254 */
   2255 int tbhmod_tx_lane_control_get(PHYMOD_ST* pc,  int *reset, int *enable)         /* TX_LANE_CONTROL */
   2256 {
   2257   TX_X4_MISCr_t TX_X4_CONTROL0_MISCr_reg;
   2258 
   2259   TX_X4_MISCr_CLR(TX_X4_CONTROL0_MISCr_reg);
   2260 
   2261   PHYMOD_IF_ERR_RETURN (READ_TX_X4_MISCr(pc, &TX_X4_CONTROL0_MISCr_reg));
   2262 
   2263   *reset = TX_X4_MISCr_RSTB_TX_LANEf_GET(TX_X4_CONTROL0_MISCr_reg);
   2264   *enable = TX_X4_MISCr_ENABLE_TX_LANEf_GET(TX_X4_CONTROL0_MISCr_reg);
   2265 
   2266    return PHYMOD_E_NONE;
   2267 }
   2268 
   2269 
   2270 /*!
   2271 @brief Read the 16 bit rev. id value etc.
   2272 @param  pc handle to current TSCBH context (#tbhmod_st)
   2273 @param  revIdV receives the revid
   2274 @returns The value of the revid.
   2275 @details
   2276 This  fucntion reads the revid register that contains core number, revision
   2277 number and returns it.
   2278 */
   2279 int tbhmod_revid_read(PHYMOD_ST* pc, uint32_t *revIdV)              /* REVID_READ */
   2280 {
   2281 #ifdef _DV_TB_
   2282   int laneselect;
   2283 #endif
   2284   TBHMOD_DBG_IN_FUNC_INFO(pc);
   2285 #ifdef _DV_TB_
   2286   laneselect = pc->lane_select;
   2287   pc->lane_select=TBHMOD_LANE_0_0_0_1;
   2288 
   2289   PHYMOD_DEBUG_ERROR(("%-22s u=%0d p=%0d sel=%x ln=%0d dxgxs=%0d\n", __func__,
   2290             pc->unit, pc->port, pc->lane_select, pc->this_lane, pc->dxgxs));
   2291 #endif
   2292   *revIdV=_tbhmod_getRevDetails(pc);
   2293 #ifdef _DV_TB_
   2294   pc->lane_select=laneselect;
   2295 #endif
   2296   return PHYMOD_E_NONE;
   2297 }
   2298 
   2299 
   2300 /* RX_X4_Fec_Control_fec_0 */
   2301 int tbhmod_cl74_control_fec_0(PHYMOD_ST* pc, int cl74_good_parity_cnt, int cl74_invalid_parity_cnt, int cl74_dec_max_pm, int cl74_burst_err_status_mode, int cl74_dbg_err_mode)
   2302 {
   2303   RX_X4_FEC0r_t     RX_X4_FEC0r_reg;
   2304 
   2305   /* TBHMOD_DBG_IN_FUNC_INFO(pc); */
   2306 
   2307   PHYMOD_DEBUG_ERROR(("%-22s CL74_CONTROL_FEC_0 Reg: cl74_good_parity_cnt=%0x cl74_invalid_parity_cnt=%0x cl74_dec_max_pm=%x cl74_burst_err_status_mode=%0x cl74_dbg_err_mode=%0x ln=%0x\n", __func__,
   2308             cl74_good_parity_cnt, cl74_invalid_parity_cnt, cl74_dec_max_pm, cl74_burst_err_status_mode, cl74_dbg_err_mode, pc->lane_mask));
   2309 
   2310 
   2311   RX_X4_FEC0r_CLR(RX_X4_FEC0r_reg);
   2312   RX_X4_FEC0r_GOOD_PARITY_CNTf_SET(RX_X4_FEC0r_reg, cl74_good_parity_cnt);
   2313   RX_X4_FEC0r_INVALID_PARITY_CNTf_SET(RX_X4_FEC0r_reg, cl74_invalid_parity_cnt);
   2314   RX_X4_FEC0r_DEC_MAX_PMf_SET(RX_X4_FEC0r_reg, cl74_dec_max_pm);
   2315   RX_X4_FEC0r_BURST_ERR_STATUS_MODEf_SET(RX_X4_FEC0r_reg, cl74_burst_err_status_mode);
   2316   RX_X4_FEC0r_DBG_ERR_MODEf_SET(RX_X4_FEC0r_reg, cl74_dbg_err_mode);
   2317   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_FEC0r(pc, RX_X4_FEC0r_reg));
   2318 
   2319   return PHYMOD_E_NONE;
   2320 }
   2321 
   2322 /* RX_X4_Fec_Control_fec_1 */
   2323 int tbhmod_cl74_control_fec_1(PHYMOD_ST* pc,int cl74_dec_pm_mode, int cl74_dec_19b_burst_gap_count, int cl74_dec_18b_burst_gap_count, int cl74_dec_17b_burst_gap_count, int cl74_dec_gap_count_mode)
   2324 {
   2325   RX_X4_FEC1r_t     RX_X4_FEC1r_reg;
   2326 
   2327 
   2328   /* TBHMOD_DBG_IN_FUNC_INFO(pc); */
   2329 
   2330   PHYMOD_DEBUG_ERROR(("%-22s CL74_CONTROL_FEC_1 Reg: cl74_dec_pm_mode=%0x cl74_dec_19b_burst_gap_count=%0x cl74_dec_18b_burst_gap_count=%x cl74_dec_17b_burst_gap_count=%0x cl74_dec_gap_count_mode=%0x ln=%0x\n", __func__,
   2331             cl74_dec_pm_mode, cl74_dec_19b_burst_gap_count, cl74_dec_18b_burst_gap_count, cl74_dec_17b_burst_gap_count, cl74_dec_gap_count_mode, pc->lane_mask));
   2332 
   2333 
   2334   RX_X4_FEC1r_CLR(RX_X4_FEC1r_reg);
   2335   RX_X4_FEC1r_DEC_PM_MODEf_SET(RX_X4_FEC1r_reg, cl74_dec_pm_mode);
   2336   RX_X4_FEC1r_DEC_19B_BURST_GAP_COUNTf_SET(RX_X4_FEC1r_reg, cl74_dec_19b_burst_gap_count);
   2337   RX_X4_FEC1r_DEC_18B_BURST_GAP_COUNTf_SET(RX_X4_FEC1r_reg, cl74_dec_18b_burst_gap_count);
   2338   RX_X4_FEC1r_DEC_17B_BURST_GAP_COUNTf_SET(RX_X4_FEC1r_reg, cl74_dec_17b_burst_gap_count);
   2339   RX_X4_FEC1r_DEC_GAP_COUNT_MODEf_SET(RX_X4_FEC1r_reg, cl74_dec_gap_count_mode);
   2340   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_FEC1r(pc, RX_X4_FEC1r_reg));
   2341 
   2342   return PHYMOD_E_NONE;
   2343 }
   2344 
   2345 /* RX_X4_Fec_Control_fec_2 */
   2346 int tbhmod_cl74_control_fec_2(PHYMOD_ST* pc, int cl74_fec_err_enable_per_stream_mpp0, int cl74_dbg_enable_per_stream_mpp0, int cl74_fec_error_code_all_per_stream_mpp0, int cl74_fec_err_enable_per_stream_mpp1, int cl74_dbg_enable_per_stream_mpp1, int cl74_fec_error_code_all_per_stream_mpp1, tbhmod_port_type_t port_type)
   2347 {
   2348 #ifdef FIXME_YZ /* mpp logic inside */
   2349   int this_lane,lane;
   2350   RX_X4_FEC2r_t     RX_X4_FEC2r_reg;
   2351 
   2352   /* TBHMOD_DBG_IN_FUNC_INFO(pc); */
   2353 
   2354   PHYMOD_DEBUG_ERROR(("%-22s CL74_CONTROL_FEC_2 Reg: cl74_fec_err_enable_per_stream_mpp0=%0x cl74_dbg_enable_per_stream_mpp0=%0x cl74_fec_error_code_all_per_stream_mpp0=%x ln=%0x, port_type = %0x\n", __func__,
   2355             cl74_fec_err_enable_per_stream_mpp0, cl74_dbg_enable_per_stream_mpp0, cl74_fec_error_code_all_per_stream_mpp0, pc.lane_mask, port_type));
   2356   PHYMOD_DEBUG_ERROR(("%-22s CL74_CONTROL_FEC_2 Reg: cl74_fec_err_enable_per_stream_mpp1=%0x cl74_dbg_enable_per_stream_mpp1=%0x cl74_fec_error_code_all_per_stream_mpp1=%x ln=%0x, port_type = %0x\n", __func__,
   2357             cl74_fec_err_enable_per_stream_mpp1, cl74_dbg_enable_per_stream_mpp1, cl74_fec_error_code_all_per_stream_mpp1, pc.lane_mask, port_type));
   2358 
   2359 
   2360   this_lane = pc.this_lane;
   2361   lane      = pc.this_lane;
   2362 
   2363   RX_X4_FEC2r_CLR(RX_X4_FEC2r_reg);
   2364   if(lane/4==0) {
   2365     RX_X4_FEC2r_FEC_ERR_ENABLEf_SET(RX_X4_FEC2r_reg,  ((cl74_fec_err_enable_per_stream_mpp0>>(lane*5))&0x1f));
   2366     RX_X4_FEC2r_DBG_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_dbg_enable_per_stream_mpp0>>(lane*5))&0x1f));
   2367     RX_X4_FEC2r_FEC_ERROR_CODE_ALLf_SET(RX_X4_FEC2r_reg, ((cl74_fec_error_code_all_per_stream_mpp0>>(lane*5))&0x1f));
   2368   }
   2369   else {
   2370     RX_X4_FEC2r_FEC_ERR_ENABLEf_SET(RX_X4_FEC2r_reg,  ((cl74_fec_err_enable_per_stream_mpp1>>((lane - 4)*5))&0x1f));
   2371     RX_X4_FEC2r_DBG_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_dbg_enable_per_stream_mpp1>>((lane - 4)*5))&0x1f));
   2372     RX_X4_FEC2r_FEC_ERROR_CODE_ALLf_SET(RX_X4_FEC2r_reg, ((cl74_fec_error_code_all_per_stream_mpp1>>((lane - 4)*5))&0x1f));
   2373   }
   2374   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_FEC2r(pc, RX_X4_FEC2r_reg));
   2375 
   2376   if(port_type == TBHMOD_SINGLE_PORT) {
   2377     do {
   2378       this_lane++;
   2379       pc.this_lane=this_lane;
   2380       if(lane/4==0) {
   2381         RX_X4_FEC2r_FEC_ERR_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_fec_err_enable_per_stream_mpp0>>(this_lane*5))&0x1f));
   2382         RX_X4_FEC2r_DBG_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_dbg_enable_per_stream_mpp0>>(this_lane*5))&0x1f));
   2383         RX_X4_FEC2r_FEC_ERROR_CODE_ALLf_SET(RX_X4_FEC2r_reg, ((cl74_fec_error_code_all_per_stream_mpp0>>(this_lane*5))&0x1f));
   2384       }
   2385       else {
   2386         RX_X4_FEC2r_FEC_ERR_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_fec_err_enable_per_stream_mpp1>>((this_lane - 4)*5))&0x1f));
   2387         RX_X4_FEC2r_DBG_ENABLEf_SET(RX_X4_FEC2r_reg, ((cl74_dbg_enable_per_stream_mpp1>>((this_lane - 4)*5))&0x1f));
   2388         RX_X4_FEC2r_FEC_ERROR_CODE_ALLf_SET(RX_X4_FEC2r_reg, ((cl74_fec_error_code_all_per_stream_mpp1>>((this_lane - 4)*5))&0x1f));
   2389       }
   2390       PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_FEC2r(pc, RX_X4_FEC2r_reg));
   2391     } while((this_lane - lane)!=3);
   2392     pc.this_lane = 0;
   2393     this_lane = 0;
   2394   }
   2395 #endif
   2396   return PHYMOD_E_NONE;
   2397 }
   2398 
   2399 /* Set FEC Bypass Error Indictator */
   2400 int tbhmod_fec_bypass_indication_set(PHYMOD_ST* pc, uint32_t rsfec_bypass_indication)
   2401 {
   2402     RX_X4_RS_FEC_RX_CTL0r_t   RX_X4_RS_FEC_RX_CTL0r_reg;
   2403 
   2404     RX_X4_RS_FEC_RX_CTL0r_CLR(RX_X4_RS_FEC_RX_CTL0r_reg);
   2405     RX_X4_RS_FEC_RX_CTL0r_CW_BAD_ENABLEf_SET(RX_X4_RS_FEC_RX_CTL0r_reg, ~rsfec_bypass_indication);
   2406     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_RS_FEC_RX_CTL0r(pc, RX_X4_RS_FEC_RX_CTL0r_reg));
   2407 
   2408     return PHYMOD_E_NONE;
   2409 }
   2410 
   2411 /* Get FEC Bypass Error Indictator */
   2412 int tbhmod_fec_bypass_indication_get(PHYMOD_ST *pc, uint32_t *rsfec_bypass_indication)
   2413 {
   2414     uint32_t val = 0;
   2415     RX_X4_RS_FEC_RX_CTL0r_t   RX_X4_RS_FEC_RX_CTL0r_reg;
   2416 
   2417     RX_X4_RS_FEC_RX_CTL0r_CLR(RX_X4_RS_FEC_RX_CTL0r_reg);
   2418     PHYMOD_IF_ERR_RETURN(READ_RX_X4_RS_FEC_RX_CTL0r(pc, &RX_X4_RS_FEC_RX_CTL0r_reg));
   2419     val = RX_X4_RS_FEC_RX_CTL0r_CW_BAD_ENABLEf_GET(RX_X4_RS_FEC_RX_CTL0r_reg);
   2420     *rsfec_bypass_indication = (~val) & 0x1;
   2421 
   2422     return PHYMOD_E_NONE;
   2423 }
   2424 
   2425 /*!
   2426 @brief disables the PCS by clearing the writing to Speed control reg
   2427 @param  pc handle to current TSCBH context (#tbhmod_st)
   2428 @returns The value PHYMOD_E_NONE upon successful completion.
   2429 @details
   2430 TBD
   2431 */
   2432 
   2433 #ifdef _DV_TB_
   2434 int tbhmod_disable_pcs_blackhawk(PHYMOD_ST* pc)
   2435 {
   2436   SC_X4_CTLr_t SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg;
   2437 
   2438   SC_X4_CTLr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg);
   2439   SC_X4_CTLr_SW_SPEED_CHANGEf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, 0);
   2440 
   2441   PHYMOD_IF_ERR_RETURN(MODIFY_SC_X4_CTLr(pc, SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2442 
   2443   return PHYMOD_E_NONE;
   2444 }
   2445 #endif /* _DV_TB_*/
   2446 
   2447 
   2448 
   2449 #ifdef _DV_TB_
   2450 /*!
   2451 @brief removes resets from all the PMD lanes
   2452 @param  pc handle to current TSCBH context (#tbhmod_st)
   2453 @returns The value PHYMOD_E_NONE upon successful completion
   2454 @details
   2455 Removes resets
   2456 */
   2457 
   2458 int tbhmod_pmd_reset_remove(PHYMOD_ST* pc, int pmd_touched)
   2459 {
   2460   PMD_X1_CTLr_t PMD_X1_PMD_X1_CONTROLr_reg;
   2461   PMD_X4_CTLr_t PMD_X4_PMD_X4_CONTROLr_reg;
   2462 
   2463 
   2464   if(pmd_touched == 0) {
   2465     PMD_X1_CTLr_CLR(PMD_X1_PMD_X1_CONTROLr_reg);
   2466     /* setup the PMD reset */
   2467     PMD_X1_CTLr_POR_H_RSTBf_SET(PMD_X1_PMD_X1_CONTROLr_reg, 1);
   2468     PMD_X1_CTLr_CORE_DP_H_RSTBf_SET(PMD_X1_PMD_X1_CONTROLr_reg, 1);
   2469 
   2470     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X1_CTLr(pc, PMD_X1_PMD_X1_CONTROLr_reg));
   2471   }
   2472 
   2473 
   2474   PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
   2475   PMD_X4_CTLr_LN_RX_H_PWRDNf_SET(PMD_X4_PMD_X4_CONTROLr_reg, 0);
   2476   PMD_X4_CTLr_LN_TX_H_PWRDNf_SET(PMD_X4_PMD_X4_CONTROLr_reg, 0);
   2477 
   2478   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
   2479 
   2480   PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
   2481   PMD_X4_CTLr_LN_H_RSTBf_SET(PMD_X4_PMD_X4_CONTROLr_reg, 1);
   2482   PMD_X4_CTLr_LN_DP_H_RSTBf_SET(PMD_X4_PMD_X4_CONTROLr_reg, 1);
   2483 
   2484   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
   2485 
   2486   return PHYMOD_E_NONE;
   2487 }
   2488 #endif
   2489 
   2490 int tbhmod_get_pcs_latched_link_status(PHYMOD_ST* pc, uint32_t *link)
   2491 {
   2492   RX_X4_PCS_LATCH_STS1r_t latched_sts ;
   2493   int                     latched_val;
   2494 
   2495   RX_X4_PCS_LATCH_STS1r_CLR(latched_sts) ;
   2496 
   2497   PHYMOD_IF_ERR_RETURN (READ_RX_X4_PCS_LATCH_STS1r(pc, &latched_sts));
   2498   latched_val = RX_X4_PCS_LATCH_STS1r_LINK_STATUS_LLf_GET(latched_sts) ;
   2499   if(latched_val) {
   2500       *link = 0 ;
   2501   } else {
   2502       *link = RX_X4_PCS_LATCH_STS1r_PCS_LINK_STATUS_LIVEf_GET(latched_sts);
   2503   }
   2504 
   2505   return PHYMOD_E_NONE;
   2506 }
   2507 
   2508 
   2509 
   2510 
   2511 /*!
   2512 @brief tbhmod_poll_for_sc_done , polls for the sc_done bit ,
   2513 @returns The value PHYMOD_E_NONE upon successful completion.
   2514 @details
   2515 Reads the SC_X4_COntrol_status reg and polls it to see if sc_done bit is set
   2516 Sets the sc_done flag=1/0, if speed control is done, after resolving to the correct speed
   2517 */
   2518 int tbhmod_poll_for_sc_done(PHYMOD_ST* pc, int mapped_speed)
   2519 {
   2520   int done;
   2521   int spd_match;
   2522   int sc_done;
   2523   int cnt;
   2524   uint16_t data;
   2525 
   2526   uint16_t sw_spd_chg_chk;
   2527 
   2528   SC_X4_STSr_t SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg;
   2529   SC_X4_RSLVD_SPDr_t SC_X4_FINAL_CONFIG_STATUS_RESOLVED_SPEEDr_reg;
   2530 
   2531   TBHMOD_DBG_IN_FUNC_INFO(pc);
   2532   done=0;
   2533   cnt=0;
   2534   sc_done = 0;
   2535   spd_match = 0;
   2536 
   2537   SC_X4_STSr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg);
   2538   while (cnt <=2000) {
   2539     PHYMOD_IF_ERR_RETURN(READ_SC_X4_STSr(pc, &SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg));
   2540     cnt = cnt + 1;
   2541          sw_spd_chg_chk = SC_X4_STSr_SW_SPEED_CHANGE_DONEf_GET(SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg);
   2542 
   2543     if(sw_spd_chg_chk) {
   2544       sc_done = 1;
   2545       break;
   2546     } else {
   2547       if(cnt == 2000) {
   2548         sc_done = 0;
   2549         break;
   2550       }
   2551     }
   2552   }
   2553 
   2554   cnt=0;
   2555   while (cnt <=400) {
   2556     SC_X4_RSLVD_SPDr_CLR(SC_X4_FINAL_CONFIG_STATUS_RESOLVED_SPEEDr_reg);
   2557     PHYMOD_IF_ERR_RETURN(READ_SC_X4_RSLVD_SPDr(pc, &SC_X4_FINAL_CONFIG_STATUS_RESOLVED_SPEEDr_reg));
   2558     data = SC_X4_RSLVD_SPDr_SPEEDf_GET(SC_X4_FINAL_CONFIG_STATUS_RESOLVED_SPEEDr_reg);
   2559 #ifdef _DV_TB_
   2560     if(pc->verbosity)
   2561      PHYMOD_DEBUG_ERROR(("Resolved speed is %x :: need %x :: uint :: %d :: lane :: %d\n", data, mapped_speed, pc->unit, pc->this_lane));
   2562 #endif
   2563     cnt = cnt + 1;
   2564     if(data == mapped_speed) {
   2565       spd_match = 1;
   2566       break;
   2567     } else {
   2568       if(cnt == 400) {
   2569         spd_match = 0;
   2570         break;
   2571       }
   2572     }
   2573   }
   2574   if(sc_done && spd_match) {
   2575     done = 1;
   2576   } else {
   2577     done = 0;
   2578   }
   2579   return done;
   2580 }
   2581 
   2582 /**
   2583 @brief   update the port mode
   2584 @param   pc handle to current TSCF context (#PHYMOD_ST)
   2585 @returns The value PHYMOD_E_NONE upon successful completion
   2586 */
   2587 int tbhmod_update_port_mode( PHYMOD_ST *pc)
   2588 {
   2589   MAIN0_SETUPr_t mode_reg;
   2590   PHYMOD_ST phy_copy;
   2591   int port_mode_sel, port_mode_sel_reg, mpp_index = 0;
   2592   uint32_t single_port_mode;
   2593   int first_couple_mode = 0, second_couple_mode = 0;
   2594 
   2595   port_mode_sel = 0 ;
   2596   single_port_mode = 0 ;
   2597 
   2598   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   2599 
   2600 
   2601   /*first check if 8 lane port */
   2602   if(pc->lane_mask == 0xff) {
   2603     single_port_mode = 1;
   2604     mpp_index = 0;
   2605   } else if (pc->lane_mask & 0xf) {
   2606     mpp_index = 0;
   2607   } else {
   2608     mpp_index = 1;
   2609   }
   2610 
   2611   /* next set the MPP index properly */
   2612   if (mpp_index) {
   2613     phy_copy.lane_mask = 0x10;
   2614   } else {
   2615     phy_copy.lane_mask = 0x1;
   2616   }
   2617 
   2618   PHYMOD_IF_ERR_RETURN(READ_MAIN0_SETUPr(&phy_copy, &mode_reg));
   2619   port_mode_sel_reg = MAIN0_SETUPr_PORT_MODE_SELf_GET(mode_reg);
   2620 
   2621   if (!single_port_mode) {
   2622       if ((pc->lane_mask == 0xf) || (pc->lane_mask == 0xf0)) {
   2623         port_mode_sel = cl82_port_mode_SINGLE_PORT;
   2624       } else {
   2625         first_couple_mode = ((port_mode_sel_reg == cl82_port_mode_TRI_2_PORT) ||
   2626                              (port_mode_sel_reg == cl82_port_mode_DUAL_PORT) ||
   2627                              (port_mode_sel_reg == cl82_port_mode_SINGLE_PORT));
   2628 
   2629         second_couple_mode = ((port_mode_sel_reg == cl82_port_mode_TRI_1_PORT) ||
   2630                               (port_mode_sel_reg == cl82_port_mode_DUAL_PORT) ||
   2631                               (port_mode_sel_reg == cl82_port_mode_SINGLE_PORT));
   2632         /* switch(pc->lane){ */
   2633         /* based on the lane mask, figue out which couple mode */
   2634         switch (pc->lane_mask) {
   2635         case 0x1:
   2636         case 0x2:
   2637         case 0x10:
   2638         case 0x20:
   2639           first_couple_mode = 0;
   2640           break;
   2641         case 0x4:
   2642         case 0x8:
   2643         case 0x40:
   2644         case 0x80:
   2645           second_couple_mode = 0;
   2646           break;
   2647         case 0x3:
   2648         case 0x30:
   2649           first_couple_mode = 1;
   2650           break;
   2651         case 0xc:
   2652         case 0xc0:
   2653           second_couple_mode = 1;
   2654           break;
   2655         default:
   2656           return PHYMOD_E_PARAM;
   2657         }
   2658 
   2659         if (first_couple_mode) {
   2660           port_mode_sel =(second_couple_mode)? cl82_port_mode_DUAL_PORT: cl82_port_mode_TRI_2_PORT;
   2661         } else if ((second_couple_mode) && (port_mode_sel_reg != cl82_port_mode_SINGLE_PORT)) {
   2662           port_mode_sel = cl82_port_mode_TRI_1_PORT;
   2663         } else {
   2664           port_mode_sel = cl82_port_mode_QUAD_PORT ;
   2665         }
   2666       }
   2667   }
   2668 
   2669   if (single_port_mode) {
   2670     port_mode_sel = cl82_port_mode_SINGLE_OCTAL_PORT;
   2671     /* both MPP copies needs to be updated */
   2672     MAIN0_SETUPr_PORT_MODE_SELf_SET(mode_reg, port_mode_sel);
   2673     PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUPr(&phy_copy, mode_reg));
   2674     phy_copy.lane_mask = 0x10;
   2675     PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUPr(&phy_copy, mode_reg));
   2676   } else {
   2677     MAIN0_SETUPr_PORT_MODE_SELf_SET(mode_reg, port_mode_sel);
   2678     PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUPr(&phy_copy, mode_reg));
   2679   }
   2680 
   2681   return PHYMOD_E_NONE ;
   2682 }
   2683 
   2684 
   2685 /* ------------------------------------------------------------------------- */
   2686 
   2687 /* TSCBH NEW TIER1s*/
   2688 /* to update port_mode_select value.  If the update warrants a pll reset,
   2689    then return accData=1, otherwise return accData=0.  The update shall
   2690    support flex port technology. Called forced speed modes */
   2691 
   2692 int tbhmod_update_port_mode_select(PHYMOD_ST* pc, tbhmod_port_type_t port_type)
   2693 {
   2694   MAIN0_SETUPr_t   MAIN0_SETUPr_reg;
   2695 #ifdef _DV_TB_
   2696   pc.port_type = port_type;
   2697   pc.accData   = 0;
   2698   if((dv_st->tsc_touched_mpp0 == 1 && pc.this_lane/4==0) || ( pc.this_lane/4==1 && dv_st->tsc_touched_mpp1==1)) {
   2699     return PHYMOD_E_NONE;
   2700   }
   2701 
   2702 #endif
   2703 
   2704 
   2705   if((port_type ==TBHMOD_MULTI_PORT) ||(port_type ==TBHMOD_DXGXS)||
   2706      (port_type ==TBHMOD_SINGLE_PORT)||(port_type ==TBHMOD_TRI1_PORT)||
   2707      (port_type ==TBHMOD_TRI2_PORT)  ||(port_type == TBHMOD_SINGLE_OCTAL_PORT)){
   2708   } else {
   2709     PHYMOD_DEBUG_ERROR(("%-22s: ERROR port_type=%0d undefined\n", __func__, port_type));
   2710     return PHYMOD_E_FAIL;
   2711   }
   2712 
   2713 
   2714  /* Leave port mode to quad in an_en */
   2715   MAIN0_SETUPr_CLR(MAIN0_SETUPr_reg);
   2716   MAIN0_SETUPr_PORT_MODE_SELf_SET(MAIN0_SETUPr_reg, port_type);
   2717   PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_SETUPr(pc, MAIN0_SETUPr_reg));
   2718 
   2719   MAIN0_SETUPr_CLR(MAIN0_SETUPr_reg);
   2720 
   2721   return PHYMOD_E_NONE;
   2722 }
   2723 
   2724 int tbhmod_low_latency_mode_en(PHYMOD_ST* pc,int low_latency_mode_en)
   2725 {
   2726 
   2727    MAIN0_SETUPr_t   MAIN0_SETUPr_reg;
   2728 
   2729    MAIN0_SETUPr_CLR(MAIN0_SETUPr_reg);
   2730    MAIN0_SETUPr_RESOLVED_PORT_MODE_CONTROLf_SET(MAIN0_SETUPr_reg,low_latency_mode_en);
   2731    PHYMOD_IF_ERR_RETURN (MODIFY_MAIN0_SETUPr(pc, MAIN0_SETUPr_reg));
   2732    return PHYMOD_E_NONE;
   2733 }
   2734 
   2735 
   2736 #ifdef _DV_TB_ /*THIS is required for SDK also*/
   2737 /*!
   2738 @brief tbhmod_set_sc_speed , sets the required speed ,
   2739 @returns The value PHYMOD_E_NONE upon successful completion.
   2740 @details
   2741 After the resets, speed_ctrl regs are programmed(as per Ankits new init seq), fills up the lookup table by
   2742 Updating the expected value
   2743 */
   2744 /*int tbhmod_set_sc_speed(tbhmod_st* pc, int set_sw_speed_change) */ /* SET_SC_SPEED */
   2745 int tbhmod_set_sc_speed(PHYMOD_ST* pc, tbhmod_spd_intfc_type_t spd_intf, int set_sw_speed_change)  /* SET_SC_SPEED */
   2746 {
   2747   int mapped_speed;
   2748   SC_X4_CTLr_t SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg;
   2749 
   2750 
   2751   /* write 0 to the speed change */
   2752   SC_X4_CTLr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg);
   2753 
   2754   PHYMOD_IF_ERR_RETURN(READ_SC_X4_CTLr(pc, &SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2755 
   2756   if(set_sw_speed_change) {
   2757     SC_X4_CTLr_SW_SPEED_CHANGEf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, 0);
   2758     PHYMOD_IF_ERR_RETURN(WRITE_SC_X4_CTLr(pc, SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2759   }
   2760 
   2761    /* Set speed and write 1 */
   2762   SC_X4_CTLr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg);
   2763   SC_X4_CTLr_SW_SPEED_CHANGEf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, set_sw_speed_change);
   2764   tbhmod_get_mapped_speed(spd_intf, &mapped_speed);
   2765   SC_X4_CTLr_SW_SPEED_IDf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, mapped_speed);
   2766   PHYMOD_IF_ERR_RETURN(WRITE_SC_X4_CTLr(pc, SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2767 
   2768   /*  Update the speed */
   2769   pc.speed= mapped_speed;
   2770 
   2771 
   2772   return PHYMOD_E_NONE;
   2773 }
   2774 #endif
   2775 
   2776 #ifdef _SDK_TBHMOD_
   2777 int tbhmod_set_sc_speed(PHYMOD_ST* pc, int mapped_speed, int set_sw_speed_change)  /* SET_SC_SPEED */
   2778 {
   2779   SC_X4_CTLr_t SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg;
   2780 
   2781 
   2782   /* write 0 to the speed change */
   2783   SC_X4_CTLr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg);
   2784 
   2785   PHYMOD_IF_ERR_RETURN(READ_SC_X4_CTLr(pc, &SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2786 
   2787   if(set_sw_speed_change) {
   2788     SC_X4_CTLr_SW_SPEED_CHANGEf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, 0);
   2789     PHYMOD_IF_ERR_RETURN(WRITE_SC_X4_CTLr(pc, SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2790   }
   2791 
   2792    /* Set speed and write 1 */
   2793   SC_X4_CTLr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg);
   2794   SC_X4_CTLr_SW_SPEED_CHANGEf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, set_sw_speed_change);
   2795   SC_X4_CTLr_SW_SPEED_IDf_SET(SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg, mapped_speed);
   2796   PHYMOD_IF_ERR_RETURN(WRITE_SC_X4_CTLr(pc, SC_X4_CONTROL_SC_X4_CONTROL_CONTROLr_reg));
   2797 
   2798   return PHYMOD_E_NONE;
   2799 }
   2800 #endif
   2801 
   2802 #ifdef DV_AN_SUPPORT
   2803 int tbhmod_pcs_set_sw_an_speed(PHYMOD_ST* pc, int speed)  /* SET_SW_AN_SPEED */
   2804 {
   2805   AN_X4_LD_CTLr_t AN_X4_LD_CTLr_reg;
   2806 
   2807 
   2808   AN_X4_LD_CTLr_CLR(AN_X4_LD_CTLr_reg);
   2809 
   2810   PHYMOD_IF_ERR_RETURN(READ_AN_X4_LD_CTLr(pc, &AN_X4_LD_CTLr_reg));
   2811 
   2812 
   2813   AN_X4_LD_CTLr_SW_AN_SPEED_IDf_SET(AN_X4_LD_CTLr_reg, speed);
   2814   AN_X4_LD_CTLr_AN_HCD_RES_DISABLEf_SET(AN_X4_LD_CTLr_reg, 1);
   2815   AN_X4_LD_CTLr_AN_TYPE_SWf_SET(AN_X4_LD_CTLr_reg, 1);
   2816   PHYMOD_IF_ERR_RETURN(MODIFY_AN_X4_LD_CTLr(pc, AN_X4_LD_CTLr_reg));
   2817 
   2818   /*  Update the speed */
   2819   pc.speed= speed;
   2820 
   2821 
   2822   return PHYMOD_E_NONE;
   2823 }
   2824 #endif
   2825 
   2826 /**
   2827 @brief   PMD per lane reset
   2828 @param   pc handle to current TSCBH context (#tbhmod_st)
   2829 @returns The value PHYMOD_E_NONE upon successful completion
   2830 @details Per lane PMD ln_rst and ln_dp_rst by writing to PMD_X4_CONTROL in pcs space
   2831 */
   2832 int tbhmod_pmd_x4_reset(PHYMOD_ST* pc)              /* PMD_X4_RESET */
   2833 {
   2834   PMD_X4_CTLr_t reg_pmd_x4_ctrl;
   2835 
   2836 
   2837   PMD_X4_CTLr_CLR(reg_pmd_x4_ctrl);
   2838   PMD_X4_CTLr_LN_H_RSTBf_SET(reg_pmd_x4_ctrl,1);
   2839   PMD_X4_CTLr_LN_DP_H_RSTBf_SET(reg_pmd_x4_ctrl,1);
   2840   PHYMOD_IF_ERR_RETURN (MODIFY_PMD_X4_CTLr(pc, reg_pmd_x4_ctrl));
   2841 
   2842   return PHYMOD_E_NONE;
   2843 }
   2844 
   2845 
   2846 /**
   2847 @brief   RSFEC latency Bit selection
   2848 @param   pc handle to current TSCBH context (#tbhmod_st)
   2849 @returns The value PHYMOD_E_NONE upon successful completion
   2850 @details assert/deassert the cw_latency bit to support 544 and 528 fecs in same MPP
   2851 */
   2852 int tbhmod_rsfec_cw_type(PHYMOD_ST* pc,int en,int fec_bypass_correction)              /* PMD_X4_RESET */
   2853 {
   2854   RX_X1_RS_FEC_CFGr_t reg_rsfec_cfg;
   2855 
   2856 
   2857   RX_X1_RS_FEC_CFGr_CLR(reg_rsfec_cfg );
   2858   RX_X1_RS_FEC_CFGr_RS_FEC_CW_TYPEf_SET(reg_rsfec_cfg,en);
   2859   if(fec_bypass_correction==1) {
   2860     RX_X1_RS_FEC_CFGr_RS_FEC_CORRECTION_ENABLEf_SET(reg_rsfec_cfg,~fec_bypass_correction);
   2861   }
   2862   PHYMOD_IF_ERR_RETURN (MODIFY_RX_X1_RS_FEC_CFGr(pc, reg_rsfec_cfg));
   2863 
   2864   return PHYMOD_E_NONE;
   2865 }
   2866 
   2867 
   2868 /**
   2869 @brief   OSTS Pipeline enable Bit selection
   2870 @param   pc handle to current TSCBH context (#tbhmod_st)
   2871 @returns The value PHYMOD_E_NONE upon successful completion
   2872 @details enable/disable One Step pipeline
   2873 */
   2874 
   2875 int tbhmod_osts_pipeline(PHYMOD_ST* pc, uint32_t en)
   2876 {
   2877  TX_X4_TX_TS_CTLr_t    reg_tx_x4_ts_ctlr;
   2878 
   2879   TX_X4_TX_TS_CTLr_CLR(reg_tx_x4_ts_ctlr);
   2880   TX_X4_TX_TS_CTLr_OSTS_PIPELINE_ENABLEf_SET(reg_tx_x4_ts_ctlr, en);
   2881 
   2882   PHYMOD_IF_ERR_RETURN (MODIFY_TX_X4_TX_TS_CTLr(pc, reg_tx_x4_ts_ctlr));
   2883   return PHYMOD_E_NONE;
   2884 }
   2885 
   2886 int tbhmod_osts_pipeline_get(PHYMOD_ST* pc, uint32_t* en)
   2887 {
   2888   TX_X4_TX_TS_CTLr_t reg_tx_x4_ts_ctlr;
   2889 
   2890   TX_X4_TX_TS_CTLr_CLR(reg_tx_x4_ts_ctlr);
   2891   PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_TS_CTLr(pc, &reg_tx_x4_ts_ctlr));
   2892 
   2893   *en = TX_X4_TX_TS_CTLr_OSTS_PIPELINE_ENABLEf_GET(reg_tx_x4_ts_ctlr);
   2894 
   2895   return PHYMOD_E_NONE;
   2896 }
   2897 
   2898 /*!
   2899 @brief tx lane reset and enable of any particular lane
   2900 @param  pc handle to current TSCBH context (#tbhmod_st)
   2901 @param  en controls enabling properties of  lane  control
   2902 @param  dis controls what property to control enum #tbhmod_tx_disable_enum_t
   2903 @returns The value PHYMOD_E_NONE upon successful completion.
   2904 @details
   2905 This function is used to reset tx lane and enable/disable tx lane of any
   2906 transmit lane.  Set bit 0 of per_lane_control to enable the TX_LANE
   2907 (1) or disable the TX lane (0).
   2908 When diable TX lane, two types of operations are inovked independently.
   2909 If per_lane_control bit [7:4] = 1, only traffic is disabled.
   2910       (TBHMOD_TX_LANE_TRAFFIC =0x10)
   2911 If bit [7:4] = 2, only reset function is invoked.
   2912       (TBHMOD_TX_LANE_RESET = 0x20)
   2913 
   2914 This function reads/modifies the following registers:
   2915 
   2916 \li rstb_tx_lane  :   0xc113[1]
   2917 \li enable_tx_lane:   0xc113[0]
   2918 */
   2919 
   2920 int tbhmod_tx_lane_control(PHYMOD_ST* pc, int en, tbhmod_tx_disable_enum_t dis)         /* TX_LANE_CONTROL */
   2921 {
   2922   TX_X4_MISCr_t TX_X4_CONTROL0_MISCr_reg;
   2923 
   2924  /* TBHMOD_DBG_IN_FUNC_INFO(pc); */
   2925 
   2926   #ifdef _DV_TB_
   2927 
   2928    printf("TBHMOD_TIER1_TX_LANE_CONTROL: Enabling TXLane and removing Reset for Lane %0d unit %0d\n",pc.this_lane,pc.unit);
   2929   #endif
   2930 
   2931    if (en) {
   2932     TX_X4_MISCr_CLR(TX_X4_CONTROL0_MISCr_reg);
   2933     TX_X4_MISCr_RSTB_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 1);
   2934     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X4_MISCr(pc, TX_X4_CONTROL0_MISCr_reg));
   2935 
   2936     TX_X4_MISCr_CLR(TX_X4_CONTROL0_MISCr_reg);
   2937     TX_X4_MISCr_ENABLE_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 1);
   2938     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X4_MISCr(pc, TX_X4_CONTROL0_MISCr_reg));
   2939   } else {
   2940     TX_X4_MISCr_CLR(TX_X4_CONTROL0_MISCr_reg);
   2941     if(dis == TBHMOD_TX_LANE_TRAFFIC_DISABLE ){
   2942       TX_X4_MISCr_ENABLE_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 0);
   2943     } else if (dis == TBHMOD_TX_LANE_RESET) {
   2944       TX_X4_MISCr_RSTB_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 0);
   2945     } else {
   2946       TX_X4_MISCr_RSTB_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 0);
   2947       TX_X4_MISCr_ENABLE_TX_LANEf_SET(TX_X4_CONTROL0_MISCr_reg, 0);
   2948     }
   2949     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X4_MISCr(pc, TX_X4_CONTROL0_MISCr_reg));
   2950   }
   2951 
   2952 
   2953   return PHYMOD_E_NONE;
   2954 }
   2955 
   2956 
   2957 /*!
   2958 @brief rx lane reset and enable of any particular lane
   2959 @param  pc handle to current TSCBH context (#tbhmod_st)
   2960 @param  accData TBD
   2961 @param  per_lane_control TBD
   2962 @returns The value PHYMOD_E_NONE upon successful completion.
   2963 @details
   2964 This function enables/disables rx lane (RSTB_LANE) or read back control bit for
   2965 that based on per_lane_control being 1 or 0. If per_lane_control is 0xa, only
   2966 read back RSTB_LANE.
   2967 \li select encodeMode
   2968 This function reads/modifies the following registers:
   2969 \li rstb_rx_lane  :   0xc137[0]
   2970 */
   2971 
   2972 int tbhmod_rx_lane_control(PHYMOD_ST* pc, int per_lane_control)         /* RX_LANE_CONTROL */
   2973 {
   2974   int cntl;
   2975   RX_X4_PMA_CTL0r_t RX_X4_CONTROL0_PMA_CONTROL_0r_reg;
   2976 
   2977   cntl = per_lane_control;
   2978 
   2979   #ifdef _DV_TB_
   2980   printf("TBHMOD_TIER1_RX_LANE_CONTROL:Enabling Rx Lane and bringing outofreset for  lane %0d unit %0d\n",pc.this_lane,pc.unit);
   2981   #endif
   2982   RX_X4_PMA_CTL0r_CLR(RX_X4_CONTROL0_PMA_CONTROL_0r_reg);
   2983 
   2984   if (cntl) {
   2985     RX_X4_PMA_CTL0r_RSTB_LANEf_SET(RX_X4_CONTROL0_PMA_CONTROL_0r_reg, 1);
   2986     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_PMA_CTL0r(pc, RX_X4_CONTROL0_PMA_CONTROL_0r_reg));
   2987   } else {
   2988      /* bit set to 0 for disabling RXP */
   2989     RX_X4_PMA_CTL0r_RSTB_LANEf_SET(RX_X4_CONTROL0_PMA_CONTROL_0r_reg, 0);
   2990     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_PMA_CTL0r(pc, RX_X4_CONTROL0_PMA_CONTROL_0r_reg));
   2991   }
   2992   return PHYMOD_E_NONE;
   2993 }
   2994 
   2995 
   2996 /*!
   2997 @brief Power down transmitter or receiver per lane basis.
   2998 @param  pc handle to current TSCBH context (a.k.a #tbhmod_st)
   2999 @param tx control for power of TX path
   3000 @param rx control for power of RX path
   3001 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3002 @details
   3003 Indi
   3004 */
   3005 int tbhmod_power_control(PHYMOD_ST* pc, int tx, int rx)
   3006 {
   3007   PMD_X4_CTLr_t PMD_X4_PMD_X4_CONTROLr_reg;
   3008 
   3009     /*TBHMOD_DBG_IN_FUNC_INFO(pc);*/
   3010   PMD_X4_CTLr_CLR(PMD_X4_PMD_X4_CONTROLr_reg);
   3011 
   3012   PMD_X4_CTLr_LN_RX_H_PWRDNf_SET(PMD_X4_PMD_X4_CONTROLr_reg, rx);
   3013   PMD_X4_CTLr_LN_TX_H_PWRDNf_SET(PMD_X4_PMD_X4_CONTROLr_reg, tx);
   3014   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_CTLr(pc, PMD_X4_PMD_X4_CONTROLr_reg));
   3015   return PHYMOD_E_NONE;
   3016 }
   3017 
   3018 
   3019 
   3020 
   3021 int tbhmod_get_sw_mgmt_glb_int(PHYMOD_ST* pc, int *port_int)
   3022 {
   3023     AN_X1_GLB_INTr_t  AN_X1_GLB_INTr_reg;
   3024 
   3025      AN_X1_GLB_INTr_CLR(AN_X1_GLB_INTr_reg);
   3026     PHYMOD_IF_ERR_RETURN(READ_AN_X1_GLB_INTr(pc, &AN_X1_GLB_INTr_reg));
   3027     *port_int = AN_X1_GLB_INTr_GET(AN_X1_GLB_INTr_reg);
   3028 
   3029 
   3030     return PHYMOD_E_NONE;
   3031 }
   3032 
   3033 
   3034 
   3035 
   3036 
   3037 /*!
   3038  @brief Rx laneswap per Mpp.
   3039 @param  unit number for instance lane number for decide which lane
   3040 @param rx_lane_swap value tells phy to log lanes mapping
   3041 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3042 @details Rx lane swap */
   3043 int tbhmod_pcs_rx_lane_swap(PHYMOD_ST* pc, int rx_lane_swap)
   3044 {
   3045     uint8_t rx_lane_map_physical[8], lane;
   3046     RX_X1_RX_LN_SWPr_t    RX_X1_RX_LN_SWPr_reg;
   3047 
   3048     /*first we need to translate logical ln based on physical lane based lane ma-*/
   3049     for (lane = 0; lane < TSCBH_NOF_LANES_IN_CORE; lane++){
   3050         rx_lane_map_physical[((rx_lane_swap >> (lane*4)) & 0xf)] = lane;
   3051     }
   3052 
   3053     /*first for physcial lane 0 through 3, use mmp0 */
   3054     RX_X1_RX_LN_SWPr_CLR(RX_X1_RX_LN_SWPr_reg);
   3055     pc->lane_mask = 0x1 << 0;
   3056     RX_X1_RX_LN_SWPr_PHYSICAL3_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[3] & 0x7));
   3057     RX_X1_RX_LN_SWPr_PHYSICAL2_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[2] & 0x7));
   3058     RX_X1_RX_LN_SWPr_PHYSICAL1_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[1] & 0x7));
   3059     RX_X1_RX_LN_SWPr_PHYSICAL0_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[0] & 0x7));
   3060     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X1_RX_LN_SWPr(pc, RX_X1_RX_LN_SWPr_reg));
   3061 
   3062     RX_X1_RX_LN_SWPr_CLR(RX_X1_RX_LN_SWPr_reg);
   3063     pc->lane_mask = 0x1 << 4;
   3064     RX_X1_RX_LN_SWPr_PHYSICAL3_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[7] & 0x7));
   3065     RX_X1_RX_LN_SWPr_PHYSICAL2_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[6] & 0x7));
   3066     RX_X1_RX_LN_SWPr_PHYSICAL1_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[5] & 0x7));
   3067     RX_X1_RX_LN_SWPr_PHYSICAL0_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg,(rx_lane_map_physical[4] & 0x7));
   3068 
   3069     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X1_RX_LN_SWPr(pc, RX_X1_RX_LN_SWPr_reg));
   3070 
   3071     return PHYMOD_E_NONE;
   3072 }
   3073 
   3074 /*!
   3075  @brief  single Rx laneswap per Mpp.
   3076 @param  unit number for instance lane number for decide which lane
   3077 @param rx_lane_swap value tells phy to log lanes mapping
   3078 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3079 @details Rx lane swap */
   3080 int tbhmod_pcs_single_rx_lane_swap_set(PHYMOD_ST* pc, int rx_physical_lane, int rx_logical_lane)
   3081 {
   3082     RX_X1_RX_LN_SWPr_t    RX_X1_RX_LN_SWPr_reg;
   3083 
   3084     /*first decide which MPP to write */
   3085     if (rx_physical_lane < 4) {
   3086         pc->lane_mask = 0x1 << 0;
   3087     } else {
   3088         pc->lane_mask = 0x1 << 4;
   3089     }
   3090 
   3091     RX_X1_RX_LN_SWPr_CLR(RX_X1_RX_LN_SWPr_reg);
   3092 
   3093     switch (rx_physical_lane) {
   3094         case 0:
   3095         case 4:
   3096             RX_X1_RX_LN_SWPr_PHYSICAL0_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg, rx_logical_lane & 0x7);
   3097             break;
   3098         case 1:
   3099         case 5:
   3100             RX_X1_RX_LN_SWPr_PHYSICAL1_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg, rx_logical_lane & 0x7);
   3101             break;
   3102         case 2:
   3103         case 6:
   3104             RX_X1_RX_LN_SWPr_PHYSICAL2_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg, rx_logical_lane & 0x7);
   3105             break;
   3106         case 3:
   3107         case 7:
   3108             RX_X1_RX_LN_SWPr_PHYSICAL3_TO_LOGICAL_SELf_SET(RX_X1_RX_LN_SWPr_reg, rx_logical_lane & 0x7);
   3109             break;
   3110         default:
   3111             PHYMOD_DEBUG_ERROR(("Unsupported physical lane \n"));
   3112             return PHYMOD_E_UNAVAIL;
   3113     }
   3114 
   3115     PHYMOD_IF_ERR_RETURN(MODIFY_RX_X1_RX_LN_SWPr(pc, RX_X1_RX_LN_SWPr_reg));
   3116 
   3117     return PHYMOD_E_NONE;
   3118 }
   3119 
   3120 
   3121 
   3122  /*!
   3123  @brief Tx laneswap per Mpp.
   3124 @param  unit number for instance lane number for decide which lane
   3125 @param tx_lane_swap value tells phy to log lanes mapping
   3126 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3127 @details Tx lane swap */
   3128 int tbhmod_pcs_tx_lane_swap(PHYMOD_ST* pc, int tx_lane_swap)
   3129 {
   3130     uint8_t tx_lane_map_physical[8], lane;
   3131     TX_X1_TX_LN_SWPr_t TX_X1_TX_LN_SWPr_reg;
   3132 
   3133     /*first we need to translate logical ln based on physical lane based lane ma-*/
   3134     for (lane = 0; lane < TSCBH_NOF_LANES_IN_CORE; lane++){
   3135         tx_lane_map_physical[((tx_lane_swap >> (lane*4)) & 0xf)] = lane;
   3136     }
   3137 
   3138     /* next need to adjust the MPP1 logical lane offset */
   3139     for (lane = 0; lane < TSCBH_NOF_LANES_IN_CORE / 2; lane++){
   3140         if (tx_lane_map_physical[4 + lane] < 4) {
   3141             tx_lane_map_physical[4 + lane] += 4;
   3142         } else {
   3143             tx_lane_map_physical[4 + lane] -= 4;
   3144         }
   3145     }
   3146     /*for the physical 0 through 3 using MPP0 */
   3147     TX_X1_TX_LN_SWPr_CLR(TX_X1_TX_LN_SWPr_reg);
   3148     pc->lane_mask = 0x1 << 0;
   3149     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL0_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[0] & 0x7));
   3150     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL1_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[1] & 0x7));
   3151     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL2_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[2] & 0x7));
   3152     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL3_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[3] & 0x7));
   3153     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X1_TX_LN_SWPr(pc, TX_X1_TX_LN_SWPr_reg));
   3154 
   3155 
   3156     /*for the physical 4 through 7 using MPP1 */
   3157     TX_X1_TX_LN_SWPr_CLR(TX_X1_TX_LN_SWPr_reg);
   3158     pc->lane_mask = 0x1 << 4;
   3159     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL0_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[4] & 0x7));
   3160     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL1_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[5] & 0x7));
   3161     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL2_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[6] & 0x7));
   3162     TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL3_SELf_SET(TX_X1_TX_LN_SWPr_reg, (tx_lane_map_physical[7] & 0x7));
   3163     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X1_TX_LN_SWPr(pc, TX_X1_TX_LN_SWPr_reg));
   3164 
   3165     return PHYMOD_E_NONE;
   3166 }
   3167 
   3168 
   3169  /*!
   3170  @brief Tx laneswap per single phyiscal lane.
   3171 @param  unit number for instance lane number for decide which lane
   3172 @param tx_lane_swap value tells phy to log lanes mapping
   3173 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3174 @details Tx lane swap */
   3175 int tbhmod_pcs_single_tx_lane_swap_set(PHYMOD_ST* pc, int tx_physical_lane, int tx_logical_lane)
   3176 {
   3177     TX_X1_TX_LN_SWPr_t TX_X1_TX_LN_SWPr_reg;
   3178     int tmp_logical_lane;
   3179 
   3180     /*first decide which MPP to write */
   3181     if (tx_physical_lane < 4) {
   3182         pc->lane_mask = 0x1 << 0;
   3183         tmp_logical_lane = tx_logical_lane;
   3184     } else {
   3185         pc->lane_mask = 0x1 << 4;
   3186         if (tx_logical_lane < 4) {
   3187             tmp_logical_lane = tx_logical_lane + 4;
   3188         } else {
   3189             tmp_logical_lane = tx_logical_lane - 4;
   3190         }
   3191     }
   3192 
   3193     TX_X1_TX_LN_SWPr_CLR(TX_X1_TX_LN_SWPr_reg);
   3194 
   3195     switch (tx_physical_lane) {
   3196         case 0:
   3197         case 4:
   3198             TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL0_SELf_SET(TX_X1_TX_LN_SWPr_reg, tmp_logical_lane & 0x7);
   3199             break;
   3200         case 1:
   3201         case 5:
   3202             TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL1_SELf_SET(TX_X1_TX_LN_SWPr_reg, tmp_logical_lane & 0x7);
   3203             break;
   3204         case 2:
   3205         case 6:
   3206             TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL2_SELf_SET(TX_X1_TX_LN_SWPr_reg, tmp_logical_lane & 0x7);
   3207             break;
   3208         case 3:
   3209         case 7:
   3210             TX_X1_TX_LN_SWPr_LOGICAL_TO_PHYSICAL3_SELf_SET(TX_X1_TX_LN_SWPr_reg, tmp_logical_lane & 0x7);
   3211             break;
   3212         default:
   3213             PHYMOD_DEBUG_ERROR(("Unsupported physical lane \n"));
   3214             return PHYMOD_E_UNAVAIL;
   3215     }
   3216 
   3217     PHYMOD_IF_ERR_RETURN(MODIFY_TX_X1_TX_LN_SWPr(pc, TX_X1_TX_LN_SWPr_reg));
   3218     return PHYMOD_E_NONE;
   3219 }
   3220 
   3221 
   3222 
   3223 /*!
   3224  *  @brief rx_scrambleidle_en per port.
   3225 @param  unit number for instance lane number for decide which lane
   3226 @param en tells enabling/disabling r_test_mode AKA scrmable_idle_en
   3227 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3228 @details  Rx scramble Idle Enable */
   3229 int tbhmod_pcs_rx_scramble_idle_en(PHYMOD_ST* pc, int en)
   3230 {
   3231 
   3232   RX_X4_DEC_CTL0r_t RX_X4_CONTROL0_DECODE_CONTROL_0r_reg;
   3233 
   3234   RX_X4_DEC_CTL0r_CLR(RX_X4_CONTROL0_DECODE_CONTROL_0r_reg);
   3235   RX_X4_DEC_CTL0r_R_TEST_MODE_CFGf_SET(RX_X4_CONTROL0_DECODE_CONTROL_0r_reg, en);
   3236   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_DEC_CTL0r(pc, RX_X4_CONTROL0_DECODE_CONTROL_0r_reg));
   3237 
   3238   return PHYMOD_E_NONE;
   3239 }
   3240 
   3241 /*!
   3242  *  @brief tbhmod_pcs_rx_ts_en per port.
   3243 @param unit number for instance lane number for decide which lane
   3244 @param en tells enabling/disabling r_test_mode AKA scrmable_idle_en
   3245 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3246 @details Enables ts in rx path */
   3247 int tbhmod_pcs_rx_ts_en(PHYMOD_ST* pc, uint32_t en, int sfd)
   3248 {
   3249   RX_X4_RX_TS_CTLr_t RX_X4_RX_TS_CTLr_reg;
   3250 
   3251 
   3252   RX_X4_RX_TS_CTLr_CLR(RX_X4_RX_TS_CTLr_reg);
   3253 
   3254   RX_X4_RX_TS_CTLr_TS_UPDATE_ENABLEf_SET(RX_X4_RX_TS_CTLr_reg, en);
   3255   RX_X4_RX_TS_CTLr_RECORD_DESKEW_TS_INFOf_SET(RX_X4_RX_TS_CTLr_reg, 1);
   3256   RX_X4_RX_TS_CTLr_RX_SFD_TS_ENf_SET(RX_X4_RX_TS_CTLr_reg, sfd);
   3257   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_RX_TS_CTLr(pc, RX_X4_RX_TS_CTLr_reg));
   3258 
   3259   return PHYMOD_E_NONE;
   3260 }
   3261 
   3262 int tbhmod_pcs_rx_ts_en_get(PHYMOD_ST* pc, uint32_t* en)
   3263 {
   3264   RX_X4_RX_TS_CTLr_t RX_X4_RX_TS_CTLr_reg;
   3265 
   3266   RX_X4_RX_TS_CTLr_CLR(RX_X4_RX_TS_CTLr_reg);
   3267   PHYMOD_IF_ERR_RETURN(READ_RX_X4_RX_TS_CTLr(pc, &RX_X4_RX_TS_CTLr_reg));
   3268   *en = RX_X4_RX_TS_CTLr_TS_UPDATE_ENABLEf_GET(RX_X4_RX_TS_CTLr_reg);
   3269 
   3270   return PHYMOD_E_NONE;
   3271 }
   3272 
   3273 uint32_t _tbhmod_pcs_vco_to_ui(uint32_t vco, int os_mode, int pam4)
   3274 {
   3275   uint32_t ui_value;
   3276   ui_value = 0;
   3277   switch(vco) {
   3278     case TBHMOD_VCO_20G:
   3279       if(os_mode == 1) {
   3280         ui_value = 0x18d3018c; /* 2/20.625 = 0.09696.. make 32 bit 0.09696.. * 2^32 = 416481676 = 0x18d3018c */
   3281       } else {
   3282         ui_value = 0x0c6980c6; /* 1/20.625 = 0.04848.. make 32 bit 0.04848.. * 2^32 = 208240838 = 0xc6980c6 */
   3283       }
   3284       break;
   3285     case TBHMOD_VCO_25G:
   3286       if(pam4) {
   3287         ui_value = 0x04f7004e;
   3288       } else {
   3289         ui_value = 0x09ee009c;
   3290       }
   3291       break;
   3292     case TBHMOD_VCO_26G:
   3293       if(pam4) {
   3294         ui_value = 0x04d19e6b;
   3295       } else {
   3296         ui_value = 0x09a33cd6;
   3297       }
   3298       break;
   3299       default: break;
   3300   }
   3301   return ui_value;
   3302 }
   3303 
   3304 /*!
   3305  *  @brief tbhmod_pcs_set_1588_ui per port.
   3306 @param unit number for instance lane number for decide which lane
   3307 @param vco tells which vco is used in the lane
   3308 @param os_mode tells which os_mode is used in the lane
   3309 @param clk4sync_div the fast clk divider 0 => 8 and 1 => 6
   3310 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3311 @details Enables ts in rx path */
   3312 int tbhmod_pcs_set_1588_ui (PHYMOD_ST* pc, uint32_t vco, uint32_t vco1, int os_mode, int clk4sync_div, int pam4)
   3313 {
   3314   PMD_X1_FCLK_PERIODr_t PMD_X1_FCLK_PERIODr_reg;
   3315   PMD_X4_UI_VALUE_HIr_t PMD_X4_UI_VALUE_HIr_reg;
   3316   PMD_X4_UI_VALUE_LOr_t PMD_X4_UI_VALUE_LOr_reg;
   3317   int fclk_period = 0, ui_value_hi, ui_value_lo;
   3318 
   3319 
   3320   ui_value_hi = _tbhmod_pcs_vco_to_ui(vco, os_mode, pam4)>>16;
   3321   ui_value_lo = _tbhmod_pcs_vco_to_ui(vco, os_mode, pam4)&0xffff;
   3322 
   3323 
   3324   switch(vco1) {
   3325     case TBHMOD_VCO_20G:
   3326       if(clk4sync_div) fclk_period = 0x4a79; else fclk_period = 0x634c;
   3327       break;
   3328     case TBHMOD_VCO_25G:
   3329       fclk_period = 0x4f70;
   3330       break;
   3331     case TBHMOD_VCO_26G:
   3332       fclk_period = 0x4d19;
   3333       break;
   3334       default: break;
   3335   }
   3336 
   3337 
   3338   PMD_X1_FCLK_PERIODr_CLR(PMD_X1_FCLK_PERIODr_reg);
   3339   PMD_X4_UI_VALUE_HIr_CLR(PMD_X4_UI_VALUE_HIr_reg);
   3340   PMD_X4_UI_VALUE_LOr_CLR(PMD_X4_UI_VALUE_LOr_reg);
   3341 
   3342   PMD_X1_FCLK_PERIODr_FCLK_FRAC_NSf_SET(PMD_X1_FCLK_PERIODr_reg, fclk_period);
   3343   PMD_X4_UI_VALUE_HIr_UI_FRAC_M1_TO_M16f_SET( PMD_X4_UI_VALUE_HIr_reg, ui_value_hi);
   3344   PMD_X4_UI_VALUE_LOr_UI_FRAC_M17_TO_M23f_SET( PMD_X4_UI_VALUE_LOr_reg, ui_value_lo);
   3345 
   3346   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X1_FCLK_PERIODr(pc, PMD_X1_FCLK_PERIODr_reg));
   3347   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_UI_VALUE_HIr(pc, PMD_X4_UI_VALUE_HIr_reg));
   3348   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_UI_VALUE_LOr(pc, PMD_X4_UI_VALUE_LOr_reg));
   3349 
   3350   return PHYMOD_E_NONE;
   3351 }
   3352 
   3353 /*!
   3354  *  @brief tbhmod_1588_pmd_latency per port.
   3355 @param unit number for instance lane number for decide which lane
   3356 @param vco tells which vco is used in the lane
   3357 @param os_mode tells which os_mode is used in the lane
   3358 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3359 @details Enables ts in rx path */
   3360 int tbhmod_1588_pmd_latency (PHYMOD_ST* pc, uint32_t vco, int os_mode, int pam4)
   3361 {
   3362   PHYMOD_ST phy_copy;
   3363   int start_lane, num_lane, i;
   3364   uint32_t tx_latency, rx_latency;
   3365   uint32_t ui_val;
   3366   PMD_X4_RX_FIXED_LATENCYr_t PMD_X4_RX_FIXED_LATENCYr_reg;
   3367   PMD_X4_TX_FIXED_LATENCYr_t PMD_X4_TX_FIXED_LATENCYr_reg;
   3368 
   3369   PHYMOD_IF_ERR_RETURN
   3370       (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   3371 
   3372   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   3373   /* ui_val with fractional bit 32 bit from _tbhmod_pcs_vco_to_ui we need 10 fractional
   3374      so we need 22 bit shift first shifting 8 then 14 to improve accuracy
   3375   */
   3376   ui_val = _tbhmod_pcs_vco_to_ui(vco, os_mode, pam4)>>8;
   3377 
   3378   /* tx_latency and rx_latency with fractional bit 10 bit */
   3379   if(pam4) {
   3380     tx_latency = (ui_val * (124-20)) >> 14;
   3381     rx_latency = (ui_val * (81 +20)) >> 14;
   3382   } else {
   3383     tx_latency = (ui_val * (144-20)) >> 14;  /* delay number from Blackhawk_V1.0 User Spec.pdf */
   3384     rx_latency = (ui_val * (121+20)) >> 14;
   3385   }
   3386 
   3387   for(i=0; i < num_lane; i++) {
   3388     
   3389     /* pc.this_lane = lane+i; */
   3390     phy_copy.lane_mask = 0x1 << (start_lane + i);
   3391     PMD_X4_RX_FIXED_LATENCYr_CLR(PMD_X4_RX_FIXED_LATENCYr_reg);
   3392     PMD_X4_TX_FIXED_LATENCYr_CLR(PMD_X4_TX_FIXED_LATENCYr_reg);
   3393 
   3394     PMD_X4_RX_FIXED_LATENCYr_RX_PMD_LATENCY_IN_NSf_SET (PMD_X4_RX_FIXED_LATENCYr_reg, (rx_latency >> 10));
   3395     PMD_X4_RX_FIXED_LATENCYr_RX_PMD_LATENCY_IN_FRAC_NSf_SET(PMD_X4_RX_FIXED_LATENCYr_reg, (rx_latency & 0x3ff));
   3396 
   3397     PMD_X4_TX_FIXED_LATENCYr_TX_PMD_LATENCY_IN_NSf_SET (PMD_X4_TX_FIXED_LATENCYr_reg, (tx_latency >> 10));
   3398     PMD_X4_TX_FIXED_LATENCYr_TX_PMD_LATENCY_IN_FRAC_NSf_SET(PMD_X4_TX_FIXED_LATENCYr_reg, (tx_latency & 0x3ff));
   3399 
   3400     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_RX_FIXED_LATENCYr(pc, PMD_X4_RX_FIXED_LATENCYr_reg));
   3401     PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_TX_FIXED_LATENCYr(pc, PMD_X4_TX_FIXED_LATENCYr_reg));
   3402   }
   3403 
   3404   return PHYMOD_E_NONE;
   3405 }
   3406 
   3407 /*! 
   3408  *  @brief tbhmod_pcs_rx_deskew_en per port.
   3409 @param unit number for instance lane number for decide which lane 
   3410 @param en tells enabling/disabling r_test_mode AKA scrmable_idle_en
   3411 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3412 @details Enables ts in rx path */
   3413 int tbhmod_pcs_rx_deskew_en(PHYMOD_ST* pc, int en)
   3414 {
   3415   RX_X4_RX_TS_CTLr_t RX_X4_RX_TS_CTLr_reg;
   3416 
   3417   RX_X4_RX_TS_CTLr_CLR(RX_X4_RX_TS_CTLr_reg);
   3418 
   3419   RX_X4_RX_TS_CTLr_RECORD_DESKEW_TS_INFOf_SET(RX_X4_RX_TS_CTLr_reg, en);
   3420   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_RX_TS_CTLr(pc, RX_X4_RX_TS_CTLr_reg));
   3421 
   3422   return PHYMOD_E_NONE;
   3423 }
   3424 
   3425 /*!
   3426  *  @brief tbhmod_pcs_set_1588_xgmii per port.
   3427 @param unit number for instance lane number for decide which lane
   3428 @param sfd tells if sfd time stamp or sop time stamp
   3429 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3430 @details Enables ts in rx path */
   3431 int tbhmod_pcs_set_1588_xgmii (PHYMOD_ST* pc, int sfd, uint32_t vco, int os_mode)
   3432 {
   3433   int nsT, subNsT;
   3434   RX_X4_RX_TS_CTLr_t RX_X4_RX_TS_CTLr_reg;
   3435   TX_X4_TX_TS_CTLr_t TX_X4_TX_TS_CTLr_reg;
   3436 
   3437 
   3438   switch(vco) {
   3439     case TBHMOD_VCO_20G:
   3440       if(os_mode == 1) {
   3441         nsT = 3; subNsT = 3;
   3442       } else {
   3443         nsT = 1; subNsT = 9;
   3444       }
   3445       break;
   3446     case TBHMOD_VCO_25G:
   3447       nsT = 1; subNsT = 4;
   3448       break;
   3449     default:
   3450       nsT = 3; subNsT = 3;
   3451       break;
   3452   }
   3453 
   3454   RX_X4_RX_TS_CTLr_CLR(RX_X4_RX_TS_CTLr_reg);
   3455   TX_X4_TX_TS_CTLr_CLR(TX_X4_TX_TS_CTLr_reg);
   3456 
   3457   RX_X4_RX_TS_CTLr_SIGN_XGMII_MODE_ADDERf_SET(RX_X4_RX_TS_CTLr_reg, 0);
   3458   RX_X4_RX_TS_CTLr_NS_XGMII_MODE_ADDERf_SET(RX_X4_RX_TS_CTLr_reg, nsT);
   3459   RX_X4_RX_TS_CTLr_SUB_NS_XGMII_MODE_ADDERf_SET(RX_X4_RX_TS_CTLr_reg, subNsT);
   3460   RX_X4_RX_TS_CTLr_RX_SFD_TS_ENf_SET(RX_X4_RX_TS_CTLr_reg, sfd);
   3461   PHYMOD_IF_ERR_RETURN(MODIFY_RX_X4_RX_TS_CTLr(pc, RX_X4_RX_TS_CTLr_reg));
   3462 
   3463   TX_X4_TX_TS_CTLr_XGMII_SFD_TIME_STAMP_ENABLEf_SET(TX_X4_TX_TS_CTLr_reg, sfd);
   3464   PHYMOD_IF_ERR_RETURN(MODIFY_TX_X4_TX_TS_CTLr(pc, TX_X4_TX_TS_CTLr_reg));
   3465 
   3466   return PHYMOD_E_NONE;
   3467 }
   3468 
   3469 int _tbhmod_virtual_lane_count_get(int bit_mux_mode, int num_lane, int* virtual_lanes, int* num_psll_per_phyl)
   3470 {
   3471   switch(bit_mux_mode) {
   3472     case 0: {
   3473                 *virtual_lanes = num_lane * 1;
   3474                 *num_psll_per_phyl = 1;
   3475                 break;
   3476             }
   3477     case 1: {
   3478                 *virtual_lanes = num_lane * 2;
   3479                 *num_psll_per_phyl = 2;
   3480                 break;
   3481             }
   3482     case 2: {
   3483                 *virtual_lanes = num_lane * 4;
   3484                 *num_psll_per_phyl = 4;
   3485                 break;
   3486              }
   3487     case 3: {
   3488                 *virtual_lanes = num_lane * 5;
   3489                 *num_psll_per_phyl = 5;
   3490                 break;
   3491              }
   3492     default: {
   3493                 *virtual_lanes = num_lane * 1;
   3494                 *num_psll_per_phyl = 1;
   3495                 break;
   3496              }
   3497   }
   3498   return PHYMOD_E_NONE;
   3499 }
   3500 
   3501 int tbhmod_pcs_mod_rx_1588_tbl_val(PHYMOD_ST* pc, int bit_mux_mode, uint32_t vco, int os_mode, int pam4, int tbl_ln, uint32_t *table) {
   3502 #ifdef SERDES_API_FLOATING_POINT
   3503   PHYMOD_ST phy_copy;
   3504   int i, curr_psll, num_psll_per_phyl;
   3505   int num_lane, start_lane, virtual_lanes;
   3506   int32_t  table_time;
   3507 
   3508   /* per psuedo logical lane
   3509    * the equation: {NS,sub_ns} + fclk_period * fclk_adjust + bit_offset * bit_ui_val
   3510    * there are 4 logical lanes per mpp and 20 virtual lanes.
   3511    */
   3512   uint32_t psll_update[20];
   3513   uint32_t ui_value;
   3514   float bit_ui_val, bit_ui_val1, bit_ui_val2;
   3515   uint16_t base_ts_ns;
   3516   uint16_t base_ts_subns;
   3517   uint8_t am_slip_cnt;
   3518   uint8_t am_ts_fclk_adj_val;
   3519   uint8_t deskew_ts_info_val;
   3520   uint32_t fclk_period;
   3521   uint32_t psll_val_min, psll_roval_min;
   3522   uint32_t psll_val_max, psll_roval_max;
   3523   int32_t  vlane_val_correction;
   3524   int32_t  psll_val_correction[20];
   3525   int32_t  psll_to_vl_map[20];
   3526   uint32_t curr_vl;
   3527 
   3528   PMD_X1_FCLK_PERIODr_t PMD_X1_FCLK_PERIODr_reg;
   3529 
   3530   RX_X4_PSLL_TO_VL_MAP0r_t RX_X4_PSLL_TO_VL_MAP0r_reg;
   3531   RX_X4_PSLL_TO_VL_MAP1r_t RX_X4_PSLL_TO_VL_MAP1r_reg;
   3532 
   3533   RX_X4_SKEW_OFFSS0r_t RX_X4_SKEW_OFFSS0r_reg;
   3534   RX_X4_SKEW_OFFSS1r_t RX_X4_SKEW_OFFSS1r_reg;
   3535   RX_X4_SKEW_OFFSS2r_t RX_X4_SKEW_OFFSS2r_reg;
   3536   RX_X4_SKEW_OFFSS3r_t RX_X4_SKEW_OFFSS3r_reg;
   3537   RX_X4_SKEW_OFFSS4r_t RX_X4_SKEW_OFFSS4r_reg;
   3538 
   3539   RX_X4_AM_TS_INFO0r_t RX_X4_AM_TS_INFO0r_reg;
   3540   RX_X4_AM_TS_INFO1r_t RX_X4_AM_TS_INFO1r_reg;
   3541   RX_X4_AM_TS_INFO2r_t RX_X4_AM_TS_INFO2r_reg;
   3542   RX_X4_AM_TS_INFO3r_t RX_X4_AM_TS_INFO3r_reg;
   3543   RX_X4_AM_TS_INFO4r_t RX_X4_AM_TS_INFO4r_reg;
   3544 
   3545   PHYMOD_IF_ERR_RETURN
   3546       (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   3547 
   3548   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   3549 
   3550   PHYMOD_IF_ERR_RETURN(
   3551        _tbhmod_virtual_lane_count_get(bit_mux_mode, num_lane, &virtual_lanes, &num_psll_per_phyl));
   3552 
   3553   if(virtual_lanes == 1) { return PHYMOD_E_NONE; }
   3554 
   3555   ui_value = _tbhmod_pcs_vco_to_ui(vco, os_mode, pam4);
   3556 
   3557   bit_ui_val1 = (float) ui_value/1024;
   3558   bit_ui_val2 = (float) bit_ui_val1/1024;
   3559   bit_ui_val = (float) bit_ui_val2/4096;
   3560 
   3561   psll_val_min = 0x80000;
   3562   psll_roval_min = 0x80000;
   3563   psll_val_max = 0;
   3564   psll_roval_max = 0;
   3565   curr_psll = 0;
   3566 
   3567   PHYMOD_IF_ERR_RETURN(READ_PMD_X1_FCLK_PERIODr(pc,&PMD_X1_FCLK_PERIODr_reg));
   3568   fclk_period = PMD_X1_FCLK_PERIODr_FCLK_FRAC_NSf_GET(PMD_X1_FCLK_PERIODr_reg);
   3569 
   3570 
   3571   for(i=0; i < num_lane; i++) {
   3572         /* pc.this_lane = lane + i; */
   3573         phy_copy.lane_mask = 0x1 << (start_lane + i);
   3574 
   3575         PHYMOD_IF_ERR_RETURN(READ_RX_X4_PSLL_TO_VL_MAP0r(&phy_copy,&RX_X4_PSLL_TO_VL_MAP0r_reg));
   3576         PHYMOD_IF_ERR_RETURN(READ_RX_X4_PSLL_TO_VL_MAP1r(&phy_copy,&RX_X4_PSLL_TO_VL_MAP1r_reg));
   3577         if (num_psll_per_phyl > 0) {
   3578             curr_vl  = RX_X4_PSLL_TO_VL_MAP0r_PSLL0_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   3579             psll_to_vl_map[curr_vl] = curr_psll;
   3580             curr_psll++;
   3581         }
   3582         if (num_psll_per_phyl > 1) {
   3583             curr_vl = RX_X4_PSLL_TO_VL_MAP0r_PSLL1_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   3584             psll_to_vl_map[curr_vl] = curr_psll;
   3585             curr_psll++;
   3586         }
   3587         if (num_psll_per_phyl > 2) {
   3588             curr_vl = RX_X4_PSLL_TO_VL_MAP0r_PSLL2_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   3589             psll_to_vl_map[curr_vl] = curr_psll;
   3590             curr_psll++;
   3591         }
   3592         if (num_psll_per_phyl > 3) {
   3593             curr_vl = RX_X4_PSLL_TO_VL_MAP1r_PSLL3_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP1r_reg);
   3594             psll_to_vl_map[curr_vl] = curr_psll;
   3595             curr_psll++;
   3596         }
   3597         if (num_psll_per_phyl > 4) {
   3598             curr_vl = RX_X4_PSLL_TO_VL_MAP1r_PSLL4_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP1r_reg);
   3599             psll_to_vl_map[curr_vl] = curr_psll;
   3600             curr_psll++;
   3601         }
   3602 
   3603   }
   3604 
   3605   for(i=0; i<virtual_lanes; i++) {
   3606     /* pc.this_lane = lane+(i/num_psll_per_phyl);*/
   3607     phy_copy.lane_mask = 0x1 << (start_lane + i/num_psll_per_phyl);
   3608 #if 0
   3609     if(num_lane > 4) {
   3610       /* pc.this_lane = lane+(i/2); */
   3611       phy_copy.lane_mask = 0x1 << (start_lane + i/2);
   3612     }
   3613 #endif
   3614     if (i%num_psll_per_phyl == 0) {
   3615       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS0r(&phy_copy,&RX_X4_SKEW_OFFSS0r_reg));
   3616       PHYMOD_IF_ERR_RETURN(READ_RX_X4_AM_TS_INFO0r(&phy_copy,&RX_X4_AM_TS_INFO0r_reg));
   3617       base_ts_ns = RX_X4_AM_TS_INFO0r_BASE_TS_NS_0f_GET(RX_X4_AM_TS_INFO0r_reg);
   3618       base_ts_subns = RX_X4_AM_TS_INFO0r_BASE_TS_SUB_NS_0f_GET(RX_X4_AM_TS_INFO0r_reg);
   3619       am_slip_cnt = RX_X4_SKEW_OFFSS0r_AM_SLIP_COUNT_0f_GET(RX_X4_SKEW_OFFSS0r_reg);
   3620       am_ts_fclk_adj_val = RX_X4_SKEW_OFFSS0r_AM_TS_FCLK_ADJUST_VALUE_0f_GET(RX_X4_SKEW_OFFSS0r_reg);
   3621       deskew_ts_info_val = RX_X4_SKEW_OFFSS0r_DESKEW_TS_INFO_VALID_0f_GET(RX_X4_SKEW_OFFSS0r_reg);
   3622       if (deskew_ts_info_val == 1) {
   3623         psll_update[i] = ((base_ts_ns << 4) | (base_ts_subns & 0xf)) + ((uint32_t) (((float) fclk_period/65536)*am_ts_fclk_adj_val) << 4) + ((uint32_t) ((float)(am_slip_cnt * bit_ui_val)) << 4);
   3624         if ( psll_update[i] < psll_val_min) psll_val_min = psll_update[i];
   3625         if ( psll_update[i] > psll_val_max) psll_val_max = psll_update[i];
   3626       }
   3627     } else if (i%num_psll_per_phyl == 1) {
   3628       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS1r(&phy_copy,&RX_X4_SKEW_OFFSS1r_reg));
   3629       PHYMOD_IF_ERR_RETURN(READ_RX_X4_AM_TS_INFO1r(&phy_copy,&RX_X4_AM_TS_INFO1r_reg));
   3630       base_ts_ns = RX_X4_AM_TS_INFO1r_BASE_TS_NS_1f_GET(RX_X4_AM_TS_INFO1r_reg);
   3631       base_ts_subns = RX_X4_AM_TS_INFO1r_BASE_TS_SUB_NS_1f_GET(RX_X4_AM_TS_INFO1r_reg);
   3632       am_slip_cnt = RX_X4_SKEW_OFFSS1r_AM_SLIP_COUNT_1f_GET(RX_X4_SKEW_OFFSS1r_reg);
   3633       am_ts_fclk_adj_val = RX_X4_SKEW_OFFSS1r_AM_TS_FCLK_ADJUST_VALUE_1f_GET(RX_X4_SKEW_OFFSS1r_reg);
   3634       deskew_ts_info_val = RX_X4_SKEW_OFFSS1r_DESKEW_TS_INFO_VALID_1f_GET(RX_X4_SKEW_OFFSS1r_reg);
   3635 
   3636       if (deskew_ts_info_val == 1) {
   3637         psll_update[i] = ((base_ts_ns << 4) | (base_ts_subns & 0xf)) + ((uint32_t) (((float) fclk_period/65536)*am_ts_fclk_adj_val) << 4) + ((uint32_t) ((float)(am_slip_cnt * bit_ui_val)) << 4);
   3638         if ( psll_update[i] < psll_val_min) psll_val_min = psll_update[i];
   3639         if ( psll_update[i] > psll_val_max) psll_val_max = psll_update[i];
   3640       }
   3641     } else if (i%num_psll_per_phyl == 2) {
   3642       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS2r(&phy_copy,&RX_X4_SKEW_OFFSS2r_reg));
   3643       PHYMOD_IF_ERR_RETURN(READ_RX_X4_AM_TS_INFO2r(&phy_copy,&RX_X4_AM_TS_INFO2r_reg));
   3644       base_ts_ns = RX_X4_AM_TS_INFO2r_BASE_TS_NS_2f_GET(RX_X4_AM_TS_INFO2r_reg);
   3645       base_ts_subns = RX_X4_AM_TS_INFO2r_BASE_TS_SUB_NS_2f_GET(RX_X4_AM_TS_INFO2r_reg);
   3646       am_slip_cnt = RX_X4_SKEW_OFFSS2r_AM_SLIP_COUNT_2f_GET(RX_X4_SKEW_OFFSS2r_reg);
   3647       am_ts_fclk_adj_val = RX_X4_SKEW_OFFSS2r_AM_TS_FCLK_ADJUST_VALUE_2f_GET(RX_X4_SKEW_OFFSS2r_reg);
   3648       deskew_ts_info_val = RX_X4_SKEW_OFFSS2r_DESKEW_TS_INFO_VALID_2f_GET(RX_X4_SKEW_OFFSS2r_reg);
   3649 
   3650       if (deskew_ts_info_val == 1) {
   3651         psll_update[i] = ((base_ts_ns << 4) | (base_ts_subns & 0xf)) + ((uint32_t) (((float) fclk_period/65536)*am_ts_fclk_adj_val) << 4) + ((uint32_t) ((float)(am_slip_cnt * bit_ui_val)) << 4);
   3652         if ( psll_update[i] < psll_val_min) psll_val_min = psll_update[i];
   3653         if ( psll_update[i] > psll_val_max) psll_val_max = psll_update[i];
   3654       }
   3655     } else if (i%num_psll_per_phyl == 3) {
   3656       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS3r(&phy_copy,&RX_X4_SKEW_OFFSS3r_reg));
   3657       PHYMOD_IF_ERR_RETURN(READ_RX_X4_AM_TS_INFO3r(&phy_copy,&RX_X4_AM_TS_INFO3r_reg));
   3658       base_ts_ns = RX_X4_AM_TS_INFO3r_BASE_TS_NS_3f_GET(RX_X4_AM_TS_INFO3r_reg);
   3659       base_ts_subns = RX_X4_AM_TS_INFO3r_BASE_TS_SUB_NS_3f_GET(RX_X4_AM_TS_INFO3r_reg);
   3660       am_slip_cnt = RX_X4_SKEW_OFFSS3r_AM_SLIP_COUNT_3f_GET(RX_X4_SKEW_OFFSS3r_reg);
   3661       am_ts_fclk_adj_val = RX_X4_SKEW_OFFSS3r_AM_TS_FCLK_ADJUST_VALUE_3f_GET(RX_X4_SKEW_OFFSS3r_reg);
   3662       deskew_ts_info_val = RX_X4_SKEW_OFFSS3r_DESKEW_TS_INFO_VALID_3f_GET(RX_X4_SKEW_OFFSS3r_reg);
   3663 
   3664       if (deskew_ts_info_val == 1) {
   3665         psll_update[i] = ((base_ts_ns << 4) | (base_ts_subns & 0xf)) + ((uint32_t) (((float) fclk_period/65536)*am_ts_fclk_adj_val) << 4) + ((uint32_t) ((float)(am_slip_cnt * bit_ui_val)) << 4);
   3666         if ( psll_update[i] < psll_val_min) psll_val_min = psll_update[i];
   3667         if ( psll_update[i] > psll_val_max) psll_val_max = psll_update[i];
   3668       }
   3669     } else if (i%num_psll_per_phyl == 4) {
   3670       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS4r(&phy_copy,&RX_X4_SKEW_OFFSS4r_reg));
   3671       PHYMOD_IF_ERR_RETURN(READ_RX_X4_AM_TS_INFO4r(&phy_copy,&RX_X4_AM_TS_INFO4r_reg));
   3672       base_ts_ns = RX_X4_AM_TS_INFO4r_BASE_TS_NS_4f_GET(RX_X4_AM_TS_INFO4r_reg);
   3673       base_ts_subns = RX_X4_AM_TS_INFO4r_BASE_TS_SUB_NS_4f_GET(RX_X4_AM_TS_INFO4r_reg);
   3674       am_slip_cnt = RX_X4_SKEW_OFFSS4r_AM_SLIP_COUNT_4f_GET(RX_X4_SKEW_OFFSS4r_reg);
   3675       am_ts_fclk_adj_val = RX_X4_SKEW_OFFSS4r_AM_TS_FCLK_ADJUST_VALUE_4f_GET(RX_X4_SKEW_OFFSS4r_reg);
   3676       deskew_ts_info_val = RX_X4_SKEW_OFFSS4r_DESKEW_TS_INFO_VALID_4f_GET(RX_X4_SKEW_OFFSS4r_reg);
   3677 
   3678       if (deskew_ts_info_val == 1) {
   3679         psll_update[i] = ((base_ts_ns << 4) | (base_ts_subns & 0xf)) + ((uint32_t) (((float) fclk_period/65536)*am_ts_fclk_adj_val) << 4) + ((uint32_t) ((float)(am_slip_cnt * bit_ui_val)) << 4);
   3680         if ( psll_update[i] < psll_val_min) psll_val_min = psll_update[i];
   3681         if ( psll_update[i] > psll_val_max) psll_val_max = psll_update[i];
   3682       }
   3683     }
   3684   }
   3685   /* Normalize to earliest */
   3686   if ((psll_val_max - psll_val_min) > 0x1000) {
   3687     /* Sometimes the psll_update could rollover. In case of rollover all the values need to
   3688      * equalized meaning account for rollover and then normalize it as usual. */
   3689     for(i=0; i<virtual_lanes; i++) {
   3690         /***
   3691         printf("tbhmod_pcs_mod_rx_1588_tbl :correction: psll_update[%d] : %8x : psll_val_min : %8x : diff : %8x\n",
   3692         i, psll_update[i], psll_val_min, psll_update[i]-psll_val_min);
   3693  */
   3694         if((psll_val_max - psll_update[i]) > 0x01000) psll_update[i] |= 0x10000 ;
   3695         if (psll_update[i] < psll_roval_min)  psll_roval_min = psll_update[i];
   3696         if (psll_update[i] > psll_roval_max)  psll_roval_max = psll_update[i];
   3697     }
   3698     for(i=0; i<virtual_lanes; i++) {
   3699         psll_val_correction[i] = psll_update[i]-psll_roval_min;
   3700     }
   3701   } else {
   3702      for(i=0; i<virtual_lanes; i++) {
   3703         psll_val_correction[i] = psll_update[i]-psll_val_min;
   3704      }
   3705   }
   3706 
   3707   /* Normalize to latest */
   3708   /****
   3709   for(i=0; i<virtual_lanes; i++) {
   3710       printf("tbhmod_pcs_mod_rx_1588_tbl :correction: psll_val_correction[%d] : %x : psll_val_max : %x : diff : %x\n",
   3711   i, psll_val_correction[i], psll_val_max, psll_val_correction[i]+psll_val_max);
   3712       psll_val_correction[i] = psll_val_correction[i]+psll_val_max;
   3713   }
   3714  */
   3715 
   3716   for(i=0; i<tbl_ln; i++) {
   3717     curr_vl = table[i] >> 15;
   3718     table_time = table[i] & 0x7fff;
   3719     if((table_time >> 14)&1) {
   3720       table_time = (table_time | 0xffff8000); /* sign ext */
   3721     }
   3722     curr_psll = psll_to_vl_map[curr_vl];
   3723     vlane_val_correction = psll_val_correction[curr_psll];
   3724 
   3725     if ((vlane_val_correction >> 14)&1) {
   3726         table_time = table_time +  (vlane_val_correction & 0x7fff);
   3727     } else {
   3728         table_time = table_time -  (vlane_val_correction & 0x7fff);
   3729     }
   3730 
   3731     table[i] = (table[i] & 0xf8000) | (table_time & 0x7fff); /* bit 19-bit 15 VL bit 14-bit 0 time */
   3732   }
   3733 #endif /* SERDES_API_FLOAT_POINT */
   3734   return PHYMOD_E_NONE;
   3735 }
   3736 
   3737 int tbhmod_pcs_ts_deskew_valid(PHYMOD_ST* pc, int bit_mux_mode, int *rx_ts_deskew_valid) {
   3738   int start_lane, num_lane;
   3739   int i, virtual_lanes = 0, num_psll_per_phyl = 0;
   3740   int ts_deskew_valid;
   3741   PHYMOD_ST phy_copy;
   3742 
   3743   RX_X4_SKEW_OFFSS0r_t RX_X4_SKEW_OFFSS0r_reg;
   3744   RX_X4_SKEW_OFFSS1r_t RX_X4_SKEW_OFFSS1r_reg;
   3745   RX_X4_SKEW_OFFSS2r_t RX_X4_SKEW_OFFSS2r_reg;
   3746   RX_X4_SKEW_OFFSS3r_t RX_X4_SKEW_OFFSS3r_reg;
   3747   RX_X4_SKEW_OFFSS4r_t RX_X4_SKEW_OFFSS4r_reg;
   3748 
   3749   PHYMOD_IF_ERR_RETURN
   3750       (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   3751   PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   3752 
   3753   PHYMOD_IF_ERR_RETURN(
   3754       _tbhmod_virtual_lane_count_get(bit_mux_mode, num_lane, &virtual_lanes, &num_psll_per_phyl));
   3755 
   3756   *rx_ts_deskew_valid = 1;
   3757   if(virtual_lanes == 1) { return PHYMOD_E_NONE; }
   3758 
   3759   for(i=0; i<virtual_lanes; i++) {
   3760     /*pc.this_lane = lane+(i%physical_lanes); */
   3761     phy_copy.lane_mask = 0x1 << (start_lane + i % num_lane);
   3762 
   3763     if((i / num_lane) == 0) {
   3764       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS0r(&phy_copy,&RX_X4_SKEW_OFFSS0r_reg));
   3765       ts_deskew_valid = RX_X4_SKEW_OFFSS0r_DESKEW_TS_INFO_VALID_0f_GET(RX_X4_SKEW_OFFSS0r_reg);
   3766       if(ts_deskew_valid != 1) { *rx_ts_deskew_valid = 0; return PHYMOD_E_NONE; }
   3767     } else if((i / num_lane) == 1) {
   3768       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS1r(&phy_copy,&RX_X4_SKEW_OFFSS1r_reg));
   3769       ts_deskew_valid = RX_X4_SKEW_OFFSS1r_DESKEW_TS_INFO_VALID_1f_GET(RX_X4_SKEW_OFFSS1r_reg);
   3770       if(ts_deskew_valid != 1) { *rx_ts_deskew_valid = 0; return PHYMOD_E_NONE; }
   3771     } else if((i / num_lane) == 2) {
   3772       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS2r(&phy_copy,&RX_X4_SKEW_OFFSS2r_reg));
   3773       ts_deskew_valid = RX_X4_SKEW_OFFSS2r_DESKEW_TS_INFO_VALID_2f_GET(RX_X4_SKEW_OFFSS2r_reg);
   3774       if(ts_deskew_valid != 1) { *rx_ts_deskew_valid = 0; return PHYMOD_E_NONE; }
   3775     } else if((i / num_lane) == 3) {
   3776       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS3r(&phy_copy,&RX_X4_SKEW_OFFSS3r_reg));
   3777       ts_deskew_valid = RX_X4_SKEW_OFFSS3r_DESKEW_TS_INFO_VALID_3f_GET(RX_X4_SKEW_OFFSS3r_reg);
   3778       if(ts_deskew_valid != 1) { *rx_ts_deskew_valid = 0; return PHYMOD_E_NONE; }
   3779     } else if((i / num_lane) == 4) {
   3780       PHYMOD_IF_ERR_RETURN(READ_RX_X4_SKEW_OFFSS4r(&phy_copy,&RX_X4_SKEW_OFFSS4r_reg));
   3781       ts_deskew_valid = RX_X4_SKEW_OFFSS4r_DESKEW_TS_INFO_VALID_4f_GET(RX_X4_SKEW_OFFSS4r_reg);
   3782       if(ts_deskew_valid != 1) { *rx_ts_deskew_valid = 0; return PHYMOD_E_NONE; }
   3783     }
   3784   }
   3785 
   3786   return PHYMOD_E_NONE;
   3787 }
   3788 
   3789 /*!
   3790  *  @brief tbhmod_pack_spd_id_tbl_entry
   3791 @param entry the entry structure to be packed into a uint32_t array
   3792 @param packed_entry the uint32_t array containing the data
   3793 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3794 @details Packs a spd_id_tbl_entry_t into a uint32_t array*/
   3795 int tbhmod_pack_spd_id_tbl_entry (spd_id_tbl_entry_t *entry, uint32_t *packed_entry)
   3796 {
   3797     spd_ctrl_pack_spd_id_tbl_entry(entry, packed_entry);
   3798     return PHYMOD_E_NONE;
   3799 }
   3800 
   3801 /*!
   3802  *  @brief tbhmod_unpack_spd_id_tbl_entry
   3803 @param packed_entry the uint32_t array containing the data
   3804 @param entry the entry structure the data will be unpacked into
   3805 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3806 @details Unpacks a spd_id_tbl_entry_t into a uint32_t array*/
   3807 int tbhmod_unpack_spd_id_tbl_entry (uint32_t *packed_entry, spd_id_tbl_entry_t *entry)
   3808 {
   3809     spd_ctrl_unpack_spd_id_tbl_entry(packed_entry, entry);
   3810     return PHYMOD_E_NONE;
   3811 }
   3812 
   3813 /*!
   3814  *  @brief tbhmod_pack_am_tbl_entry
   3815 @param entry the entry structure to be packed into a uint32_t array
   3816 @param packed_entry the uint32_t array containing the data
   3817 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3818 @details Packs a am_tbl_entry_t into a uint32_t array*/
   3819 int tbhmod_pack_am_tbl_entry (am_tbl_entry_t *entry, uint32_t *packed_entry)
   3820 {
   3821     spd_ctrl_pack_am_tbl_entry(entry, packed_entry);
   3822     return PHYMOD_E_NONE;
   3823 }
   3824 
   3825 
   3826 /*!
   3827  *  @brief tbhmod_unpack_am_tbl_entry
   3828 @param packed_entry the uint32_t array containing the data
   3829 @param entry the entry structure the data will be unpacked into
   3830 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3831 @details Unpacks a am_tbl_entry_t into a uint32_t array*/
   3832 int tbhmod_unpack_am_tbl_entry (uint32_t *packed_entry, am_tbl_entry_t *entry)
   3833 {
   3834     spd_ctrl_unpack_am_tbl_entry(packed_entry, entry);
   3835     return PHYMOD_E_NONE;
   3836 }
   3837 
   3838 /*!
   3839  *  @brief tbhmod_pack_um_tbl_entry
   3840 @param entry the entry structure to be packed into a uint32_t array
   3841 @param packed_entry the uint32_t array containing the data
   3842 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3843 @details Packs a um_tbl_entry_t into a uint32_t array*/
   3844 int tbhmod_pack_um_tbl_entry (um_tbl_entry_t *entry, uint32_t *packed_entry)
   3845 {
   3846     spd_ctrl_pack_um_tbl_entry(entry, packed_entry);
   3847     return PHYMOD_E_NONE;
   3848 }
   3849 
   3850 /*!
   3851  *  @brief tbhmod_unpack_um_tbl_entry
   3852 @param packed_entry the uint32_t array containing the data
   3853 @param entry the entry structure the data will be unpacked into
   3854 @returns PHYMOD_E_NONE if no errors. PHYMOD_EERROR else.
   3855 @details Unpacks a um_tbl_entry_t into a uint32_t array*/
   3856 int tbhmod_unpack_um_tbl_entry (uint32_t *packed_entry, um_tbl_entry_t *entry)
   3857 {
   3858     spd_ctrl_unpack_um_tbl_entry(packed_entry, entry);
   3859     return PHYMOD_E_NONE;
   3860 }
   3861 
   3862 /**
   3863  * @brief   Select the ILKN path and bypass TSCF PCS
   3864  * @param   pc handle to current TSCBH context (#tbhmod_st)
   3865  * @returns The value PHYMOD_E_NONE upon successful completion
   3866  * @details This will enable ILKN path. PCS is set to bypass to relinquish PMD
   3867  * control. Expect PMD to be programmed elsewhere.
   3868  */
   3869 int tbhmod_init_pcs_ilkn(PHYMOD_ST* pc)              /* INIT_PCS_ILKN */
   3870 {
   3871   ILKN_CTL0r_t ILKN_CONTROL0r_reg;
   3872 
   3873   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3874 
   3875   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
   3876   ILKN_CTL0r_SOFT_RST_RXf_SET(ILKN_CONTROL0r_reg, 0);
   3877   ILKN_CTL0r_SOFT_RST_TXf_SET(ILKN_CONTROL0r_reg, 0);
   3878   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
   3879 
   3880   
   3881   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
   3882   ILKN_CTL0r_CREDIT_ENf_SET(ILKN_CONTROL0r_reg, 1);
   3883   ILKN_CTL0r_ILKN_SELf_SET(ILKN_CONTROL0r_reg, 1);
   3884   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
   3885 
   3886   return PHYMOD_E_NONE;
   3887 }
   3888 
   3889 /**
   3890  * @brief   Select the ILKN path and bypass TSCF PCS
   3891  * @param   pc handle to current TSCBH context (#tbhmod_st)
   3892  * @returns The value PHYMOD_E_NONE upon successful completion
   3893  * @details This will enable ILKN path. PCS is set to bypass to relinquish PMD
   3894  * control. Expect PMD to be programmed elsewhere.
   3895  */
   3896 int tbhmod_pcs_ilkn_enable(PHYMOD_ST* pc, int enable)
   3897 {
   3898   ILKN_CTL0r_t ILKN_CONTROL0r_reg;
   3899   PMD_X4_OVRRr_t pmd_x4_override;
   3900 
   3901   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3902 
   3903   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
   3904   ILKN_CTL0r_SOFT_RST_RXf_SET(ILKN_CONTROL0r_reg, 0);
   3905   ILKN_CTL0r_SOFT_RST_TXf_SET(ILKN_CONTROL0r_reg, 0);
   3906   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
   3907 
   3908   
   3909   ILKN_CTL0r_CLR(ILKN_CONTROL0r_reg);
   3910   ILKN_CTL0r_CREDIT_ENf_SET(ILKN_CONTROL0r_reg, enable);
   3911   ILKN_CTL0r_ILKN_SELf_SET(ILKN_CONTROL0r_reg, enable);
   3912   PHYMOD_IF_ERR_RETURN(MODIFY_ILKN_CTL0r(pc, ILKN_CONTROL0r_reg));
   3913 
   3914   /* if ILKN enable, set the PMD ln dp reset override bit as well */
   3915   PMD_X4_OVRRr_CLR(pmd_x4_override);
   3916   PMD_X4_OVRRr_LN_DP_H_RSTB_OENf_SET(pmd_x4_override, enable);
   3917   PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override));
   3918 
   3919   return PHYMOD_E_NONE;
   3920 }
   3921 
   3922 
   3923 /**
   3924  * @brief  Get the plldiv from lookup table
   3925  * @param  pc handle to current TSCBH context (#PHYMOD_ST)
   3926  * @param  mapped_speed_id: speed entry index in sw_speed_table
   3927  * @param  plldiv  Receives PLL Divider value
   3928  * @returns The value PHYMOD_E_NONE upon successful completion
   3929  * @details Get the plldiv from lookup table as a function of the speed.
   3930  */
   3931 
   3932 int tbhmod_plldiv_lkup_get(PHYMOD_ST* pc, int mapped_speed_id, tbhmod_refclk_t refclk,  uint32_t *plldiv)
   3933 {
   3934   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3935   if (refclk == TBHMOD_REF_CLK_312P5MHZ) {
   3936     *plldiv = tscbh_sc_pmd_entry_312M_ref[mapped_speed_id].pll_mode;
   3937   } else {
   3938     *plldiv = tscbh_sc_pmd_entry[mapped_speed_id].pll_mode;
   3939   }
   3940 
   3941   return PHYMOD_E_NONE;
   3942 
   3943 }
   3944 
   3945 
   3946 /**
   3947  * @brief   Check if ILKN is set
   3948  * @param   pc handle to current TSCBH context (#PHYMOD_ST), ilkn_set status
   3949  * @returns The value PHYMOD_E_NONE upon successful completion
   3950  * @details Check if ILKN is set, ilkn_set = 1 if it is set.
   3951  */
   3952 int tbhmod_pcs_ilkn_chk(PHYMOD_ST* pc, int *ilkn_set)              /* INIT_PCS_ILKN */
   3953 {
   3954   ILKN_CTL0r_t ILKN_CONTROL0r_reg;
   3955 
   3956   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3957 
   3958   PHYMOD_IF_ERR_RETURN(READ_ILKN_CTL0r(pc, &ILKN_CONTROL0r_reg));
   3959   *ilkn_set = ILKN_CTL0r_ILKN_SELf_GET(ILKN_CONTROL0r_reg);
   3960 
   3961   return PHYMOD_E_NONE;
   3962 }
   3963 
   3964 int tbhmod_refclk_set(PHYMOD_ST* pc, tbhmod_refclk_t ref_clk)
   3965 {
   3966   MAIN0_SETUPr_t MAIN0_SETUPr_reg;
   3967 
   3968   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3969 
   3970   pc->lane_mask = 0x1 << 0;
   3971   PHYMOD_IF_ERR_RETURN(READ_MAIN0_SETUPr(pc, &MAIN0_SETUPr_reg));
   3972   MAIN0_SETUPr_REFCLK_SELf_SET(MAIN0_SETUPr_reg, ref_clk);
   3973   PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUPr(pc, MAIN0_SETUPr_reg));
   3974 
   3975   pc->lane_mask = 0x1 << 4;
   3976   PHYMOD_IF_ERR_RETURN(READ_MAIN0_SETUPr(pc, &MAIN0_SETUPr_reg));
   3977   MAIN0_SETUPr_REFCLK_SELf_SET(MAIN0_SETUPr_reg, ref_clk);
   3978   PHYMOD_IF_ERR_RETURN(MODIFY_MAIN0_SETUPr(pc, MAIN0_SETUPr_reg));
   3979 
   3980   return PHYMOD_E_NONE;
   3981 }
   3982 
   3983 int tbhmod_refclk_get(PHYMOD_ST* pc, tbhmod_refclk_t* ref_clk)
   3984 {
   3985   MAIN0_SETUPr_t MAIN0_SETUPr_reg;
   3986 
   3987   TBHMOD_DBG_IN_FUNC_INFO(pc);
   3988 
   3989   PHYMOD_IF_ERR_RETURN(READ_MAIN0_SETUPr(pc, &MAIN0_SETUPr_reg));
   3990   *ref_clk = MAIN0_SETUPr_REFCLK_SELf_GET(MAIN0_SETUPr_reg);
   3991 
   3992   return PHYMOD_E_NONE;
   3993 }
   3994 
   3995 /**
   3996  * @brief   Set Per lane OS mode set in PMD
   3997  * @param   pc handle to current TSCBH context (#PHYMOD_ST)
   3998  * @param   mapped_speed_id: speed entry index in sw_speed_table
   3999  * @param   os_mode over sample rate.
   4000  * @returns The value PHYMOD_E_NONE upon successful completion
   4001  * @details Per Port PMD Init
   4002  */
   4003 int tbhmod_pmd_osmode_set(PHYMOD_ST* pc, int mapped_speed_id, tbhmod_refclk_t refclk)
   4004 {
   4005   RXTXCOM_OSR_MODE_CTLr_t reg_osr_mode;
   4006   int os_mode;
   4007 
   4008   TBHMOD_DBG_IN_FUNC_INFO(pc);
   4009   RXTXCOM_OSR_MODE_CTLr_CLR(reg_osr_mode);
   4010 
   4011   /* 0=OS_MODE_1;    1=OS_MODE_2;
   4012    * 2=OS_MODE_4;    4=OS_MODE_21p25;
   4013    * 8=OS MODE_16p5; 12=OS_MODE_20p625;  */
   4014 
   4015   if (refclk == TBHMOD_REF_CLK_312P5MHZ) {
   4016       os_mode =  tscbh_sc_pmd_entry_312M_ref[mapped_speed_id].t_pma_os_mode;
   4017   } else {
   4018       os_mode =  tscbh_sc_pmd_entry[mapped_speed_id].t_pma_os_mode;
   4019   }
   4020 
   4021   RXTXCOM_OSR_MODE_CTLr_OSR_MODE_FRCf_SET(reg_osr_mode, 1);
   4022   RXTXCOM_OSR_MODE_CTLr_OSR_MODE_FRC_VALf_SET(reg_osr_mode, os_mode);
   4023 
   4024   PHYMOD_IF_ERR_RETURN
   4025      (MODIFY_RXTXCOM_OSR_MODE_CTLr(pc, reg_osr_mode));
   4026 
   4027   return PHYMOD_E_NONE;
   4028 }
   4029 
   4030 
   4031 int tbhmod_fec_correctable_counter_get(PHYMOD_ST* pc, uint32_t* count)
   4032 {
   4033     int start_lane, num_lane;
   4034     RX_X4_FEC_CORR_CTR0r_t lower_reg;
   4035     RX_X4_FEC_CORR_CTR1r_t upper_reg;
   4036 
   4037     PHYMOD_IF_ERR_RETURN
   4038         (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   4039 
   4040     if (num_lane != 8) {
   4041         pc->lane_mask = 1 << start_lane;
   4042         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR0r(pc, &lower_reg));
   4043         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR1r(pc, &upper_reg));
   4044         *count = RX_X4_FEC_CORR_CTR1r_RS_FEC_FEC_CORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4045                  RX_X4_FEC_CORR_CTR0r_RS_FEC_FEC_CORR_CW_CNTR_LOWERf_GET(lower_reg);
   4046     } else {
   4047         pc->lane_mask = 0x1;
   4048         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR0r(pc, &lower_reg));
   4049         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR1r(pc, &upper_reg));
   4050         *count = RX_X4_FEC_CORR_CTR1r_RS_FEC_FEC_CORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4051                  RX_X4_FEC_CORR_CTR0r_RS_FEC_FEC_CORR_CW_CNTR_LOWERf_GET(lower_reg);
   4052 
   4053         pc->lane_mask = 0x10;
   4054         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR0r(pc, &lower_reg));
   4055         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_CORR_CTR1r(pc, &upper_reg));
   4056         *count += RX_X4_FEC_CORR_CTR1r_RS_FEC_FEC_CORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4057                  RX_X4_FEC_CORR_CTR0r_RS_FEC_FEC_CORR_CW_CNTR_LOWERf_GET(lower_reg);
   4058     }
   4059 
   4060     return PHYMOD_E_NONE;
   4061 }
   4062 
   4063 int tbhmod_fec_uncorrectable_counter_get(PHYMOD_ST* pc, uint32_t* count)
   4064 {
   4065     int start_lane, num_lane;
   4066     RX_X4_FEC_UNCORR_CTR0r_t lower_reg;
   4067     RX_X4_FEC_UNCORR_CTR1r_t upper_reg;
   4068 
   4069     PHYMOD_IF_ERR_RETURN
   4070         (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   4071 
   4072     if (num_lane != 8) {
   4073         pc->lane_mask = 1 << start_lane;
   4074         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR0r(pc, &lower_reg));
   4075         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR1r(pc, &upper_reg));
   4076         *count = RX_X4_FEC_UNCORR_CTR1r_RS_FEC_FEC_UNCORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4077                  RX_X4_FEC_UNCORR_CTR0r_RS_FEC_FEC_UNCORR_CW_CNTR_LOWERf_GET(lower_reg);
   4078     } else {
   4079         pc->lane_mask = 0x1;
   4080         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR0r(pc, &lower_reg));
   4081         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR1r(pc, &upper_reg));
   4082         *count = RX_X4_FEC_UNCORR_CTR1r_RS_FEC_FEC_UNCORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4083                  RX_X4_FEC_UNCORR_CTR0r_RS_FEC_FEC_UNCORR_CW_CNTR_LOWERf_GET(lower_reg);
   4084 
   4085         pc->lane_mask = 0x10;
   4086         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR0r(pc, &lower_reg));
   4087         PHYMOD_IF_ERR_RETURN(READ_RX_X4_FEC_UNCORR_CTR1r(pc, &upper_reg));
   4088         *count += RX_X4_FEC_UNCORR_CTR1r_RS_FEC_FEC_UNCORR_CW_CNTR_UPPERf_GET(upper_reg) << 16 |
   4089                  RX_X4_FEC_UNCORR_CTR0r_RS_FEC_FEC_UNCORR_CW_CNTR_LOWERf_GET(lower_reg);
   4090     }
   4091 
   4092     return PHYMOD_E_NONE;
   4093 }
   4094 
   4095 /*
   4096  * On TSCBH, SYNCE_X4 programming is per logical lane based.
   4097  */
   4098 int tbhmod_synce_mode_set(PHYMOD_ST* pc, int stage0_mode, int stage1_mode)
   4099 {
   4100     INTEGER_DIVr_t INTEGER_DIVr_reg;
   4101 
   4102     INTEGER_DIVr_CLR(INTEGER_DIVr_reg);
   4103     INTEGER_DIVr_SYNCE_MODE_STAGE0f_SET(INTEGER_DIVr_reg, stage0_mode);
   4104     INTEGER_DIVr_SYNCE_MODE_STAGE1f_SET(INTEGER_DIVr_reg, stage1_mode);
   4105 
   4106     PHYMOD_IF_ERR_RETURN(MODIFY_INTEGER_DIVr(pc, INTEGER_DIVr_reg));
   4107 
   4108     return PHYMOD_E_NONE;
   4109 }
   4110 
   4111 int tbhmod_synce_mode_get(PHYMOD_ST* pc, int* stage0_mode, int* stage1_mode)
   4112 {
   4113     INTEGER_DIVr_t INTEGER_DIVr_reg;
   4114 
   4115     INTEGER_DIVr_CLR(INTEGER_DIVr_reg);
   4116     PHYMOD_IF_ERR_RETURN(READ_INTEGER_DIVr(pc, &INTEGER_DIVr_reg));
   4117     *stage0_mode = INTEGER_DIVr_SYNCE_MODE_STAGE0f_GET(INTEGER_DIVr_reg);
   4118     *stage1_mode = INTEGER_DIVr_SYNCE_MODE_STAGE1f_GET(INTEGER_DIVr_reg);
   4119 
   4120     return PHYMOD_E_NONE;
   4121 }
   4122 
   4123 int tbhmod_synce_clk_ctrl_set(PHYMOD_ST* pc, uint32_t val)
   4124 {
   4125     FRACTIONAL_DIVr_t FRACTIONAL_DIVr_reg;
   4126 
   4127     FRACTIONAL_DIVr_CLR(FRACTIONAL_DIVr_reg);
   4128     FRACTIONAL_DIVr_SET(FRACTIONAL_DIVr_reg, val);
   4129     PHYMOD_IF_ERR_RETURN(MODIFY_FRACTIONAL_DIVr(pc, FRACTIONAL_DIVr_reg));
   4130 
   4131     return PHYMOD_E_NONE;
   4132 }
   4133 
   4134 int tbhmod_synce_clk_ctrl_get(PHYMOD_ST* pc, uint32_t* val)
   4135 {
   4136     FRACTIONAL_DIVr_t FRACTIONAL_DIVr_reg;
   4137 
   4138     FRACTIONAL_DIVr_CLR(FRACTIONAL_DIVr_reg);
   4139     PHYMOD_IF_ERR_RETURN(READ_FRACTIONAL_DIVr(pc, &FRACTIONAL_DIVr_reg));
   4140 
   4141     *val = FRACTIONAL_DIVr_GET(FRACTIONAL_DIVr_reg);
   4142 
   4143     return PHYMOD_E_NONE;
   4144 }
   4145 
   4146 int tbhmod_1588_tx_info_get(PHYMOD_ST* pc, tbhmod_ts_tx_info_t* ts_tx_info)
   4147 {
   4148     TX_X4_TX_1588_TIMESTAMP_STSr_t reg_tx_1588_timestamp_sts;
   4149     TX_X4_TX_1588_TIMESTAMP_HIr_t reg_tx_1588_timestamp_hi;
   4150     TX_X4_TX_1588_TIMESTAMP_MIDr_t reg_tx_1588_timestamp_mid;
   4151     TX_X4_TX_1588_TIMESTAMP_LOr_t reg_tx_1588_timestamp_lo;
   4152     TX_X4_TX_TS_SEQ_IDr_t reg_tx_ts_seq_id;
   4153     uint16_t ts_entry_valid;
   4154 
   4155     TX_X4_TX_1588_TIMESTAMP_STSr_CLR(reg_tx_1588_timestamp_sts);
   4156     TX_X4_TX_1588_TIMESTAMP_HIr_CLR(reg_tx_1588_timestamp_hi);
   4157     TX_X4_TX_1588_TIMESTAMP_LOr_CLR(reg_tx_1588_timestamp_lo);
   4158     TX_X4_TX_TS_SEQ_IDr_CLR(reg_tx_ts_seq_id);
   4159 
   4160     PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_STSr(pc, &reg_tx_1588_timestamp_sts));
   4161     ts_entry_valid = TX_X4_TX_1588_TIMESTAMP_STSr_TS_ENTRY_VALIDf_GET(reg_tx_1588_timestamp_sts);
   4162     if (ts_entry_valid == 0) {
   4163         return PHYMOD_E_EMPTY;
   4164     }
   4165 
   4166     PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_HIr(pc, &reg_tx_1588_timestamp_hi));
   4167     PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_MIDr(pc, &reg_tx_1588_timestamp_mid));
   4168     PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_LOr(pc, &reg_tx_1588_timestamp_lo));
   4169     PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_TS_SEQ_IDr(pc, &reg_tx_ts_seq_id));
   4170 
   4171     ts_tx_info->ts_val_hi = TX_X4_TX_1588_TIMESTAMP_HIr_TS_IN_NS_HIf_GET(reg_tx_1588_timestamp_hi);
   4172     ts_tx_info->ts_val_mid = TX_X4_TX_1588_TIMESTAMP_MIDr_TS_IN_NS_MIDf_GET(reg_tx_1588_timestamp_mid);
   4173     ts_tx_info->ts_val_lo = TX_X4_TX_1588_TIMESTAMP_LOr_TS_IN_NS_LOf_GET(reg_tx_1588_timestamp_lo);
   4174     ts_tx_info->ts_seq_id = TX_X4_TX_TS_SEQ_IDr_TS_SEQIDf_GET(reg_tx_ts_seq_id);
   4175     ts_tx_info->ts_sub_nanosec = TX_X4_TX_1588_TIMESTAMP_STSr_TS_SUB_NSf_GET(reg_tx_1588_timestamp_sts);
   4176 
   4177     return PHYMOD_E_NONE;
   4178 }
   4179 
   4180 #if 0
   4181 int tbhmod_pmd_lane_override_enable(PHYMOD_ST* pc, uint32_t enable)
   4182 {
   4183       PMD_X4_OVRRr_t pmd_x4_override;
   4184       PMD_X4_OVRRr_CLR(pmd_x4_override);
   4185       PMD_X4_OVRRr_LN_DP_H_RSTB_OENf_SET(pmd_x4_override, enable);
   4186       PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override));
   4187     return PHYMOD_E_NONE;
   4188 }
   4189 #endif
   4190 
   4191 int tbhmod_pmd_rx_lock_override_enable(PHYMOD_ST* pc, uint32_t enable)
   4192 {
   4193       PMD_X4_OVRRr_t pmd_x4_override;
   4194       PMD_X4_OVRRr_CLR(pmd_x4_override);
   4195       BCMI_TSCBH_XGXS_PMD_X4_OVRRr_RX_LOCK_OVRDf_SET(pmd_x4_override, enable);
   4196       PHYMOD_IF_ERR_RETURN(MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override));
   4197     return PHYMOD_E_NONE;
   4198 }
   4199 
   4200 int tbhmod_polling_for_sc_done(PHYMOD_ST* pc)
   4201 {
   4202     int cnt;
   4203     uint16_t sw_spd_chg_chk;
   4204     SC_X4_STSr_t SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg;
   4205 
   4206     cnt = 0;
   4207 
   4208     SC_X4_STSr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg);
   4209     /* wait for 5 second for the status bit to set */
   4210     while (cnt <= 5000) {
   4211         PHYMOD_IF_ERR_RETURN(READ_SC_X4_STSr(pc, &SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg));
   4212         cnt = cnt + 1;
   4213         sw_spd_chg_chk = SC_X4_STSr_SW_SPEED_CHANGE_DONEf_GET(SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg);
   4214 
   4215         if(sw_spd_chg_chk) {
   4216             break;
   4217         } else {
   4218             if(cnt == 5000) {
   4219                 PHYMOD_DEBUG_ERROR(("WARNING :: speed change done bit is NOT set \n"));
   4220                 break;
   4221             }
   4222         }
   4223         PHYMOD_USLEEP(1000);
   4224     }
   4225     return PHYMOD_E_NONE;
   4226 }
   4227 
   4228 int tbhmod_read_sc_done(PHYMOD_ST* pc)
   4229 {
   4230     SC_X4_STSr_t SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg;
   4231 
   4232     SC_X4_STSr_CLR(SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg);
   4233     PHYMOD_IF_ERR_RETURN(READ_SC_X4_STSr(pc, &SC_X4_CONTROL_SC_X4_CONTROL_STATUSr_reg));
   4234     return PHYMOD_E_NONE;
   4235 }
   4236 
   4237 
   4238 int tbhmod_read_sc_fsm_status(PHYMOD_ST* pc)
   4239 {
   4240 
   4241     SC_X4_DBGr_t debug_reg;
   4242 
   4243     SC_X4_DBGr_CLR(debug_reg);
   4244     PHYMOD_IF_ERR_RETURN(READ_SC_X4_DBGr(pc, &debug_reg));
   4245     return PHYMOD_E_NONE;
   4246 }
   4247 
   4248 int tbhmod_resolved_port_mode_get(PHYMOD_ST* pc, uint32_t* port_mode)
   4249 {
   4250     int start_lane, num_lane;
   4251     SC_X1_STSr_t reg_val;
   4252 
   4253     PHYMOD_IF_ERR_RETURN
   4254         (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   4255 
   4256     if (start_lane < 4) {
   4257         pc->lane_mask = 0x1 << 0;
   4258     } else {
   4259         pc->lane_mask = 0x1 << 4;
   4260     }
   4261 
   4262     PHYMOD_IF_ERR_RETURN(READ_SC_X1_STSr(pc, &reg_val));
   4263     *port_mode = (uint32_t) SC_X1_STSr_RESOLVED_PORT_MODEf_GET(reg_val);
   4264 
   4265     return PHYMOD_E_NONE;
   4266 }
   4267 
   4268 /* This function will read ECC status registers and return 1b and 2b error status.
   4269  * All the status registers are CR registers, so the status bit will be cleared within
   4270  * this function.
   4271  */
   4272 int tbhmod_intr_status_get(PHYMOD_ST* pc, tbhmod_intr_status_t* intr_status)
   4273 {
   4274     RX_X1_ECC_STS_BASE_R_FECr_t         RX_X1_ECC_STS_BASE_R_FECr_reg;
   4275     RX_X1_ECC_STS_RSFEC_RBUF_MPPr_t     RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg;
   4276     RX_X1_ECC_STS_RSFEC_RS400G_MPPr_t   RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg;
   4277     RX_X1_ECC_STS_DESKEWr_t             RX_X1_ECC_STS_DESKEWr_reg;
   4278     RX_X1_ECC_STS_SPD_TBLr_t            RX_X1_ECC_STS_SPD_TBLr_reg;
   4279     RX_X1_ECC_STS_AM_TBLr_t             RX_X1_ECC_STS_AM_TBLr_reg;
   4280     RX_X1_ECC_STS_UM_TBLr_t             RX_X1_ECC_STS_UM_TBLr_reg;
   4281     RX_X1_ECC_STS_TX_1588_MPPr_t        RX_X1_ECC_STS_TX_1588_MPPr_reg;
   4282     RX_X1_ECC_STS_TX_1588_400Gr_t       RX_X1_ECC_STS_TX_1588_400Gr_reg;
   4283     RX_X1_ECC_STS_RX_1588_MPPr_t        RX_X1_ECC_STS_RX_1588_MPPr_reg;
   4284     RX_X1_ECC_STS_RX_1588_400Gr_t       RX_X1_ECC_STS_RX_1588_400Gr_reg;
   4285 
   4286     pc->lane_mask = 0x1;
   4287     switch (intr_status->type) {
   4288         case phymodIntrEccRx1588400g:
   4289             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RX_1588_400Gr(pc, &RX_X1_ECC_STS_RX_1588_400Gr_reg));
   4290             intr_status->is_2b_err = RX_X1_ECC_STS_RX_1588_400Gr_TWO_BIT_ERR_EVENT_RX_1588_400Gf_GET(RX_X1_ECC_STS_RX_1588_400Gr_reg);
   4291             intr_status->is_1b_err = RX_X1_ECC_STS_RX_1588_400Gr_ONE_BIT_ERR_EVENT_RX_1588_400Gf_GET(RX_X1_ECC_STS_RX_1588_400Gr_reg);
   4292             break;
   4293         case phymodIntrEccRx1588Mpp1:
   4294             pc->lane_mask = 0x1 << 4;
   4295             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RX_1588_MPPr(pc, &RX_X1_ECC_STS_RX_1588_MPPr_reg));
   4296             intr_status->is_2b_err = RX_X1_ECC_STS_RX_1588_MPPr_TWO_BIT_ERR_EVENT_RX_1588_MPPf_GET(RX_X1_ECC_STS_RX_1588_MPPr_reg);
   4297             intr_status->is_1b_err = RX_X1_ECC_STS_RX_1588_MPPr_ONE_BIT_ERR_EVENT_RX_1588_MPPf_GET(RX_X1_ECC_STS_RX_1588_MPPr_reg);
   4298             break;
   4299         case phymodIntrEccRx1588Mpp0:
   4300             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RX_1588_MPPr(pc, &RX_X1_ECC_STS_RX_1588_MPPr_reg));
   4301             intr_status->is_2b_err = RX_X1_ECC_STS_RX_1588_MPPr_TWO_BIT_ERR_EVENT_RX_1588_MPPf_GET(RX_X1_ECC_STS_RX_1588_MPPr_reg);
   4302             intr_status->is_1b_err = RX_X1_ECC_STS_RX_1588_MPPr_ONE_BIT_ERR_EVENT_RX_1588_MPPf_GET(RX_X1_ECC_STS_RX_1588_MPPr_reg);
   4303             break;
   4304         case phymodIntrEccTx1588400g:
   4305             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_TX_1588_400Gr(pc, &RX_X1_ECC_STS_TX_1588_400Gr_reg));
   4306             intr_status->is_2b_err = RX_X1_ECC_STS_TX_1588_400Gr_TWO_BIT_ERR_EVENT_TX_1588_400Gf_GET(RX_X1_ECC_STS_TX_1588_400Gr_reg);
   4307             intr_status->is_1b_err = RX_X1_ECC_STS_TX_1588_400Gr_ONE_BIT_ERR_EVENT_TX_1588_400Gf_GET(RX_X1_ECC_STS_TX_1588_400Gr_reg);
   4308             break;
   4309         case phymodIntrEccTx1588Mpp1:
   4310             pc->lane_mask = 0x1 << 4;
   4311             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_TX_1588_MPPr(pc, &RX_X1_ECC_STS_TX_1588_MPPr_reg));
   4312             intr_status->is_2b_err = RX_X1_ECC_STS_TX_1588_MPPr_TWO_BIT_ERR_EVENT_TX_1588_MPPf_GET(RX_X1_ECC_STS_TX_1588_MPPr_reg);
   4313             intr_status->is_1b_err = RX_X1_ECC_STS_TX_1588_MPPr_ONE_BIT_ERR_EVENT_TX_1588_MPPf_GET(RX_X1_ECC_STS_TX_1588_MPPr_reg);
   4314             break;
   4315         case phymodIntrEccTx1588Mpp0:
   4316             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_TX_1588_MPPr(pc, &RX_X1_ECC_STS_TX_1588_MPPr_reg));
   4317             intr_status->is_2b_err = RX_X1_ECC_STS_TX_1588_MPPr_TWO_BIT_ERR_EVENT_TX_1588_MPPf_GET(RX_X1_ECC_STS_TX_1588_MPPr_reg);
   4318             intr_status->is_1b_err = RX_X1_ECC_STS_TX_1588_MPPr_ONE_BIT_ERR_EVENT_TX_1588_MPPf_GET(RX_X1_ECC_STS_TX_1588_MPPr_reg);
   4319             break;
   4320         case phymodIntrEccUMTable:
   4321             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_UM_TBLr(pc, &RX_X1_ECC_STS_UM_TBLr_reg));
   4322             intr_status->is_2b_err = RX_X1_ECC_STS_UM_TBLr_TWO_BIT_ERR_EVENT_UM_TBLf_GET(RX_X1_ECC_STS_UM_TBLr_reg);
   4323             intr_status->is_1b_err = RX_X1_ECC_STS_UM_TBLr_ONE_BIT_ERR_EVENT_UM_TBLf_GET(RX_X1_ECC_STS_UM_TBLr_reg);
   4324             break;
   4325         case phymodIntrEccAMTable:
   4326             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_AM_TBLr(pc, &RX_X1_ECC_STS_AM_TBLr_reg));
   4327             intr_status->is_2b_err = RX_X1_ECC_STS_AM_TBLr_TWO_BIT_ERR_EVENT_AM_TBLf_GET(RX_X1_ECC_STS_AM_TBLr_reg);
   4328             intr_status->is_1b_err = RX_X1_ECC_STS_AM_TBLr_ONE_BIT_ERR_EVENT_AM_TBLf_GET(RX_X1_ECC_STS_AM_TBLr_reg);
   4329             break;
   4330         case phymodIntrEccSpeedTable:
   4331             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_SPD_TBLr(pc, &RX_X1_ECC_STS_SPD_TBLr_reg));
   4332             intr_status->is_2b_err = RX_X1_ECC_STS_SPD_TBLr_TWO_BIT_ERR_EVENT_SPD_TBLf_GET(RX_X1_ECC_STS_SPD_TBLr_reg);
   4333             intr_status->is_1b_err = RX_X1_ECC_STS_SPD_TBLr_ONE_BIT_ERR_EVENT_SPD_TBLf_GET(RX_X1_ECC_STS_SPD_TBLr_reg);
   4334             break;
   4335         case phymodIntrEccDeskew:
   4336             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_DESKEWr(pc, &RX_X1_ECC_STS_DESKEWr_reg));
   4337             intr_status->is_2b_err = RX_X1_ECC_STS_DESKEWr_TWO_BIT_ERR_EVENT_DESKEWf_GET(RX_X1_ECC_STS_DESKEWr_reg);
   4338             intr_status->is_1b_err = RX_X1_ECC_STS_DESKEWr_ONE_BIT_ERR_EVENT_DESKEWf_GET(RX_X1_ECC_STS_DESKEWr_reg);
   4339             break;
   4340         case phymodIntrEccRsFECRs400gMpp1:
   4341             pc->lane_mask = 0x1 << 4;
   4342             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RSFEC_RS400G_MPPr(pc, &RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg));
   4343             intr_status->is_2b_err = RX_X1_ECC_STS_RSFEC_RS400G_MPPr_TWO_BIT_ERR_EVENT_RSFEC_RS400G_MPPf_GET(RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg);
   4344             intr_status->is_1b_err = RX_X1_ECC_STS_RSFEC_RS400G_MPPr_ONE_BIT_ERR_EVENT_RSFEC_RS400G_MPPf_GET(RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg);
   4345             break;
   4346         case phymodIntrEccRsFECRs400gMpp0:
   4347             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RSFEC_RS400G_MPPr(pc, &RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg));
   4348             intr_status->is_2b_err = RX_X1_ECC_STS_RSFEC_RS400G_MPPr_TWO_BIT_ERR_EVENT_RSFEC_RS400G_MPPf_GET(RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg);
   4349             intr_status->is_1b_err = RX_X1_ECC_STS_RSFEC_RS400G_MPPr_ONE_BIT_ERR_EVENT_RSFEC_RS400G_MPPf_GET(RX_X1_ECC_STS_RSFEC_RS400G_MPPr_reg);
   4350             break;
   4351         case phymodIntrEccRsFECRbufMpp1:
   4352             pc->lane_mask = 0x1 << 4;
   4353             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RSFEC_RBUF_MPPr(pc, &RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg));
   4354             intr_status->is_2b_err = RX_X1_ECC_STS_RSFEC_RBUF_MPPr_TWO_BIT_ERR_EVENT_RSFEC_RBUF_MPPf_GET(RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg);
   4355             intr_status->is_1b_err = RX_X1_ECC_STS_RSFEC_RBUF_MPPr_ONE_BIT_ERR_EVENT_RSFEC_RBUF_MPPf_GET(RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg);
   4356             break;
   4357         case phymodIntrEccRsFECRbufMpp0:
   4358             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_RSFEC_RBUF_MPPr(pc, &RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg));
   4359             intr_status->is_2b_err = RX_X1_ECC_STS_RSFEC_RBUF_MPPr_TWO_BIT_ERR_EVENT_RSFEC_RBUF_MPPf_GET(RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg);
   4360             intr_status->is_1b_err = RX_X1_ECC_STS_RSFEC_RBUF_MPPr_ONE_BIT_ERR_EVENT_RSFEC_RBUF_MPPf_GET(RX_X1_ECC_STS_RSFEC_RBUF_MPPr_reg);
   4361             break;
   4362         case phymodIntrEccBaseRFEC:
   4363             PHYMOD_IF_ERR_RETURN(READ_RX_X1_ECC_STS_BASE_R_FECr(pc, &RX_X1_ECC_STS_BASE_R_FECr_reg));
   4364             intr_status->is_2b_err = RX_X1_ECC_STS_BASE_R_FECr_TWO_BIT_ERR_EVENT_BASE_R_FECf_GET(RX_X1_ECC_STS_BASE_R_FECr_reg);
   4365             intr_status->is_1b_err = RX_X1_ECC_STS_BASE_R_FECr_ONE_BIT_ERR_EVENT_BASE_R_FECf_GET(RX_X1_ECC_STS_BASE_R_FECr_reg);
   4366             break;
   4367         default:
   4368             return PHYMOD_E_PARAM;
   4369     }
   4370 
   4371     return PHYMOD_E_NONE;
   4372 }
   4373 
   4374 /* This function will return rev_number for the core */
   4375 int tbhmod_revid_get(PHYMOD_ST* pc, uint32_t* rev_id)
   4376 {
   4377     MAIN0_SERDESIDr_t MAIN0_SERDESIDr_reg;
   4378 
   4379     PHYMOD_IF_ERR_RETURN(READ_MAIN0_SERDESIDr(pc, &MAIN0_SERDESIDr_reg));
   4380     *rev_id = MAIN0_SERDESIDr_REV_NUMBERf_GET(MAIN0_SERDESIDr_reg);
   4381 
   4382     return PHYMOD_E_NONE;
   4383 }
   4384 int tbhmod_pmd_override_enable_set(PHYMOD_ST* pc,
   4385                                    phymod_override_type_t pmd_override_type,
   4386                                    uint32_t override_enable,
   4387                                    uint32_t override_val)
   4388 {
   4389     int start_lane, num_lane;
   4390     PMD_X4_OVRRr_t pmd_x4_override_reg;
   4391     PMD_X4_CTLr_t  pmd_x4_ctrl_reg;
   4392 
   4393 
   4394     PHYMOD_IF_ERR_RETURN
   4395         (phymod_util_lane_config_get(pc, &start_lane, &num_lane));
   4396 
   4397     PMD_X4_CTLr_CLR(pmd_x4_ctrl_reg);
   4398     PMD_X4_OVRRr_CLR(pmd_x4_override_reg);
   4399 
   4400     switch  (pmd_override_type) {
   4401     case phymodPMDLaneReset:
   4402         if (override_enable) {
   4403             PMD_X4_CTLr_LN_DP_H_RSTBf_SET(pmd_x4_ctrl_reg, override_val);
   4404             PHYMOD_IF_ERR_RETURN
   4405                 (MODIFY_PMD_X4_CTLr(pc, pmd_x4_ctrl_reg));
   4406         }
   4407         PMD_X4_OVRRr_LN_DP_H_RSTB_OENf_SET(pmd_x4_override_reg, override_enable);
   4408         PHYMOD_IF_ERR_RETURN
   4409             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4410         break;
   4411     case phymodPMDTxDisable:
   4412         if (override_enable) {
   4413             PMD_X4_CTLr_TX_DISABLEf_SET(pmd_x4_ctrl_reg, override_val);
   4414             PHYMOD_IF_ERR_RETURN
   4415                 (MODIFY_PMD_X4_CTLr(pc, pmd_x4_ctrl_reg));
   4416         }
   4417         PMD_X4_OVRRr_TX_DISABLE_OENf_SET(pmd_x4_override_reg, override_enable);
   4418         PHYMOD_IF_ERR_RETURN
   4419             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4420         break;
   4421     case phymodPMDRxLock:
   4422         PMD_X4_OVRRr_RX_LOCK_OVRDf_SET(pmd_x4_override_reg, override_enable);
   4423         PHYMOD_IF_ERR_RETURN
   4424             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4425         break;
   4426     case phymodPMDSignalDetect:
   4427         PMD_X4_OVRRr_SIGNAL_DETECT_OVRDf_SET(pmd_x4_override_reg, override_enable);
   4428         PHYMOD_IF_ERR_RETURN
   4429             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4430         break;
   4431     case phymodPMDRxClkValid:
   4432         PMD_X4_OVRRr_RX_CLK_VLD_OVRDf_SET(pmd_x4_override_reg, override_enable);
   4433         PHYMOD_IF_ERR_RETURN
   4434             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4435         break;
   4436     case phymodPMDTxClkValid:
   4437         PMD_X4_OVRRr_TX_CLK_VLD_OVRDf_SET(pmd_x4_override_reg, override_enable);
   4438         PHYMOD_IF_ERR_RETURN
   4439             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4440         break;
   4441     case phymodPMDLaneMode:
   4442         if (override_enable) {
   4443             PMD_X4_CTLr_PAM4_MODEf_SET(pmd_x4_ctrl_reg, override_val);
   4444             PHYMOD_IF_ERR_RETURN
   4445                 (MODIFY_PMD_X4_CTLr(pc, pmd_x4_ctrl_reg));
   4446         }
   4447         PMD_X4_OVRRr_LANE_MODE_OENf_SET(pmd_x4_override_reg, override_enable);
   4448         PHYMOD_IF_ERR_RETURN
   4449             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4450         break;
   4451     case phymodPMDOsrMode:
   4452         if (override_enable) {
   4453             PMD_X4_CTLr_OSR_MODEf_SET(pmd_x4_ctrl_reg, override_val);
   4454             PHYMOD_IF_ERR_RETURN
   4455                 (MODIFY_PMD_X4_CTLr(pc, pmd_x4_ctrl_reg));
   4456         }
   4457         PMD_X4_OVRRr_OSR_MODE_OENf_SET(pmd_x4_override_reg, override_enable);
   4458         PHYMOD_IF_ERR_RETURN
   4459             (MODIFY_PMD_X4_OVRRr(pc, pmd_x4_override_reg));
   4460         break;
   4461     default:
   4462         PHYMOD_DEBUG_ERROR(("Unsupported PMD override type\n"));
   4463         return PHYMOD_E_PARAM;
   4464     }
   4465     return PHYMOD_E_NONE;
   4466 }
   4467 int tbhmod_400g_autoneg_timer_disable(PHYMOD_ST* pc, int timer_disable)
   4468 {
   4469     AN_X1_LNK_FAIL_INHBT_TMR_CL72r_t link_fail_cl72_timer_reg;
   4470     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_t link_fail_not_cl72_timer_reg;
   4471     AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_t link_fail_cl72_pam4_timer_reg;
   4472     AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_t link_fail_not_cl72_pam4_timer_reg;
   4473 
   4474     if (timer_disable) {
   4475         /* 0x9255 0 */
   4476         AN_X1_LNK_FAIL_INHBT_TMR_CL72r_CLR(link_fail_cl72_timer_reg);
   4477         AN_X1_LNK_FAIL_INHBT_TMR_CL72r_SET(link_fail_cl72_timer_reg, 0x0);
   4478         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72r(pc, link_fail_cl72_timer_reg));
   4479         /* 0x9256 0 */
   4480         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_CLR(link_fail_not_cl72_timer_reg);
   4481         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_SET(link_fail_not_cl72_timer_reg, 0x0);
   4482         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r(pc, link_fail_not_cl72_timer_reg));
   4483 
   4484         /*0x925a 0 */
   4485         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_CLR(link_fail_cl72_pam4_timer_reg);
   4486         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_SET(link_fail_cl72_pam4_timer_reg, 0x0);
   4487         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r(pc, link_fail_cl72_pam4_timer_reg));
   4488         /*0x925b 0 */
   4489         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_CLR(link_fail_not_cl72_pam4_timer_reg);
   4490         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_SET(link_fail_not_cl72_pam4_timer_reg, 0x0);
   4491         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r(pc, link_fail_not_cl72_pam4_timer_reg));
   4492     } else { /* need to restore the timer value */
   4493 
   4494         /* 0x9255 500.04 ms */
   4495         AN_X1_LNK_FAIL_INHBT_TMR_CL72r_CLR(link_fail_cl72_timer_reg);
   4496         AN_X1_LNK_FAIL_INHBT_TMR_CL72r_SET(link_fail_cl72_timer_reg, 0x8236);
   4497         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72r(pc, link_fail_cl72_timer_reg));
   4498         /* 0x9256 160.98 ms */
   4499         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_CLR(link_fail_not_cl72_timer_reg);
   4500         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r_SET(link_fail_not_cl72_timer_reg, 0x29ab);
   4501         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72r(pc, link_fail_not_cl72_timer_reg));
   4502 
   4503         /*0x925a 2983.2 ms */
   4504         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_CLR(link_fail_cl72_pam4_timer_reg);
   4505         AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r_SET(link_fail_cl72_pam4_timer_reg, 0xc238);
   4506         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_CL72_PAM4r(pc, link_fail_cl72_pam4_timer_reg));
   4507         /*0x925b 1000.08 ms */
   4508         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_CLR(link_fail_not_cl72_pam4_timer_reg);
   4509         AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r_SET(link_fail_not_cl72_pam4_timer_reg, 0x41aa);
   4510         PHYMOD_IF_ERR_RETURN(WRITE_AN_X1_LNK_FAIL_INHBT_TMR_NOT_CL72_PAM4r(pc, link_fail_not_cl72_pam4_timer_reg));
   4511 
   4512     }
   4513     return PHYMOD_E_NONE;
   4514 }
   4515 
   4516 int tbhmod_fec_arch_decode_get(int fec_arch, phymod_fec_type_t* fec_type)
   4517 {
   4518     switch (fec_arch) {
   4519         case 1:
   4520             *fec_type = phymod_fec_CL74;
   4521             break;
   4522         case 2:
   4523             *fec_type = phymod_fec_CL91;
   4524             break;
   4525         case 3:
   4526             *fec_type = phymod_fec_RS272;
   4527             break;
   4528         case 4:
   4529             *fec_type = phymod_fec_RS544;
   4530             break;
   4531         case 5:
   4532             *fec_type = phymod_fec_RS544_2XN;
   4533             break;
   4534         case 6:
   4535             *fec_type = phymod_fec_RS272_2XN;
   4536             break;
   4537         default:
   4538             *fec_type = phymod_fec_None;
   4539             break;
   4540     }
   4541 
   4542     return PHYMOD_E_NONE;
   4543 }
   4544 
   4545 int tbhmod_vco_to_pll_lkup(uint32_t vco, tbhmod_refclk_t refclk, uint32_t* pll_div)
   4546 {
   4547     switch(refclk) {
   4548         case TBHMOD_REF_CLK_156P25MHZ:
   4549             if (vco == TBHMOD_VCO_20G) {
   4550                 *pll_div = TBHMOD_PLL_MODE_DIV_132;
   4551             } else if (vco == TBHMOD_VCO_25G) {
   4552                 *pll_div = TBHMOD_PLL_MODE_DIV_165;
   4553             } else {
   4554                 *pll_div = TBHMOD_PLL_MODE_DIV_170;
   4555             }
   4556             break;
   4557         case TBHMOD_REF_CLK_312P5MHZ:
   4558             if (vco == TBHMOD_VCO_20G) {
   4559                 *pll_div = TBHMOD_PLL_MODE_DIV_66;
   4560             } else if (vco == TBHMOD_VCO_25G) {
   4561                 *pll_div = TBHMOD_PLL_MODE_DIV_82P5;
   4562             } else {
   4563                 *pll_div = TBHMOD_PLL_MODE_DIV_85;
   4564             }
   4565             break;
   4566         default:
   4567             break;
   4568     }
   4569 
   4570     return PHYMOD_E_NONE;
   4571 }
   4572 
   4573 int tbhmod_pll_to_vco_get(tbhmod_refclk_t ref_clock, uint32_t pll, uint32_t* vco)
   4574 {
   4575     if (ref_clock == TBHMOD_REF_CLK_156P25MHZ) {
   4576         switch  (pll) {
   4577             case phymod_TSCBH_PLL_DIV170:
   4578                  *vco = TBHMOD_VCO_26G;
   4579                  break;
   4580             case phymod_TSCBH_PLL_DIV165:
   4581                  *vco = TBHMOD_VCO_25G;
   4582                  break;
   4583             case phymod_TSCBH_PLL_DIV132:
   4584                  *vco = TBHMOD_VCO_20G;
   4585                  break;
   4586             case phymod_TSCBH_PLL_DIVNONE:
   4587                  *vco = TBHMOD_VCO_NONE;
   4588                  break;
   4589             default:
   4590                  *vco = TBHMOD_VCO_PCS_BYPASS;
   4591                  break;
   4592         }
   4593     } else if (ref_clock == TBHMOD_REF_CLK_312P5MHZ) {
   4594         switch  (pll) {
   4595             case phymod_TSCBH_PLL_DIV85:
   4596                  *vco = TBHMOD_VCO_26G;
   4597                  break;
   4598             case phymod_TSCBH_PLL_DIV82P5:
   4599                  *vco = TBHMOD_VCO_25G;
   4600                  break;
   4601             case phymod_TSCBH_PLL_DIV66:
   4602                  *vco = TBHMOD_VCO_20G;
   4603                  break;
   4604             case phymod_TSCBH_PLL_DIVNONE:
   4605                  *vco = TBHMOD_VCO_NONE;
   4606                  break;
   4607             default:
   4608                  *vco = TBHMOD_VCO_PCS_BYPASS;
   4609                  break;
   4610         }
   4611     } else {
   4612         PHYMOD_DEBUG_ERROR(("Unsupported reference clock.\n"));
   4613         return PHYMOD_E_UNAVAIL;
   4614     }
   4615 
   4616     return PHYMOD_E_NONE;
   4617 }
   4618 
   4619 int tbhmod_rsfec_symbol_error_counter_get(PHYMOD_ST* pc,
   4620                                           int bit_mux_mode,
   4621                                           int max_count,
   4622                                           int* actual_count,
   4623                                           uint32_t* symb_err_cnt)
   4624 {
   4625     PHYMOD_ST phy_copy;
   4626     int num_lanes, start_lane, virtual_lanes, num_psll_per_phyl;
   4627     int i, cur_vl = 0;
   4628     uint16_t lower, upper;
   4629     uint32_t sum, vl_symb_err_cnt[20];
   4630 
   4631     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg;
   4632     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg;
   4633     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg;
   4634     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg;
   4635     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg;
   4636     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg;
   4637     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg;
   4638     RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_t RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg;
   4639 
   4640     RX_X4_PSLL_TO_VL_MAP0r_t RX_X4_PSLL_TO_VL_MAP0r_reg;
   4641     RX_X4_PSLL_TO_VL_MAP1r_t RX_X4_PSLL_TO_VL_MAP1r_reg;
   4642 
   4643     PHYMOD_IF_ERR_RETURN
   4644         (phymod_util_lane_config_get(pc, &start_lane, &num_lanes));
   4645 
   4646     if (max_count < num_lanes) {
   4647         return PHYMOD_E_PARAM;
   4648     } else {
   4649         *actual_count = num_lanes;
   4650     }
   4651 
   4652     PHYMOD_MEMCPY(&phy_copy, pc, sizeof(phy_copy));
   4653     PHYMOD_MEMSET(vl_symb_err_cnt, 0x0, 20 * sizeof(uint32_t));
   4654     PHYMOD_IF_ERR_RETURN(
   4655         _tbhmod_virtual_lane_count_get(bit_mux_mode, num_lanes, &virtual_lanes, &num_psll_per_phyl));
   4656 
   4657     /* Get error counts from registers for each virtual lanes (FEC lanes) */
   4658     /* Need to read lower 16 bits first, then upper 16 bits. */
   4659     switch (virtual_lanes) {
   4660         case 1:
   4661             phy_copy.lane_mask = 0x1 << start_lane;
   4662             PHYMOD_IF_ERR_RETURN(
   4663                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4664             PHYMOD_IF_ERR_RETURN(
   4665                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4666             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4667             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4668             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4669             break;
   4670         case 2:
   4671             phy_copy.lane_mask = 0x1 << start_lane;
   4672             PHYMOD_IF_ERR_RETURN(
   4673                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4674             PHYMOD_IF_ERR_RETURN(
   4675                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4676             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4677             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4678             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4679             cur_vl++;
   4680             PHYMOD_IF_ERR_RETURN(
   4681                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg));
   4682             PHYMOD_IF_ERR_RETURN(
   4683                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg));
   4684             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg);
   4685             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg);
   4686             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4687             break;
   4688         case 4:
   4689             phy_copy.lane_mask = 0x1 << start_lane;
   4690             PHYMOD_IF_ERR_RETURN(
   4691                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4692             PHYMOD_IF_ERR_RETURN(
   4693                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4694             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4695             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4696             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4697             cur_vl++;
   4698             PHYMOD_IF_ERR_RETURN(
   4699                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg));
   4700             PHYMOD_IF_ERR_RETURN(
   4701                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg));
   4702             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg);
   4703             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg);
   4704             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4705             cur_vl++;
   4706             PHYMOD_IF_ERR_RETURN(
   4707                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg));
   4708             PHYMOD_IF_ERR_RETURN(
   4709                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg));
   4710             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg);
   4711             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg);
   4712             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4713             cur_vl++;
   4714             PHYMOD_IF_ERR_RETURN(
   4715                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg));
   4716             PHYMOD_IF_ERR_RETURN(
   4717                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg));
   4718             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg);
   4719             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg);
   4720             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4721             break;
   4722         case 8:
   4723             phy_copy.lane_mask = 0x1 << start_lane;
   4724             PHYMOD_IF_ERR_RETURN(
   4725                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4726             PHYMOD_IF_ERR_RETURN(
   4727                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4728             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4729             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4730             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4731             cur_vl++;
   4732             PHYMOD_IF_ERR_RETURN(
   4733                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg));
   4734             PHYMOD_IF_ERR_RETURN(
   4735                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg));
   4736             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg);
   4737             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg);
   4738             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4739             cur_vl++;
   4740             PHYMOD_IF_ERR_RETURN(
   4741                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg));
   4742             PHYMOD_IF_ERR_RETURN(
   4743                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg));
   4744             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg);
   4745             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg);
   4746             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4747             cur_vl++;
   4748             PHYMOD_IF_ERR_RETURN(
   4749                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg));
   4750             PHYMOD_IF_ERR_RETURN(
   4751                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg));
   4752             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg);
   4753             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg);
   4754             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4755             cur_vl++;
   4756             phy_copy.lane_mask = 0x1 << (start_lane + 2);
   4757             PHYMOD_IF_ERR_RETURN(
   4758                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4759             PHYMOD_IF_ERR_RETURN(
   4760                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4761             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4762             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4763             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4764             cur_vl++;
   4765             PHYMOD_IF_ERR_RETURN(
   4766                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg));
   4767             PHYMOD_IF_ERR_RETURN(
   4768                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg));
   4769             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg);
   4770             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg);
   4771             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4772             cur_vl++;
   4773             PHYMOD_IF_ERR_RETURN(
   4774                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg));
   4775             PHYMOD_IF_ERR_RETURN(
   4776                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg));
   4777             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg);
   4778             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg);
   4779             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4780             cur_vl++;
   4781             PHYMOD_IF_ERR_RETURN(
   4782                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg));
   4783             PHYMOD_IF_ERR_RETURN(
   4784                 READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg));
   4785             lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg);
   4786             upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg);
   4787             vl_symb_err_cnt[cur_vl] = upper << 16 | lower;
   4788             break;
   4789         case 16:
   4790             /* This is 400G case. We need to get the counters from both MPPs. */
   4791             for (i = 0; i < num_lanes; i++) {
   4792                 if (cur_vl == 16) {
   4793                     cur_vl = 0;
   4794                 }
   4795                 phy_copy.lane_mask = 0x1 << (start_lane + i);
   4796                 PHYMOD_IF_ERR_RETURN(
   4797                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg));
   4798                 PHYMOD_IF_ERR_RETURN(
   4799                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg));
   4800                 lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW0r_reg);
   4801                 upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP0r_reg);
   4802                 vl_symb_err_cnt[cur_vl] += upper << 16 | lower;
   4803                 cur_vl++;
   4804                 PHYMOD_IF_ERR_RETURN(
   4805                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg));
   4806                 PHYMOD_IF_ERR_RETURN(
   4807                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg));
   4808                 lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW1r_reg);
   4809                 upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP1r_reg);
   4810                 vl_symb_err_cnt[cur_vl] += upper << 16 | lower;
   4811                 cur_vl++;
   4812                 PHYMOD_IF_ERR_RETURN(
   4813                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg));
   4814                 PHYMOD_IF_ERR_RETURN(
   4815                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg));
   4816                 lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW2r_reg);
   4817                 upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP2r_reg);
   4818                 vl_symb_err_cnt[cur_vl] += upper << 16 | lower;
   4819                 cur_vl++;
   4820                 PHYMOD_IF_ERR_RETURN(
   4821                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg));
   4822                 PHYMOD_IF_ERR_RETURN(
   4823                     READ_RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r(&phy_copy, &RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg));
   4824                 lower = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_LOW3r_reg);
   4825                 upper = RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_GET(RX_X4_RS_FEC_FEC_SYM_ERR_CTR_UP3r_reg);
   4826                 vl_symb_err_cnt[cur_vl] += upper << 16 | lower;
   4827                 cur_vl++;
   4828             }
   4829             break;
   4830         default:
   4831             return PHYMOD_E_PARAM;
   4832     }
   4833 
   4834     /* Map virtual lanes (FEC lanes) to logical lanes */
   4835     for (i = 0; i < num_lanes; i++) {
   4836         sum = 0;
   4837         phy_copy.lane_mask = 0x1 << (start_lane + i);
   4838         PHYMOD_IF_ERR_RETURN(READ_RX_X4_PSLL_TO_VL_MAP0r(&phy_copy, &RX_X4_PSLL_TO_VL_MAP0r_reg));
   4839         PHYMOD_IF_ERR_RETURN(READ_RX_X4_PSLL_TO_VL_MAP1r(&phy_copy, &RX_X4_PSLL_TO_VL_MAP1r_reg));
   4840         if (num_psll_per_phyl > 0) {
   4841             cur_vl = RX_X4_PSLL_TO_VL_MAP0r_PSLL0_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   4842             sum += vl_symb_err_cnt[cur_vl];
   4843         }
   4844         if (num_psll_per_phyl > 1) {
   4845             cur_vl = RX_X4_PSLL_TO_VL_MAP0r_PSLL1_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   4846             /* Check overflow */
   4847             if (vl_symb_err_cnt[cur_vl] > 0xffffffff - sum) {
   4848                 sum = 0xffffffff;
   4849             } else {
   4850                 sum += vl_symb_err_cnt[cur_vl];
   4851             }
   4852         }
   4853         if (num_psll_per_phyl > 2) {
   4854             cur_vl = RX_X4_PSLL_TO_VL_MAP0r_PSLL2_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP0r_reg);
   4855             /* Check overflow */
   4856             if (vl_symb_err_cnt[cur_vl] > 0xffffffff - sum) {
   4857                 sum = 0xffffffff;
   4858             } else {
   4859                 sum += vl_symb_err_cnt[cur_vl];
   4860             }
   4861         }
   4862         if (num_psll_per_phyl > 3) {
   4863             cur_vl = RX_X4_PSLL_TO_VL_MAP1r_PSLL3_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP1r_reg);
   4864             /* Check overflow */
   4865             if (vl_symb_err_cnt[cur_vl] > 0xffffffff - sum) {
   4866                 sum = 0xffffffff;
   4867             } else {
   4868                 sum += vl_symb_err_cnt[cur_vl];
   4869             }
   4870         }
   4871         if (num_psll_per_phyl > 4) {
   4872             cur_vl = RX_X4_PSLL_TO_VL_MAP1r_PSLL4_TO_VL_MAPPINGf_GET(RX_X4_PSLL_TO_VL_MAP1r_reg);
   4873             /* Check overflow */
   4874             if (vl_symb_err_cnt[cur_vl] > 0xffffffff - sum) {
   4875                 sum = 0xffffffff;
   4876             } else {
   4877                 sum += vl_symb_err_cnt[cur_vl];
   4878             }
   4879         }
   4880         symb_err_cnt[i] = sum;
   4881     }
   4882     return PHYMOD_E_NONE;
   4883 }
   4884 
   4885 #ifdef _DV_AN_NEWCODE_
   4886 #include "tbhmod_an_newcode_onlyfordv.c"
   4887 #endif /* _DV_AN_NEWCODE_ */
   4888 
   4889 
   4890 
   4891