phy8806x_diagnostics.c (24669B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_util.h> 13 #include <phymod/phymod_config.h> 14 #include <phymod/phymod_diagnostics.h> 15 #include <phymod/phymod_diagnostics_dispatch.h> 16 17 #if defined(INCLUDE_PHY_8806X) 18 19 #ifdef INCLUDE_FCMAP 20 #include <soc/phy/phymod_ctrl.h> 21 #include <soc/phy/phyctrl.h> 22 #include <soc/phyctrl.h> 23 #endif 24 25 #endif 26 27 #include "../../tscf/tier1/tefmod_enum_defines.h" 28 #include "../../phy8806x/tier1/phy8806x_cfg_seq.h" 29 #include "../../phy8806x/tier1/phy8806x_tsc_enum.h" 30 #include "../../phy8806x/tier1/phy8806x_tsc_common.h" 31 #include "../../phy8806x/tier1/phy8806x_tsc_interface.h" 32 #include "../../phy8806x/tier1/phy8806x_tsc_dependencies.h" 33 #include "../../phy8806x/tier1/phy8806x_tsc_debug_functions.h" 34 35 #ifdef PHYMOD_PHY8806X_SUPPORT 36 37 38 /*phymod, internal enum mappings*/ 39 STATIC 40 int _phy8806x_prbs_poly_phymod_to_phy8806x(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *phy8806x_poly) 41 { 42 switch(phymod_poly){ 43 case phymodPrbsPoly7: 44 *phy8806x_poly = PRBS_7; 45 break; 46 case phymodPrbsPoly9: 47 *phy8806x_poly = PRBS_9; 48 break; 49 case phymodPrbsPoly11: 50 *phy8806x_poly = PRBS_11; 51 break; 52 case phymodPrbsPoly15: 53 *phy8806x_poly = PRBS_15; 54 break; 55 case phymodPrbsPoly23: 56 *phy8806x_poly = PRBS_23; 57 break; 58 case phymodPrbsPoly31: 59 *phy8806x_poly = PRBS_31; 60 break; 61 case phymodPrbsPoly58: 62 *phy8806x_poly = PRBS_58; 63 break; 64 default: 65 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly)); 66 } 67 return PHYMOD_E_NONE; 68 } 69 70 STATIC 71 int _phy8806x_prbs_poly_tscf_to_phymod(phy8806x_prbs_polynomial_type_t tscf_poly, phymod_prbs_poly_t *phymod_poly) 72 { 73 switch(tscf_poly){ 74 case PHY8806X_PRBS_POLYNOMIAL_7: 75 *phymod_poly = phymodPrbsPoly7; 76 break; 77 case PHY8806X_PRBS_POLYNOMIAL_9: 78 *phymod_poly = phymodPrbsPoly9; 79 break; 80 case PHY8806X_PRBS_POLYNOMIAL_11: 81 *phymod_poly = phymodPrbsPoly11; 82 break; 83 case PHY8806X_PRBS_POLYNOMIAL_15: 84 *phymod_poly = phymodPrbsPoly15; 85 break; 86 case PHY8806X_PRBS_POLYNOMIAL_23: 87 *phymod_poly = phymodPrbsPoly23; 88 break; 89 case PHY8806X_PRBS_POLYNOMIAL_31: 90 *phymod_poly = phymodPrbsPoly31; 91 break; 92 case PHY8806X_PRBS_POLYNOMIAL_58: 93 *phymod_poly = phymodPrbsPoly58; 94 break; 95 default: 96 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tscf_poly)); 97 } 98 return PHYMOD_E_NONE; 99 } 100 101 int phy8806x_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 102 { 103 /* Not supported */ 104 PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_set function is NOT SUPPORTED!!\n")); 105 return PHYMOD_E_NONE; 106 } 107 108 int phy8806x_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 109 { 110 /* Not supported */ 111 PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_get function is NOT SUPPORTED!!\n")); 112 return PHYMOD_E_NONE; 113 } 114 115 116 int phy8806x_phy_rx_slicer_position_max_get(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position_min, const phymod_slicer_position_t* position_max) 117 { 118 /* Not supported */ 119 PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_max_get function is NOT SUPPORTED!!\n")); 120 return PHYMOD_E_NONE; 121 } 122 123 124 int phy8806x_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 125 { 126 enum srds_prbs_polynomial_enum phy8806x_poly; 127 128 PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_phymod_to_phy8806x(prbs->poly, &phy8806x_poly)); 129 /*first check which direction */ 130 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 131 PHYMOD_IF_ERR_RETURN 132 (phy8806x_tsc_config_rx_prbs(&phy->access, phy8806x_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 133 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 134 PHYMOD_IF_ERR_RETURN 135 (phy8806x_tsc_config_tx_prbs(&phy->access, phy8806x_poly, prbs->invert)); 136 } else { 137 PHYMOD_IF_ERR_RETURN 138 (phy8806x_tsc_config_rx_prbs(&phy->access, phy8806x_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 139 PHYMOD_IF_ERR_RETURN 140 (phy8806x_tsc_config_tx_prbs(&phy->access, phy8806x_poly, prbs->invert)); 141 } 142 return PHYMOD_E_NONE; 143 } 144 145 int phy8806x_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 146 { 147 phymod_prbs_t config_tmp; 148 phy8806x_prbs_polynomial_type_t tscf_poly; 149 150 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 151 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 152 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_poly_get(&phy->access, &tscf_poly)); 153 PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 154 prbs->invert = config_tmp.invert; 155 prbs->poly = config_tmp.poly; 156 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 157 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert)); 158 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_poly_get(&phy->access, &tscf_poly)); 159 PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 160 prbs->invert = config_tmp.invert; 161 prbs->poly = config_tmp.poly; 162 } else { 163 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 164 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_poly_get(&phy->access, &tscf_poly)); 165 PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 166 prbs->invert = config_tmp.invert; 167 prbs->poly = config_tmp.poly; 168 } 169 return PHYMOD_E_NONE; 170 } 171 172 int phy8806x_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 173 { 174 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 175 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_tx_prbs_en(&phy->access, enable)); 176 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 177 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_rx_prbs_en(&phy->access, enable)); 178 } else { 179 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_tx_prbs_en(&phy->access, enable)); 180 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_rx_prbs_en(&phy->access, enable)); 181 } 182 return PHYMOD_E_NONE; 183 } 184 185 int phy8806x_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 186 { 187 uint32_t enable_tmp; 188 189 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 190 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_enable_get(&phy->access, &enable_tmp)); 191 *enable = enable_tmp; 192 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 193 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_enable_get(&phy->access, &enable_tmp)); 194 *enable = enable_tmp; 195 } else { 196 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_enable_get(&phy->access, &enable_tmp)); 197 *enable = enable_tmp; 198 PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_enable_get(&phy->access, &enable_tmp)); 199 *enable &= enable_tmp; 200 } 201 return PHYMOD_E_NONE; 202 } 203 204 int phy8806x_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 205 { 206 uint8_t status = 0; 207 uint32_t prbs_err_count = 0; 208 209 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_prbs_chk_lock_state(&phy->access, &status)); 210 if (status) { 211 prbs_status->prbs_lock = 1; 212 /*next check the lost of lock and error count */ 213 status = 0; 214 PHYMOD_IF_ERR_RETURN 215 (phy8806x_tsc_prbs_err_count_state(&phy->access, &prbs_err_count, &status)); 216 if (status) { 217 /*temp lost of lock */ 218 prbs_status->prbs_lock_loss = 1; 219 } else { 220 prbs_status->prbs_lock_loss = 0; 221 prbs_status->error_count = prbs_err_count; 222 } 223 } else { 224 prbs_status->prbs_lock = 0; 225 } 226 return PHYMOD_E_NONE; 227 } 228 229 int phy8806x_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 230 { 231 /* Not supported */ 232 PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_config_set function is NOT SUPPORTED!!\n")); 233 return PHYMOD_E_NONE; 234 } 235 236 int phy8806x_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 237 { 238 /* Not supported */ 239 PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_config_get function is NOT SUPPORTED!!\n")); 240 return PHYMOD_E_NONE; 241 } 242 243 int phy8806x_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 244 { 245 /* Not supported */ 246 PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_enable_set function is NOT SUPPORTED!!\n")); 247 return PHYMOD_E_NONE; 248 } 249 250 int phy8806x_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 251 { 252 /* Not supported */ 253 PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_enable_get function is NOT SUPPORTED!!\n")); 254 return PHYMOD_E_NONE; 255 } 256 257 int phy8806x_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 258 { 259 int16_t temperature; 260 261 phy8806x_tsc_read_die_temperature(&core->access, &temperature); 262 diag->temperature = temperature; 263 phy8806x_tsc_read_pll_range(&core->access, &diag->pll_range); 264 265 return PHYMOD_E_NONE; 266 } 267 268 int phy8806x_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag) 269 { 270 unsigned char rx_lock; 271 int osr_mode; 272 phymod_diag_eyescan_t_init(&diag->eyescan); 273 phymod_diag_slicer_offset_t_init(&diag->slicer_offset); 274 275 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_pmd_lock_status(&phy->access, &rx_lock)); 276 diag->rx_lock = (uint32_t ) rx_lock; 277 PHYMOD_IF_ERR_RETURN(phy8806x_osr_mode_get(&phy->access, &osr_mode)); 278 switch(osr_mode) { 279 case 0: diag->osr_mode = phymodOversampleMode1; break; 280 case 1: diag->osr_mode = phymodOversampleMode2; break; 281 case 2: diag->osr_mode = phymodOversampleMode4; break; 282 case 8: diag->osr_mode = phymodOversampleMode16P5; break; 283 case 12: diag->osr_mode = phymodOversampleMode20P625; break; 284 default: 285 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode)); 286 } 287 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_signal_detect(&phy->access, &diag->signal_detect)); 288 return PHYMOD_E_NONE; 289 } 290 291 int phy8806x_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char *type) 292 { 293 int start_lane, num_lane; 294 phymod_phy_access_t phy_copy; 295 struct phy8806x_tsc_detailed_lane_status_st lane_st[4]; 296 int i = 0; 297 int j = 0; 298 uint32_t cmd_type; 299 uint8_t trace_mem[768]; 300 301 #if defined(INCLUDE_PHY_8806X) 302 #ifdef INCLUDE_FCMAP 303 soc_phymod_core_t *soc_core; 304 phy_ctrl_t *pc; 305 #endif 306 #endif 307 308 if (!type) { 309 cmd_type = (uint32_t)TEFMOD_DIAG_STATE; 310 } else if (!PHYMOD_STRCMP(type, "ber")) { 311 cmd_type = (uint32_t)TEFMOD_DIAG_BER; 312 } else if (!PHYMOD_STRCMP(type, "config")) { 313 cmd_type = (uint32_t)TEFMOD_DIAG_CFG; 314 } else if (!PHYMOD_STRCMP(type, "CL72")) { 315 cmd_type = (uint32_t)TEFMOD_DIAG_CL72; 316 } else if (!PHYMOD_STRCMP(type, "debug")) { 317 cmd_type = (uint32_t)TEFMOD_DIAG_DEBUG; 318 } else { 319 cmd_type = (uint32_t)TEFMOD_DIAG_STATE; 320 } 321 322 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 323 324 /*next figure out the lane num and start_lane based on the input*/ 325 PHYMOD_IF_ERR_RETURN 326 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 327 328 #if defined(INCLUDE_PHY_8806X) 329 #ifdef INCLUDE_FCMAP 330 soc_core = PHYMOD_ACC_USER_ACC(&phy->access); 331 pc = EXT_PHY_SW_STATE(soc_core->unit, soc_core->port); 332 if (pc->fcmap_enable && (!(pc->flags & PHYCTRL_SYS_SIDE_CTRL))) { 333 num_lane = 1; 334 } 335 #endif 336 #endif 337 338 for (i = 0; i < num_lane; i++) { 339 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 340 341 switch (cmd_type) { 342 case TEFMOD_DIAG_CFG: 343 PHYMOD_IF_ERR_RETURN 344 (phy8806x_tsc_display_core_config(&phy_copy.access)); 345 PHYMOD_IF_ERR_RETURN 346 (phy8806x_tsc_display_lane_config(&phy_copy.access)); 347 break; 348 349 case TEFMOD_DIAG_CL72: 350 PHYMOD_IF_ERR_RETURN 351 (phy8806x_tsc_display_cl93n72_status(&phy_copy.access)); 352 break; 353 354 case TEFMOD_DIAG_DEBUG: 355 PHYMOD_IF_ERR_RETURN 356 (phy8806x_tsc_display_lane_debug_status(&phy_copy.access)); 357 break; 358 359 case TEFMOD_DIAG_BER: 360 break; 361 362 case TEFMOD_DIAG_STATE: 363 default: 364 PHYMOD_IF_ERR_RETURN 365 (phy8806x_tsc_display_core_state_hdr(&phy_copy.access)); 366 PHYMOD_IF_ERR_RETURN 367 (phy8806x_tsc_display_core_state_line(&phy_copy.access)); 368 PHYMOD_IF_ERR_RETURN 369 (phy8806x_tsc_display_core_state(&phy_copy.access)); 370 PHYMOD_IF_ERR_RETURN 371 (phy8806x_tsc_display_lane_state_hdr(&phy_copy.access)); 372 PHYMOD_IF_ERR_RETURN 373 (phy8806x_tsc_display_lane_state(&phy_copy.access)); 374 for (j = 0; j < 4; j++) { 375 PHYMOD_IF_ERR_RETURN 376 (phy8806x_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 377 } 378 PHYMOD_IF_ERR_RETURN 379 (phy8806x_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 380 PHYMOD_IF_ERR_RETURN 381 (phy8806x_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 382 break; 383 } 384 } 385 386 return PHYMOD_E_NONE; 387 } 388 389 STATIC err_code_t phy8806x_phy_meas_lowber_eye (const phymod_access_t *pa, 390 const phymod_phy_eyescan_options_t* eyescan_options, 391 uint32_t *buffer) 392 { 393 struct phy8806x_tsc_eyescan_options_st e_options; 394 395 e_options.linerate_in_khz = eyescan_options->linerate_in_khz; 396 e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds; 397 e_options.horz_max = eyescan_options->horz_max; 398 e_options.horz_min = eyescan_options->horz_min; 399 e_options.hstep = eyescan_options->hstep; 400 e_options.vert_max = eyescan_options->vert_max; 401 e_options.vert_min = eyescan_options->vert_min; 402 e_options.vstep = eyescan_options->vstep; 403 e_options.mode = eyescan_options->mode; 404 405 return (phy8806x_tsc_meas_lowber_eye(pa, e_options, buffer)); 406 } 407 408 STATIC err_code_t phy8806x_phy_display_lowber_eye (const phymod_access_t *pa, 409 const phymod_phy_eyescan_options_t* eyescan_options, 410 uint32_t *buffer) 411 { 412 struct phy8806x_tsc_eyescan_options_st e_options; 413 414 e_options.linerate_in_khz = eyescan_options->linerate_in_khz; 415 e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds; 416 e_options.horz_max = eyescan_options->horz_max; 417 e_options.horz_min = eyescan_options->horz_min; 418 e_options.hstep = eyescan_options->hstep; 419 e_options.vert_max = eyescan_options->vert_max*2; 420 e_options.vert_min = eyescan_options->vert_min*2; 421 e_options.vstep = eyescan_options->vstep*2; 422 e_options.mode = eyescan_options->mode; 423 424 return(phy8806x_tsc_display_lowber_eye (pa, e_options, buffer)); 425 } 426 427 static void _phy8806x_diag_uc_reg_dump(const phymod_access_t *pa) 428 { 429 err_code_t errc; 430 431 COMPILER_REFERENCE(errc); 432 433 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 434 PHYMOD_DIAG_OUT(("| MICRO CODE USR CTRL CONFIGURATION REGISTERS |\n")); 435 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 436 PHYMOD_DIAG_OUT(("| config_word [0x00]: 0x%04X |\n", phy8806x_tsc_rdwl_uc_var(pa,&errc,0x0))); 437 PHYMOD_DIAG_OUT(("| retune_after_restart [0x02]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x2))); 438 PHYMOD_DIAG_OUT(("| clk90_offset_adjust [0x03]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x3))); 439 PHYMOD_DIAG_OUT(("| clk90_offset_override [0x04]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x4))); 440 PHYMOD_DIAG_OUT(("| lane_event_log_level [0x05]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x5))); 441 PHYMOD_DIAG_OUT(("| disable_startup [0x06]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x6))); 442 PHYMOD_DIAG_OUT(("| disable_startup_dfe [0x07]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x7))); 443 PHYMOD_DIAG_OUT(("| disable_steady_state [0x08]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x8))); 444 PHYMOD_DIAG_OUT(("| disable_steady_state_dfe [0x09]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x9))); 445 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 446 PHYMOD_DIAG_OUT(("| MICRO CODE USER STATUS REGISTERS |\n")); 447 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 448 PHYMOD_DIAG_OUT(("| restart_counter [0x0A]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xa))); 449 PHYMOD_DIAG_OUT(("| reset_counter [0x0B]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xb))); 450 PHYMOD_DIAG_OUT(("| pmd_lock_counter [0x0C]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xc))); 451 PHYMOD_DIAG_OUT(("| heye_left [0x0D]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xd))); 452 PHYMOD_DIAG_OUT(("| heye_left_lsbyte [0x0E]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xe))); 453 PHYMOD_DIAG_OUT(("| heye_right [0x0F]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0xf))); 454 PHYMOD_DIAG_OUT(("| heye_right_lsbyte [0x10]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x10))); 455 PHYMOD_DIAG_OUT(("| veye_upper [0x11]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x11))); 456 PHYMOD_DIAG_OUT(("| veye_upper_lsbyte [0x12]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x12))); 457 PHYMOD_DIAG_OUT(("| veye_lower [0x13]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x13))); 458 PHYMOD_DIAG_OUT(("| veye_lower_lsbyte [0x14]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x14))); 459 PHYMOD_DIAG_OUT(("| micro_stopped [0x15]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x15))); 460 PHYMOD_DIAG_OUT(("| link_time [0x16]: 0x%04X |\n", phy8806x_tsc_rdwl_uc_var(pa,&errc,0x16))); 461 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 462 PHYMOD_DIAG_OUT(("| MICRO CODE MISC REGISTERS |\n")); 463 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 464 PHYMOD_DIAG_OUT(("| usr_diag_status [0x18]: 0x%04X |\n", phy8806x_tsc_rdwl_uc_var(pa,&errc,0x18))); 465 PHYMOD_DIAG_OUT(("| usr_diag_rd_ptr [0x1A]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x1a))); 466 PHYMOD_DIAG_OUT(("| usr_diag_mode [0x1B]: 0x%04X |\n", phy8806x_tsc_rdbl_uc_var(pa,&errc,0x1b))); 467 PHYMOD_DIAG_OUT(("| usr_var_msb [0x1C]: 0x%04X |\n", phy8806x_tsc_rdwl_uc_var(pa,&errc,0x1c))); 468 PHYMOD_DIAG_OUT(("| usr_var_lsb [0x1E]: 0x%04X |\n", phy8806x_tsc_rdwl_uc_var(pa,&errc,0x1e))); 469 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 470 } 471 472 STATIC int phy8806x_diagnostics_eyescan_run_uc(const phymod_phy_access_t* phy, uint32_t flags) 473 { 474 int ii, rc = PHYMOD_E_NONE; 475 uint32_t stripe[64]; 476 uint16_t status; 477 int j ; 478 phymod_phy_access_t phy_copy; 479 480 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 481 482 for(j=0; j< PHYMOD_CONFIG_MAX_LANES_PER_CORE; j++) { /* Loop for all lanes. */ 483 if ((phy->access.lane_mask & (1<<j))==0) continue; 484 485 phy_copy.access.lane_mask = (phy->access.lane_mask & (1<<j)); 486 487 if(PHYMOD_EYESCAN_F_ENABLE_GET(flags)) { 488 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_meas_eye_scan_start(&(phy_copy.access), 0)); 489 490 if(!PHYMOD_EYESCAN_F_ENABLE_DONT_WAIT_GET(flags)) { 491 PHYMOD_USLEEP(100000); 492 } 493 } 494 495 if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) { 496 497 for (ii = 62; ii >= -62; ii=ii-2) { 498 if (ii == 62) { 499 PHYMOD_DIAG_OUT(("\n\n\n")); 500 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 501 PHYMOD_DIAG_OUT((" | EYESCAN Phy: 0x%03x lane_mask: 0x%02x |\n", phy_copy.access.addr, phy_copy.access.lane_mask)); 502 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 503 /*display eyescan header*/ 504 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_header(&(phy_copy.access), 1)); 505 } 506 507 rc = phy8806x_tsc_read_eye_scan_stripe(&(phy_copy.access), stripe, &status); 508 if(rc != PHYMOD_E_NONE) { 509 _phy8806x_diag_uc_reg_dump(&(phy_copy.access)); 510 PHYMOD_IF_ERR_RETURN(rc); 511 } 512 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_stripe(&(phy_copy.access), ii, &stripe[0])); 513 514 PHYMOD_DIAG_OUT(("\n")); 515 } 516 517 if (rc == PHYMOD_E_NONE) { 518 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_footer(&(phy_copy.access), 1)); 519 PHYMOD_DIAG_OUT(("\n")); 520 } 521 } 522 523 if(PHYMOD_EYESCAN_F_DONE_GET(flags)) { 524 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_meas_eye_scan_done(&(phy_copy.access))); 525 } 526 } 527 return PHYMOD_E_NONE; 528 } 529 530 STATIC int phy8806x_diagnostics_eyescan_run_lowber( 531 const phymod_phy_access_t* phy, 532 uint32_t flags, 533 const phymod_phy_eyescan_options_t* eyescan_options 534 ) 535 { 536 uint32_t *buffer; 537 int buffer_size = 64*64; 538 int rv = PHYMOD_E_NONE; 539 540 buffer = PHYMOD_MALLOC(sizeof(uint32_t) * buffer_size, "buffer"); 541 if (NULL == buffer) { 542 return PHYMOD_E_MEMORY; 543 } 544 PHYMOD_MEMSET(buffer, 0, sizeof(uint32_t) * buffer_size); 545 546 /*enable eyescan*/ 547 if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) { 548 549 rv = phy8806x_phy_meas_lowber_eye (&(phy->access), eyescan_options, buffer); 550 if (rv < 0) { 551 goto cleanup; 552 } 553 rv = phy8806x_phy_display_lowber_eye (&(phy->access), eyescan_options, buffer); 554 if (rv < 0) { 555 goto cleanup; 556 } 557 } 558 if (buffer != NULL) { 559 PHYMOD_FREE(buffer); 560 } 561 562 if(PHYMOD_EYESCAN_F_DONE_GET(flags)) { 563 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_pmd_uc_cmd(&(phy->access), CMD_CAPTURE_BER_END, 0, 2000)); 564 } 565 566 return PHYMOD_E_NONE; 567 568 cleanup: 569 if (buffer != NULL) { 570 PHYMOD_FREE(buffer); 571 } 572 573 return rv; 574 } 575 576 int phy8806x_phy_eyescan_run(const phymod_phy_access_t* phy, 577 uint32_t flags, 578 phymod_eyescan_mode_t mode, 579 const phymod_phy_eyescan_options_t* eyescan_options) 580 { 581 uint8_t pmd_rx_lock=0; 582 583 PHYMOD_IF_ERR_RETURN 584 (phy8806x_tsc_pmd_lock_status(&phy->access, &pmd_rx_lock)); 585 if(pmd_rx_lock == 0) { 586 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Can not get eyescan when pmd_rx is not locked\n"))); 587 } 588 589 /* If stage isn't set - perform all stages*/ 590 if(!PHYMOD_EYESCAN_F_ENABLE_GET(flags) 591 && !PHYMOD_EYESCAN_F_PROCESS_GET(flags) 592 && !PHYMOD_EYESCAN_F_DONE_GET(flags)) 593 { 594 PHYMOD_EYESCAN_F_ENABLE_SET(flags); 595 PHYMOD_EYESCAN_F_PROCESS_SET(flags); 596 PHYMOD_EYESCAN_F_DONE_SET(flags); 597 } 598 599 switch(mode) { 600 case phymodEyescanModeFast: 601 return phy8806x_diagnostics_eyescan_run_uc(phy, flags); 602 case phymodEyescanModeLowBER: 603 return phy8806x_diagnostics_eyescan_run_lowber(phy, flags, eyescan_options); 604 default: 605 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported eyescan mode %u"), mode)); 606 } 607 } 608 609 610 #endif /* PHYMOD_PHY8806X_SUPPORT */