dino_diag_seq.c (23863B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 * 6 */ 7 8 /* 9 * 10 * 11 * This program is the proprietary software of Broadcom Corporation 12 * and/or its licensors, and may only be used, duplicated, modified 13 * or distributed pursuant to the terms and conditions of a separate, 14 * written license agreement executed between you and Broadcom 15 * (an "Authorized License"). Except as set forth in an Authorized 16 * License, Broadcom grants no license (express or implied), right 17 * to use, or waiver of any kind with respect to the Software, and 18 * Broadcom expressly reserves all rights in and to the Software 19 * and all intellectual property rights therein. IF YOU HAVE 20 * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE 21 * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE 22 * ALL USE OF THE SOFTWARE. 23 * 24 * Except as expressly set forth in the Authorized License, 25 * 26 * 1. This program, including its structure, sequence and organization, 27 * constitutes the valuable trade secrets of Broadcom, and you shall use 28 * all reasonable efforts to protect the confidentiality thereof, 29 * and to use this information only in connection with your use of 30 * Broadcom integrated circuit products. 31 * 32 * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS 33 * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, 34 * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, 35 * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY 36 * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, 37 * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, 38 * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 39 * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING 40 * OUT OF USE OR PERFORMANCE OF THE SOFTWARE. 41 * 42 * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL 43 * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, 44 * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER 45 * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY 46 * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE 47 * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF 48 * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00, 49 * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING 50 * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$ 51 */ 52 #define DINO_EXCLUDE_STATIC_FUNCTION_DECLARATIONS 53 54 #include <phymod/phymod.h> 55 #include <phymod/phymod_system.h> 56 #include <phymod/phymod_diagnostics.h> 57 #include "bcmi_dino_defs.h" 58 #include "dino_cfg_seq.h" 59 #include "dino_diag_seq.h" 60 #include "dino_serdes/falcon2_dino_src/falcon2_dino_functions.h" 61 #include "dino_serdes/merlin_dino_src/merlin_dino_functions.h" 62 #include "dino_serdes/common/srds_api_enum.h" 63 #include "dino_serdes/falcon2_dino_src/falcon2_dino_internal.h" 64 #include "dino_serdes/merlin_dino_src/merlin_dino_internal.h" 65 66 int _dino_phy_prbs_config_set(const phymod_access_t* pa, uint32_t flags, uint16_t if_side, uint16_t lane, const phymod_prbs_t* prbs) 67 { 68 uint16_t prbs_poly = 0; 69 70 PHYMOD_IF_ERR_RETURN( 71 _dino_phymod_prbs_poly_to_serdes_prbs_poly(prbs->poly, &prbs_poly)); 72 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 73 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 74 PHYMOD_IF_ERR_RETURN( 75 falcon2_dino_config_tx_prbs(pa, prbs_poly, (uint8_t)prbs->invert)); 76 } else { 77 PHYMOD_IF_ERR_RETURN( 78 merlin_dino_config_tx_prbs(pa, prbs_poly, (uint8_t)prbs->invert)); 79 } 80 } 81 82 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags) || flags == 0) { 83 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 84 PHYMOD_IF_ERR_RETURN( 85 falcon2_dino_config_rx_prbs(pa, prbs_poly, PRBS_INITIAL_SEED_HYSTERESIS, 86 (uint8_t)prbs->invert)); 87 } else { 88 PHYMOD_IF_ERR_RETURN( 89 merlin_dino_config_rx_prbs(pa, prbs_poly, PRBS_INITIAL_SEED_HYSTERESIS, 90 (uint8_t)prbs->invert)); 91 } 92 } 93 94 return PHYMOD_E_NONE; 95 } 96 97 int _dino_phy_prbs_enable_set(const phymod_access_t* pa, uint32_t flags, uint16_t if_side, uint16_t lane, uint32_t enable) 98 { 99 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 100 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 101 PHYMOD_IF_ERR_RETURN( 102 falcon2_dino_tx_prbs_en(pa, enable)); 103 } else { 104 PHYMOD_IF_ERR_RETURN( 105 merlin_dino_tx_prbs_en(pa, enable)); 106 } 107 } 108 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags) || flags == 0) { 109 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 110 if (enable) { 111 PHYMOD_IF_ERR_RETURN ( 112 falcon2_dino_wr_prbs_chk_clk_en_frc_on(1)); 113 } 114 PHYMOD_IF_ERR_RETURN( 115 falcon2_dino_rx_prbs_en(pa, enable)); 116 if (!enable) { 117 PHYMOD_IF_ERR_RETURN ( 118 falcon2_dino_wr_prbs_chk_clk_en_frc_on(0)); 119 } 120 } else { 121 if (enable) { 122 PHYMOD_IF_ERR_RETURN ( 123 wr_prbs_chk_clk_en_frc_on(1)); 124 } 125 PHYMOD_IF_ERR_RETURN ( 126 merlin_dino_rx_prbs_en(pa, enable)); 127 if (!enable) { 128 PHYMOD_IF_ERR_RETURN ( 129 wr_prbs_chk_clk_en_frc_on(0)); 130 } 131 } 132 } 133 134 return PHYMOD_E_NONE; 135 } 136 137 int _dino_phy_prbs_enable_get(const phymod_access_t* pa, uint32_t flags, uint16_t if_side, uint16_t lane, uint32_t *enable) 138 { 139 uint8_t gen_en = 0; 140 uint8_t ckr_en = 0; 141 142 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 143 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 144 PHYMOD_IF_ERR_RETURN( 145 falcon2_dino_get_tx_prbs_en(pa, &gen_en)); 146 *enable = gen_en; 147 } else { 148 PHYMOD_IF_ERR_RETURN( 149 merlin_dino_get_tx_prbs_en(pa, &gen_en)); 150 *enable = gen_en; 151 } 152 } 153 if (flags == 0 || PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 154 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 155 PHYMOD_IF_ERR_RETURN( 156 falcon2_dino_get_rx_prbs_en(pa, &ckr_en)); 157 *enable = ckr_en; 158 } else { 159 PHYMOD_IF_ERR_RETURN( 160 merlin_dino_get_rx_prbs_en(pa, &ckr_en)); 161 *enable = ckr_en; 162 } 163 } 164 if (flags == 0) { 165 *enable = ckr_en & gen_en; 166 } 167 PHYMOD_IF_ERR_RETURN ( 168 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 169 170 return PHYMOD_E_NONE; 171 } 172 173 int _dino_phy_prbs_config_get(const phymod_access_t* pa, 174 uint32_t flags, 175 uint16_t if_side, 176 uint16_t lane, 177 phymod_prbs_t* prbs, 178 uint16_t* serdes_poly, 179 uint16_t* chkr_mode) 180 { 181 uint8_t data = 0; 182 enum srds_prbs_polynomial_enum srds_prbs_poly; 183 enum srds_prbs_checker_mode_enum srds_prbs_chkr_mode; 184 185 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 186 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 187 PHYMOD_IF_ERR_RETURN(falcon2_dino_get_tx_prbs_config(pa, &srds_prbs_poly, &data)); 188 prbs->invert = data; 189 *serdes_poly = srds_prbs_poly; 190 } else { 191 PHYMOD_IF_ERR_RETURN(merlin_dino_get_tx_prbs_config(pa, &srds_prbs_poly, &data)); 192 prbs->invert = data; 193 *serdes_poly = srds_prbs_poly; 194 } 195 } 196 if (flags == 0 || PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 197 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 198 PHYMOD_IF_ERR_RETURN(falcon2_dino_get_rx_prbs_config(pa, &srds_prbs_poly, &srds_prbs_chkr_mode, &data)); 199 prbs->invert = data; 200 *serdes_poly = srds_prbs_poly; 201 *chkr_mode = srds_prbs_chkr_mode; 202 } else { 203 PHYMOD_IF_ERR_RETURN(merlin_dino_get_rx_prbs_config(pa, &srds_prbs_poly, &srds_prbs_chkr_mode, &data)); 204 prbs->invert = data; 205 *serdes_poly = srds_prbs_poly; 206 *chkr_mode = srds_prbs_chkr_mode; 207 } 208 } 209 210 return PHYMOD_E_NONE; 211 } 212 213 int _dino_phy_prbs_status_get(const phymod_access_t* pa, uint32_t flags, uint16_t if_side, uint16_t lane, phymod_prbs_status_t* prbs_status) 214 { 215 uint8_t data = 0; 216 uint32_t err_cnt = 0; 217 218 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 219 PHYMOD_IF_ERR_RETURN(falcon2_dino_prbs_chk_lock_state(pa, &data)); 220 prbs_status->prbs_lock &= data; 221 PHYMOD_IF_ERR_RETURN(falcon2_dino_prbs_err_count_state(pa, &err_cnt, &data)); 222 prbs_status->prbs_lock_loss &= data; 223 prbs_status->error_count |= err_cnt; 224 } else { 225 PHYMOD_IF_ERR_RETURN(merlin_dino_prbs_chk_lock_state(pa, &data)); 226 prbs_status->prbs_lock &= data; 227 PHYMOD_IF_ERR_RETURN(merlin_dino_prbs_err_count_state(pa, &err_cnt, &data)); 228 prbs_status->prbs_lock_loss &= data; 229 prbs_status->error_count |= err_cnt; 230 } 231 232 return PHYMOD_E_NONE; 233 } 234 235 int _dino_phy_display_eyescan(const phymod_access_t *pa, uint16_t if_side, uint16_t lane) 236 { 237 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 238 PHYMOD_IF_ERR_RETURN 239 (falcon2_dino_display_core_state_hdr(pa)); 240 PHYMOD_IF_ERR_RETURN 241 (falcon2_dino_display_core_state_line(pa)); 242 PHYMOD_IF_ERR_RETURN 243 (falcon2_dino_display_lane_state_hdr(pa)); 244 PHYMOD_IF_ERR_RETURN 245 (falcon2_dino_display_lane_state(pa)); 246 PHYMOD_IF_ERR_RETURN 247 (falcon2_dino_display_eye_scan(pa)); 248 } else { 249 PHYMOD_IF_ERR_RETURN 250 (merlin_dino_display_core_state_hdr(pa)) ; 251 PHYMOD_IF_ERR_RETURN 252 (merlin_dino_display_core_state_line(pa)); 253 PHYMOD_IF_ERR_RETURN 254 (merlin_dino_display_lane_state_hdr(pa)); 255 PHYMOD_IF_ERR_RETURN 256 (merlin_dino_display_lane_state(pa)); 257 PHYMOD_IF_ERR_RETURN 258 (merlin_dino_display_eye_scan(pa)); 259 } 260 261 return PHYMOD_E_NONE; 262 } 263 264 err_code_t _dino_merlin_read_pll_range(const phymod_access_t *pa, uint32_t *pll_range) 265 { 266 err_code_t __err; 267 __err=ERR_CODE_NONE; 268 *pll_range = rdc_pll_range(); 269 270 return (ERR_CODE_NONE); 271 } 272 273 err_code_t _dino_falcon2_read_pll_range(const phymod_access_t *pa, uint32_t *pll_range) 274 { 275 err_code_t __err; 276 __err=ERR_CODE_NONE; 277 *pll_range = falcon2_dino_rdc_ams_pll_range(); 278 279 return (ERR_CODE_NONE); 280 } 281 282 int _dino_core_diagnostics_get(const phymod_access_t* pa, uint16_t if_side, uint16_t lane,phymod_core_diagnostics_t* diag) 283 { 284 int16_t temp = 0; 285 286 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 287 PHYMOD_IF_ERR_RETURN(falcon2_dino_read_die_temperature(pa, &temp)); 288 diag->temperature = temp; 289 PHYMOD_IF_ERR_RETURN(_dino_falcon2_read_pll_range(pa, &diag->pll_range)); 290 } else { /* Merlin core status dump */ 291 PHYMOD_IF_ERR_RETURN(merlin_dino_read_die_temperature(pa, &temp)); 292 diag->temperature = temp; 293 PHYMOD_IF_ERR_RETURN(_dino_merlin_read_pll_range(pa, &diag->pll_range)); 294 } 295 296 return PHYMOD_E_NONE; 297 } 298 299 int _dino_phy_diagnostics_get(const phymod_access_t *pa, uint16_t if_side, uint16_t lane, phymod_phy_diagnostics_t* diag) 300 { 301 falcon2_dino_lane_state_st falcon_state; 302 merlin_dino_lane_state_st merlin_state; 303 PHYMOD_MEMSET(&falcon_state, 0, sizeof(falcon2_dino_lane_state_st)); 304 PHYMOD_MEMSET(&merlin_state, 0, sizeof(merlin_dino_lane_state_st)); 305 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 306 PHYMOD_DEBUG_VERBOSE(("Phy Diagnostics for Lane:%d \n",lane)); 307 /* set the core to get the master /slave */ 308 /* system side always master line side considered as slave*/ 309 PHYMOD_IF_ERR_RETURN( 310 _falcon2_dino_read_lane_state(pa, &falcon_state)); 311 diag->signal_detect = falcon_state.sig_det; 312 diag->osr_mode = falcon_state.osr_mode.tx_rx; 313 diag->rx_lock = falcon_state.rx_lock; 314 diag->tx_ppm = falcon_state.tx_ppm; 315 diag->clk90_offset = falcon_state.clk90; 316 diag->clkp1_offset = falcon_state.clkp1; 317 diag->p1_lvl = falcon_state.p1_lvl; 318 diag->dfe1_dcd = falcon_state.dfe1_dcd; 319 diag->dfe2_dcd = falcon_state.dfe2_dcd; 320 diag->slicer_offset.offset_pe = falcon_state.pe; 321 diag->slicer_offset.offset_ze = falcon_state.ze; 322 diag->slicer_offset.offset_me = falcon_state.me; 323 diag->slicer_offset.offset_po = falcon_state.po; 324 diag->slicer_offset.offset_zo = falcon_state.zo; 325 diag->slicer_offset.offset_mo = falcon_state.mo; 326 diag->eyescan.heye_left = falcon_state.heye_left; 327 diag->eyescan.heye_right = falcon_state.heye_right; 328 diag->eyescan.veye_upper = falcon_state.veye_upper; 329 diag->eyescan.veye_lower = falcon_state.veye_lower; 330 diag->link_time = falcon_state.link_time; 331 diag->pf_main = falcon_state.pf_main; 332 diag->pf_hiz = falcon_state.pf_hiz; 333 diag->pf_bst = falcon_state.pf_bst; 334 diag->pf_low = 0; /* not availble in serdes api*/ 335 diag->pf2_ctrl = falcon_state.pf2_ctrl; 336 diag->vga = falcon_state.vga; 337 diag->dc_offset = falcon_state.dc_offset; 338 diag->p1_lvl_ctrl = falcon_state.p1_lvl_ctrl; 339 diag->dfe1 = falcon_state.dfe1; 340 diag->dfe2 = falcon_state.dfe2; 341 diag->dfe3 = falcon_state.dfe3; 342 diag->dfe4 = falcon_state.dfe4; 343 diag->dfe5 = falcon_state.dfe5; 344 diag->dfe6 = falcon_state.dfe6; 345 diag->txfir_pre = falcon_state.txfir_pre; 346 diag->txfir_main = falcon_state.txfir_main; 347 diag->txfir_post1 = falcon_state.txfir_post1; 348 diag->txfir_post2 = falcon_state.txfir_post2; 349 diag->txfir_post3 = falcon_state.txfir_post3; 350 diag->tx_amp_ctrl = 0; /* not availble in serdes api*/ 351 diag->br_pd_en = falcon_state.br_pd_en; 352 } else { 353 PHYMOD_IF_ERR_RETURN 354 (_merlin_dino_read_lane_state(pa, &merlin_state)); 355 diag->signal_detect = merlin_state.sig_det; 356 diag->osr_mode = merlin_state.osr_mode.tx_rx; 357 diag->rx_lock = merlin_state.rx_lock; 358 diag->tx_ppm = merlin_state.tx_ppm; 359 diag->clk90_offset = merlin_state.clk90; 360 diag->clkp1_offset = merlin_state.clkp1; 361 diag->p1_lvl = merlin_state.p1_lvl; 362 diag->dfe1_dcd = merlin_state.dfe1_dcd; 363 diag->dfe2_dcd = merlin_state.dfe2_dcd; 364 diag->slicer_offset.offset_pe = merlin_state.pe; 365 diag->slicer_offset.offset_ze = merlin_state.ze; 366 diag->slicer_offset.offset_me = merlin_state.me; 367 diag->slicer_offset.offset_po = merlin_state.po; 368 diag->slicer_offset.offset_zo = merlin_state.zo; 369 diag->slicer_offset.offset_mo = merlin_state.mo; 370 diag->eyescan.heye_left = merlin_state.heye_left; 371 diag->eyescan.heye_right = merlin_state.heye_right; 372 diag->eyescan.veye_upper = merlin_state.veye_upper; 373 diag->eyescan.veye_lower = merlin_state.veye_lower; 374 diag->link_time = merlin_state.link_time; 375 diag->pf_main = merlin_state.pf_main; 376 diag->pf_hiz = merlin_state.pf_hiz; 377 diag->pf_bst = merlin_state.pf_bst; 378 diag->pf_low = 0; /* Not Availble in serdes API*/ 379 diag->pf2_ctrl = merlin_state.pf2_ctrl; 380 diag->vga = merlin_state.vga; 381 diag->dc_offset = merlin_state.dc_offset; 382 diag->p1_lvl_ctrl = merlin_state.p1_lvl_ctrl; 383 diag->dfe1 = merlin_state.dfe1; 384 diag->dfe2 = merlin_state.dfe2; 385 diag->dfe3 = merlin_state.dfe3; 386 diag->dfe4 = merlin_state.dfe4; 387 diag->dfe5 = merlin_state.dfe5; 388 diag->dfe6 = merlin_state.dfe6; 389 diag->txfir_pre = merlin_state.txfir_pre; 390 diag->txfir_main = merlin_state.txfir_main; 391 diag->txfir_post1 = merlin_state.txfir_post1; 392 diag->txfir_post2 = merlin_state.txfir_post2; 393 diag->txfir_post3 = merlin_state.txfir_post3; 394 diag->tx_amp_ctrl = 0; /* Not Availble in serdes API*/ 395 diag->br_pd_en = merlin_state.br_pd_en; 396 } 397 398 return PHYMOD_E_NONE; 399 } 400 401 int _dino_ber_proj_lane_speed_get(const phymod_phy_access_t *phy, phymod_phy_inf_config_t *config, uint16_t if_side, uint16_t lane, uint32_t *speed) 402 { 403 phymod_phy_access_t phy_copy; 404 PHYMOD_MEMSET(&phy_copy, 0, sizeof(phymod_phy_access_t)); 405 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phymod_phy_access_t)); 406 407 PHYMOD_IF_ERR_RETURN( 408 _dino_phy_interface_config_get(&phy_copy, 0, config)); 409 410 if (if_side == DINO_IF_LINE) { 411 if (config->data_rate == DINO_SPD_100G || config->data_rate == DINO_SPD_106G) { 412 if (PHYMOD_INTF_CONFIG_PHY_GEARBOX_ENABLE_GET(&phy_copy) && 413 (if_side == DINO_IF_LINE)) { 414 *speed = 25781250; 415 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 416 *speed = 27952500; 417 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 418 *speed = 27343750; 419 } 420 } else { 421 *speed = 10312500; 422 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 423 *speed = 10937500; 424 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 425 *speed = 11180000; 426 } 427 } 428 } else if ((config->data_rate == DINO_SPD_40G || config->data_rate == DINO_SPD_42G || 429 config->data_rate == DINO_SPD_10G || config->data_rate == DINO_SPD_11G 430 )) { 431 *speed = 10312500; 432 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 433 *speed = 10937500; 434 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 435 *speed = 11180000; 436 } 437 } 438 } else { 439 *speed = 10312500; 440 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 441 *speed = 10937500; 442 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 443 *speed = 11180000; 444 } 445 } 446 447 return PHYMOD_E_NONE; 448 } 449 450 int _dino_ber_proj(const phymod_phy_access_t *phy, uint16_t if_side, uint16_t lane, const phymod_phy_eyescan_options_t* eyescan_options) 451 { 452 const phymod_access_t *pa = &phy->access; 453 phymod_phy_inf_config_t config; 454 int rv = PHYMOD_E_NONE; 455 #ifdef SERDES_API_FLOATING_POINT 456 uint32_t speed; 457 USR_DOUBLE speedD; 458 #endif 459 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 460 461 PHYMOD_DEBUG_VERBOSE(("eye_margin_proj for Lane:%d \n", lane)); 462 if (DINO_IS_FALCON_SIDE(if_side, lane)) { 463 PHYMOD_IF_ERR_RETURN 464 (falcon2_dino_display_core_state_hdr(pa)); 465 PHYMOD_IF_ERR_RETURN 466 (falcon2_dino_display_core_state_line(pa)); 467 PHYMOD_IF_ERR_RETURN 468 (falcon2_dino_display_lane_state_hdr(pa)); 469 PHYMOD_IF_ERR_RETURN 470 (falcon2_dino_display_lane_state(pa)); 471 #ifdef SERDES_API_FLOATING_POINT 472 PHYMOD_IF_ERR_RETURN 473 (_dino_ber_proj_lane_speed_get(phy, &config, if_side, lane, &speed)); 474 speedD = speed * 1000.0; 475 PHYMOD_IF_ERR_RETURN ( 476 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 477 PHYMOD_IF_ERR_RETURN 478 (falcon2_dino_eye_margin_proj(pa, speedD, eyescan_options->ber_proj_scan_mode, 479 eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt)); 480 #else 481 PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n")); 482 rv = PHYMOD_E_RESOURCE; 483 #endif 484 } else { 485 PHYMOD_IF_ERR_RETURN 486 (merlin_dino_display_core_state_hdr(pa)) ; 487 PHYMOD_IF_ERR_RETURN 488 (merlin_dino_display_core_state_line(pa)); 489 PHYMOD_IF_ERR_RETURN 490 (merlin_dino_display_lane_state_hdr(pa)); 491 PHYMOD_IF_ERR_RETURN 492 (merlin_dino_display_lane_state(pa)); 493 #ifdef SERDES_API_FLOATING_POINT 494 PHYMOD_IF_ERR_RETURN 495 (_dino_ber_proj_lane_speed_get(phy, &config, if_side, lane, &speed)); 496 speedD = speed * 1000.0; 497 PHYMOD_IF_ERR_RETURN ( 498 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 499 PHYMOD_IF_ERR_RETURN 500 (merlin_dino_eye_margin_proj(pa, speedD, eyescan_options->ber_proj_scan_mode, 501 eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt)); 502 /*Work around for PRBS Locked with Errors */ 503 #else 504 PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n")); 505 rv = PHYMOD_E_RESOURCE; 506 #endif 507 PHYMOD_IF_ERR_RETURN 508 (wr_trnsum_error_count_en(0)); 509 } 510 511 return rv; 512 } 513 514 int _dino_phy_link_mon_enable_set(const phymod_access_t* pa, uint32_t enable) 515 { 516 uint32_t reg_val = 0; 517 BCMI_DINO_MAIN_CTLr_t dino_main_ctl; 518 PHYMOD_MEMSET(&dino_main_ctl, 0, sizeof(BCMI_DINO_MAIN_CTLr_t)); 519 520 /* Disable link mon before configuring it */ 521 PHYMOD_IF_ERR_RETURN( 522 BCMI_DINO_READ_MAIN_CTLr(pa, &dino_main_ctl)); 523 reg_val = BCMI_DINO_MAIN_CTLr_GET(dino_main_ctl); 524 reg_val &= (~(1 << 2)); 525 BCMI_DINO_MAIN_CTLr_SET(dino_main_ctl, reg_val); 526 PHYMOD_IF_ERR_RETURN( 527 BCMI_DINO_WRITE_MAIN_CTLr(pa, dino_main_ctl)); 528 /* enable / disable link monitor */ 529 PHYMOD_IF_ERR_RETURN( 530 BCMI_DINO_READ_MAIN_CTLr(pa, &dino_main_ctl)); 531 reg_val = BCMI_DINO_MAIN_CTLr_GET(dino_main_ctl); 532 reg_val |= (enable << 2); 533 BCMI_DINO_MAIN_CTLr_SET(dino_main_ctl, reg_val); 534 PHYMOD_IF_ERR_RETURN( 535 BCMI_DINO_WRITE_MAIN_CTLr(pa, dino_main_ctl)); 536 537 return PHYMOD_E_NONE; 538 } 539 540 int _dino_phy_link_mon_enable_get(const phymod_access_t* pa, uint32_t *enable) 541 { 542 BCMI_DINO_MAIN_CTLr_t dino_main_ctl; 543 PHYMOD_MEMSET(&dino_main_ctl, 0, sizeof(BCMI_DINO_MAIN_CTLr_t)); 544 545 PHYMOD_IF_ERR_RETURN( 546 BCMI_DINO_READ_MAIN_CTLr(pa, &dino_main_ctl)); 547 if (BCMI_DINO_MAIN_CTLr_MAIN_CTRLf_GET(dino_main_ctl) & 0x1) { 548 *enable &= 1; 549 } else { 550 *enable &= 0; 551 } 552 553 return PHYMOD_E_NONE; 554 } 555 556 int _dino_phy_link_mon_status_get(const phymod_access_t* pa, uint32_t* lock_status, uint32_t* lock_lost_lh, uint32_t* error_count) 557 { 558 uint16_t ber_count_lsb = 0; 559 uint16_t ber_count_msb = 0; 560 BCMI_DINO_MAIN_STSr_t dino_main_sts; 561 BCMI_DINO_LIVE_STSr_t dino_live_sts; 562 BCMI_DINO_CL49_BER_STSr_t cl49_ber_sts; 563 BCMI_DINO_BER_CNT_MSBr_t ber_cnt_msb; 564 PHYMOD_MEMSET(&dino_live_sts, 0, sizeof(BCMI_DINO_LIVE_STSr_t)); 565 PHYMOD_MEMSET(&dino_main_sts, 0, sizeof(BCMI_DINO_MAIN_STSr_t)); 566 PHYMOD_MEMSET(&cl49_ber_sts, 0, sizeof(BCMI_DINO_CL49_BER_STSr_t)); 567 PHYMOD_MEMSET(&ber_cnt_msb, 0, sizeof (BCMI_DINO_BER_CNT_MSBr_t)); 568 569 PHYMOD_IF_ERR_RETURN( 570 BCMI_DINO_READ_LIVE_STSr(pa, &dino_live_sts)); 571 if (dino_live_sts.v[0] & 0x2) { 572 *lock_status &= 1; 573 } else { 574 *lock_status &= 0; 575 } 576 577 PHYMOD_IF_ERR_RETURN( 578 BCMI_DINO_READ_MAIN_STSr(pa, &dino_main_sts)); 579 if (dino_main_sts.v[0] & 0x8) { 580 *lock_lost_lh &= 0; 581 } else { 582 *lock_lost_lh &= 1; 583 } 584 PHYMOD_IF_ERR_RETURN( 585 BCMI_DINO_READ_CL49_BER_STSr(pa, &cl49_ber_sts)); 586 ber_count_lsb = (cl49_ber_sts.v[0] & 0x7f); 587 ber_count_lsb >>= 1; 588 PHYMOD_IF_ERR_RETURN( 589 BCMI_DINO_READ_BER_CNT_MSBr(pa, &ber_cnt_msb)); 590 ber_count_msb = ber_cnt_msb.v[0]; 591 *error_count = (ber_count_msb << 6) | ber_count_lsb; 592 593 return PHYMOD_E_NONE; 594 }