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,®_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, ®_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, ®_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, ®_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, ®_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, ®_tx_1588_timestamp_hi)); 4167 PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_MIDr(pc, ®_tx_1588_timestamp_mid)); 4168 PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_1588_TIMESTAMP_LOr(pc, ®_tx_1588_timestamp_lo)); 4169 PHYMOD_IF_ERR_RETURN(READ_TX_X4_TX_TS_SEQ_IDr(pc, ®_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, ®_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