tscbh_diagnostics.c (25397B)
1 2 /* 3 * 4 * 5 * 6 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 7 * 8 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 9 */ 10 11 #include <phymod/phymod.h> 12 #include <phymod/phymod_system.h> 13 #include <phymod/phymod_util.h> 14 #include <phymod/phymod_config.h> 15 #include <phymod/phymod_diagnostics.h> 16 #include <phymod/phymod_diagnostics_dispatch.h> 17 #include <phymod/phymod_acc.h> 18 #include <phymod/chip/tscbh.h> 19 #include <phymod/chip/tscbh_diagnostics.h> 20 21 #include "blackhawk/tier1/blackhawk_cfg_seq.h" 22 #include "blackhawk/tier1/common/srds_api_enum.h" 23 #include "blackhawk/tier1/blackhawk_tsc_enum.h" 24 #include "blackhawk/tier1/blackhawk_tsc_common.h" 25 #include "blackhawk/tier1/blackhawk_tsc_interface.h" 26 #include "blackhawk/tier1/blackhawk_tsc_dependencies.h" 27 #include "blackhawk/tier1/blackhawk_tsc_internal.h" 28 #include "blackhawk/tier1/public/blackhawk_api_uc_vars_rdwr_defns_public.h" 29 #include "blackhawk/tier1/blackhawk_tsc_access.h" 30 #include "blackhawk/tier1/blackhawk_tsc_types.h" 31 #include "tscbh/tier1/tbhmod.h" 32 33 34 #define PATTERN_MAX_LENGTH 240 35 #ifdef PHYMOD_BLACKHAWK_SUPPORT 36 37 38 /*phymod, internal enum mappings*/ 39 STATIC 40 int _tscbh_prbs_poly_phymod_to_blackhawk(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *blackhawk_poly) 41 { 42 switch(phymod_poly){ 43 case phymodPrbsPoly7: 44 *blackhawk_poly = PRBS_7; 45 break; 46 case phymodPrbsPoly9: 47 *blackhawk_poly = PRBS_9; 48 break; 49 case phymodPrbsPoly11: 50 *blackhawk_poly = PRBS_11; 51 break; 52 case phymodPrbsPoly15: 53 *blackhawk_poly = PRBS_15; 54 break; 55 case phymodPrbsPoly23: 56 *blackhawk_poly = PRBS_23; 57 break; 58 case phymodPrbsPoly31: 59 *blackhawk_poly = PRBS_31; 60 break; 61 case phymodPrbsPoly58: 62 *blackhawk_poly = PRBS_58; 63 break; 64 case phymodPrbsPoly49: 65 *blackhawk_poly = PRBS_49; 66 break; 67 case phymodPrbsPoly10: 68 *blackhawk_poly = PRBS_10; 69 break; 70 case phymodPrbsPoly20: 71 *blackhawk_poly = PRBS_20; 72 break; 73 case phymodPrbsPoly13: 74 *blackhawk_poly = PRBS_13; 75 break; 76 default: 77 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly)); 78 } 79 return PHYMOD_E_NONE; 80 } 81 82 STATIC 83 int _tscbh_prbs_poly_tscbh_to_phymod(enum srds_prbs_polynomial_enum *blackhawk_poly, phymod_prbs_poly_t *phymod_poly) 84 { 85 switch(*blackhawk_poly){ 86 case PRBS_7: 87 *phymod_poly = phymodPrbsPoly7; 88 break; 89 case PRBS_9: 90 *phymod_poly = phymodPrbsPoly9; 91 break; 92 case PRBS_11: 93 *phymod_poly = phymodPrbsPoly11; 94 break; 95 case PRBS_15: 96 *phymod_poly = phymodPrbsPoly15; 97 break; 98 case PRBS_23: 99 *phymod_poly = phymodPrbsPoly23; 100 break; 101 case PRBS_31: 102 *phymod_poly = phymodPrbsPoly31; 103 break; 104 case PRBS_58: 105 *phymod_poly = phymodPrbsPoly58; 106 break; 107 case PRBS_49: 108 *phymod_poly = phymodPrbsPoly49; 109 break; 110 case PRBS_10: 111 *phymod_poly = phymodPrbsPoly10; 112 break; 113 case PRBS_20: 114 *phymod_poly = phymodPrbsPoly20; 115 break; 116 case PRBS_13: 117 *phymod_poly = phymodPrbsPoly13; 118 break; 119 default: 120 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), *blackhawk_poly)); 121 } 122 return PHYMOD_E_NONE; 123 } 124 125 126 int tscbh_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 127 { 128 /* Not supported */ 129 PHYMOD_DEBUG_ERROR(("tscbh_phy_rx_slicer_position_set function is NOT SUPPORTED!!\n")); 130 131 return PHYMOD_E_NONE; 132 } 133 134 int tscbh_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 135 { 136 /* Not supported */ 137 PHYMOD_DEBUG_ERROR(("tscbh_phy_rx_slicer_position_get function is NOT SUPPORTED!!\n")); 138 139 return PHYMOD_E_NONE; 140 } 141 142 143 int tscbh_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) 144 { 145 /* Not supported */ 146 PHYMOD_DEBUG_ERROR(("tscbh_phy_rx_slicer_position_max_get function is NOT SUPPORTED!!\n")); 147 148 return PHYMOD_E_NONE; 149 } 150 151 152 int tscbh_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 153 { 154 enum srds_prbs_polynomial_enum blackhawk_poly; 155 phymod_phy_access_t phy_copy; 156 int start_lane, num_lane, i; 157 phymod_firmware_lane_config_t fw_config; 158 159 PHYMOD_IF_ERR_RETURN 160 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 161 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 162 163 /* next to see if the port is PAM4 or not */ 164 PHYMOD_IF_ERR_RETURN 165 (tscbh_phy_firmware_lane_config_get(phy, &fw_config)); 166 167 PHYMOD_IF_ERR_RETURN(_tscbh_prbs_poly_phymod_to_blackhawk(prbs->poly, &blackhawk_poly)); 168 /*first check which direction */ 169 for (i = 0; i < num_lane; i++) { 170 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 171 continue; 172 } 173 phy_copy.access.lane_mask = 1 << (start_lane + i); 174 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 175 /* if PAM4 speed, use mode 2 */ 176 if (fw_config.ForcePAM4Mode) { 177 PHYMOD_IF_ERR_RETURN 178 (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_NO_HYSTERESIS, prbs->invert)); 179 } else { 180 PHYMOD_IF_ERR_RETURN 181 (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 182 } 183 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 184 PHYMOD_IF_ERR_RETURN 185 (blackhawk_tsc_config_tx_prbs(&phy_copy.access, blackhawk_poly, prbs->invert)); 186 } else { 187 /* if PAM4 speed, use mode 2 */ 188 if (fw_config.ForcePAM4Mode) { 189 PHYMOD_IF_ERR_RETURN 190 (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_NO_HYSTERESIS, prbs->invert)); 191 } else { 192 PHYMOD_IF_ERR_RETURN 193 (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 194 } 195 PHYMOD_IF_ERR_RETURN 196 (blackhawk_tsc_config_tx_prbs(&phy_copy.access, blackhawk_poly, prbs->invert)); 197 } 198 } 199 return PHYMOD_E_NONE; 200 } 201 202 int tscbh_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 203 { 204 phymod_prbs_t config_tmp; 205 enum srds_prbs_polynomial_enum blackhawk_poly; 206 enum srds_prbs_checker_mode_enum prbs_checker_mode; 207 phymod_phy_access_t phy_copy; 208 uint8_t invert; 209 210 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 211 212 213 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 214 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_config(&phy_copy.access, &blackhawk_poly, &invert)); 215 config_tmp.invert = invert; 216 PHYMOD_IF_ERR_RETURN(_tscbh_prbs_poly_tscbh_to_phymod(&blackhawk_poly, &config_tmp.poly)); 217 prbs->invert = config_tmp.invert; 218 prbs->poly = config_tmp.poly; 219 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 220 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_config(&phy_copy.access, 221 &blackhawk_poly, 222 &prbs_checker_mode, 223 &invert)); 224 config_tmp.invert = invert; 225 PHYMOD_IF_ERR_RETURN(_tscbh_prbs_poly_tscbh_to_phymod(&blackhawk_poly, &config_tmp.poly)); 226 prbs->invert = config_tmp.invert; 227 prbs->poly = config_tmp.poly; 228 } else { 229 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_config(&phy_copy.access, &blackhawk_poly, &invert)); 230 config_tmp.invert = invert; 231 PHYMOD_IF_ERR_RETURN(_tscbh_prbs_poly_tscbh_to_phymod(&blackhawk_poly, &config_tmp.poly)); 232 prbs->invert = config_tmp.invert; 233 prbs->poly = config_tmp.poly; 234 } 235 return PHYMOD_E_NONE; 236 } 237 238 int tscbh_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 239 { 240 phymod_phy_access_t phy_copy; 241 int start_lane, num_lane, i; 242 243 PHYMOD_IF_ERR_RETURN 244 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 245 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 246 247 /*first check which direction */ 248 for (i = 0; i < num_lane; i++) { 249 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 250 continue; 251 } 252 phy_copy.access.lane_mask = 1 << (start_lane + i); 253 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 254 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_prbs_en(&phy_copy.access, enable)); 255 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 256 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rx_prbs_en(&phy_copy.access, enable)); 257 } else { 258 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_prbs_en(&phy_copy.access, enable)); 259 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rx_prbs_en(&phy_copy.access, enable)); 260 } 261 } 262 return PHYMOD_E_NONE; 263 } 264 265 int tscbh_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 266 { 267 uint8_t enable_tmp; 268 phymod_phy_access_t phy_copy; 269 270 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 271 272 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 273 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_en(&phy_copy.access, &enable_tmp)); 274 *enable = enable_tmp; 275 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 276 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_en(&phy_copy.access, &enable_tmp)); 277 *enable = enable_tmp; 278 } else { 279 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_en(&phy_copy.access, &enable_tmp)); 280 *enable = enable_tmp; 281 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_en(&phy_copy.access, &enable_tmp)); 282 *enable &= enable_tmp; 283 } 284 285 return PHYMOD_E_NONE; 286 } 287 288 289 int tscbh_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 290 { 291 uint8_t status = 0; 292 uint32_t prbs_err_count = 0; 293 int i, start_lane, num_lane; 294 phymod_phy_access_t phy_copy; 295 296 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 297 /* next figure out the lane num and start_lane based on the input */ 298 PHYMOD_IF_ERR_RETURN 299 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 300 301 prbs_status->prbs_lock = 0; 302 prbs_status->error_count = 0; 303 prbs_status->prbs_lock_loss = 0; 304 prbs_status->prbs_lock = 1; 305 306 for (i = 0; i < num_lane; i++) { 307 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 308 continue; 309 } 310 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 311 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_prbs_chk_lock_state(&phy_copy.access, &status)); 312 if (status) { 313 /*next check the lost of lock and error count */ 314 status = 0; 315 PHYMOD_IF_ERR_RETURN 316 (blackhawk_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 317 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count)); 318 if (status) { 319 /*temp lost of lock */ 320 prbs_status->prbs_lock_loss = 1; 321 } else { 322 prbs_status->error_count += prbs_err_count; 323 } 324 } else { 325 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i )); 326 prbs_status->prbs_lock = 0; 327 /* return PHYMOD_E_NONE; */ 328 } 329 } 330 return PHYMOD_E_NONE; 331 } 332 333 #if 0 334 int tscbh_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 335 { 336 phymod_phy_access_t phy_copy; 337 338 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 339 340 PHYMOD_IF_ERR_RETURN 341 (blackhawk_tsc_config_shared_tx_pattern (&phy_copy.access, 342 (uint8_t) pattern->pattern_len, (const char *) pattern->pattern)); 343 return PHYMOD_E_NONE; 344 } 345 346 int tscbh_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 347 { 348 phymod_phy_access_t phy_copy; 349 350 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 351 PHYMOD_IF_ERR_RETURN 352 (blackhawk_tsc_config_shared_tx_pattern_idx_get(&phy_copy.access, 353 &pattern->pattern_len, 354 pattern->pattern)); 355 return PHYMOD_E_NONE; 356 } 357 358 359 int tscbh_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, const phymod_pattern_t* pattern) 360 { 361 phymod_phy_access_t phy_copy; 362 363 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 364 PHYMOD_IF_ERR_RETURN 365 (blackhawk_tsc_tx_shared_patt_gen_en(&phy_copy.access, (uint8_t) enable, (uint8_t)pattern->pattern_len)); 366 return PHYMOD_E_NONE; 367 } 368 369 int tscbh_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 370 { 371 phymod_phy_access_t phy_copy; 372 373 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 374 PHYMOD_IF_ERR_RETURN 375 (blackhawk_tsc_tx_shared_patt_gen_en_get(&phy_copy.access, (uint8_t *) enable)); 376 return PHYMOD_E_NONE; 377 } 378 379 #endif 380 381 int tscbh_phy_fec_cl91_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 382 { 383 phymod_phy_access_t phy_copy; 384 385 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 386 PHYMOD_IF_ERR_RETURN 387 (tbhmod_fec_correctable_counter_get(&phy_copy.access, count)); 388 return PHYMOD_E_NONE; 389 } 390 391 int tscbh_phy_fec_cl91_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 392 { 393 phymod_phy_access_t phy_copy; 394 395 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 396 PHYMOD_IF_ERR_RETURN 397 (tbhmod_fec_uncorrectable_counter_get(&phy_copy.access, count)); 398 return PHYMOD_E_NONE; 399 400 } 401 402 403 int tscbh_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 404 { 405 406 return PHYMOD_E_NONE; 407 } 408 409 410 int tscbh_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag) 411 { 412 413 return PHYMOD_E_NONE; 414 } 415 416 static void _tscbh_diag_uc_reg_dump(phymod_access_t *pa) 417 { 418 err_code_t errc; 419 420 COMPILER_REFERENCE(errc); 421 422 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 423 PHYMOD_DIAG_OUT(("| MICRO CODE USR CTRL CONFIGURATION REGISTERS |\n")); 424 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 425 PHYMOD_DIAG_OUT(("| config_word [0x00]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0x0))); 426 PHYMOD_DIAG_OUT(("| usr_misc_ctrl_word [0x04]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0x4))); 427 PHYMOD_DIAG_OUT(("| retune_after_restart [0x06]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x6))); 428 PHYMOD_DIAG_OUT(("| clk90_offset_adjust [0x07]: 0x%04X |\n", blackhawk_tsc_rdbls_uc_var(pa,&errc,0x7))); 429 PHYMOD_DIAG_OUT(("| clk90_offset_override [0x08]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x8))); 430 PHYMOD_DIAG_OUT(("| lane_event_log_level [0x09]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x9))); 431 PHYMOD_DIAG_OUT(("| pam4_chn_loss [0x0A]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0xa))); 432 PHYMOD_DIAG_OUT(("| cl93n72_frc_byte [0x0B]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0xb))); 433 PHYMOD_DIAG_OUT(("| disable_startup [0x0C]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0xc))); 434 PHYMOD_DIAG_OUT(("| disable_steady_state [0x0E]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0xe))); 435 PHYMOD_DIAG_OUT(("| disable_startup_dfe [0x10]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x10))); 436 PHYMOD_DIAG_OUT(("| disable_steady_state_dfe [0x11]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x11))); 437 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 438 PHYMOD_DIAG_OUT(("| MICRO CODE USER STATUS REGISTERS |\n")); 439 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 440 PHYMOD_DIAG_OUT(("| restart_counter [0x12]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x12))); 441 PHYMOD_DIAG_OUT(("| reset_counter [0x13]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x13))); 442 PHYMOD_DIAG_OUT(("| pmd_lock_counter [0x14]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x14))); 443 PHYMOD_DIAG_OUT(("| heye_left [0x15]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x15))); 444 PHYMOD_DIAG_OUT(("| heye_right [0x16]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x16))); 445 PHYMOD_DIAG_OUT(("| veye_upper [0x17]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x17))); 446 PHYMOD_DIAG_OUT(("| veye_lower [0x18]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x18))); 447 PHYMOD_DIAG_OUT(("| micro_stopped [0x19]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x19))); 448 PHYMOD_DIAG_OUT(("| link_time [0x1C]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0x1c))); 449 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 450 PHYMOD_DIAG_OUT(("| MICRO CODE MISC REGISTERS |\n")); 451 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 452 PHYMOD_DIAG_OUT(("| usr_diag_status [0x1E]: 0x%04X |\n", blackhawk_tsc_rdwl_uc_var(pa,&errc,0x1e))); 453 PHYMOD_DIAG_OUT(("| usr_diag_rd_ptr [0x20]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x20))); 454 PHYMOD_DIAG_OUT(("| usr_diag_mode [0x21]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x21))); 455 PHYMOD_DIAG_OUT(("| usr_main_tap_est [0x22]: 0x%04X |\n", blackhawk_tsc_rdwls_uc_var(pa,&errc,0x22))); 456 PHYMOD_DIAG_OUT(("| usr_sts_phase_hoffset [0x24]: 0x%04X |\n", blackhawk_tsc_rdbls_uc_var(pa,&errc,0x24))); 457 PHYMOD_DIAG_OUT(("| usr_diag_wr_ptr [0x25]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x25))); 458 PHYMOD_DIAG_OUT(("| status_byte [0x26]: 0x%04X |\n", blackhawk_tsc_rdbl_uc_var(pa,&errc,0x26))); 459 PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n")); 460 } 461 462 STATIC int tscbh_diagnostics_eyescan_run_uc(const phymod_phy_access_t* phy, uint32_t flags) 463 { 464 int rc = PHYMOD_E_NONE; 465 int j ; 466 phymod_phy_access_t phy_copy; 467 468 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 469 470 if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) { 471 for(j=0; j< PHYMOD_CONFIG_MAX_LANES_PER_CORE; j++) { /* Loop for all lanes. */ 472 if ((phy->access.lane_mask & (1<<j))==0) continue; 473 474 phy_copy.access.lane_mask = (phy->access.lane_mask & (1<<j)); 475 476 PHYMOD_DIAG_OUT(("\n\n\n")); 477 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 478 PHYMOD_DIAG_OUT((" | EYESCAN Phy: 0x%03x lane_mask: 0x%02x |\n", phy_copy.access.addr, phy_copy.access.lane_mask)); 479 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 480 481 rc = blackhawk_tsc_display_eye_scan(&(phy_copy.access)); 482 if(rc != PHYMOD_E_NONE) { 483 _tscbh_diag_uc_reg_dump(&(phy_copy.access)); 484 PHYMOD_IF_ERR_RETURN(rc); 485 } 486 } 487 } 488 return PHYMOD_E_NONE; 489 } 490 491 STATIC int tscbh_diagnostics_eye_margin_proj( const phymod_phy_access_t* phy, uint32_t flags, 492 const phymod_phy_eyescan_options_t* eyescan_options) 493 { 494 #ifdef SERDES_API_FLOATING_POINT 495 int osr_mode; 496 USR_DOUBLE data_rate, data_rate_in_Mhz; 497 phymod_phy_access_t phy_copy; 498 int start_lane, num_lane, i, found=0; 499 phymod_phy_speed_config_t speed_config; 500 501 struct blackhawk_tsc_uc_core_config_st core_cfg; 502 if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) { 503 PHYMOD_IF_ERR_RETURN 504 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 505 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 506 for (i = 0; i < num_lane; i++) { 507 phy_copy.access.lane_mask = 1 << (start_lane + i); 508 509 if (found == 0) { 510 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_uc_core_config(&(phy_copy.access), &core_cfg)); 511 PHYMOD_IF_ERR_RETURN(blackhawk_osr_mode_get(&phy_copy.access, &osr_mode)); 512 PHYMOD_IF_ERR_RETURN(tscbh_phy_speed_config_get(phy, &speed_config)); 513 data_rate = speed_config.data_rate * 1000.0 * 1000.0; 514 data_rate = data_rate * 66 / 64 / num_lane; 515 data_rate_in_Mhz= data_rate / 1000.0 / 1000.0; 516 found = 1; 517 } 518 if(num_lane > 1) { 519 PHYMOD_DIAG_OUT((" l=%0d, baud rate = %fMB/s \n", i, data_rate_in_Mhz)); 520 } else { 521 PHYMOD_DIAG_OUT((" baud rate = %fMB/s \n", data_rate_in_Mhz)); 522 } 523 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_eye_margin_proj(&phy_copy.access, data_rate, eyescan_options->ber_proj_scan_mode, 524 eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt)); 525 } 526 } 527 #else 528 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("BER Proj is supported with SERDES_API_FLOATING_POINT only\n"))); 529 #endif 530 531 return PHYMOD_E_NONE; 532 } 533 534 int tscbh_phy_eyescan_run(const phymod_phy_access_t* phy, 535 uint32_t flags, 536 phymod_eyescan_mode_t mode, 537 const phymod_phy_eyescan_options_t* eyescan_options) 538 { 539 uint8_t pmd_rx_lock=0; 540 phymod_phy_access_t phy_copy; 541 542 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 543 544 PHYMOD_IF_ERR_RETURN 545 (blackhawk_tsc_pmd_lock_status(&phy_copy.access, &pmd_rx_lock)); 546 547 if(pmd_rx_lock == 0) { 548 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Can not get eyescan when pmd_rx is not locked\n"))); 549 } 550 551 /* If stage isn't set - perform all stages*/ 552 if(!PHYMOD_EYESCAN_F_ENABLE_GET(flags) 553 && !PHYMOD_EYESCAN_F_PROCESS_GET(flags) 554 && !PHYMOD_EYESCAN_F_DONE_GET(flags)) 555 { 556 PHYMOD_EYESCAN_F_ENABLE_SET(flags); 557 PHYMOD_EYESCAN_F_PROCESS_SET(flags); 558 PHYMOD_EYESCAN_F_DONE_SET(flags); 559 } 560 561 /* mode phymodEyescanModeBERProj gives BER projection */ 562 switch(mode) { 563 case phymodEyescanModeFast: 564 return tscbh_diagnostics_eyescan_run_uc(phy, flags); 565 case phymodEyescanModeBERProj: 566 return tscbh_diagnostics_eye_margin_proj(phy, flags, eyescan_options); 567 default: 568 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported eyescan mode %u"), mode)); 569 } 570 571 return PHYMOD_E_NONE; 572 } 573 574 /* Get RS FEC symbol error count.*/ 575 int tscbh_phy_rsfec_symbol_error_counter_get(const phymod_phy_access_t* phy, 576 int max_count, 577 int* actual_count, 578 uint32_t* error_count) 579 { 580 phymod_phy_access_t phy_copy; 581 int start_lane, num_lane, speed_id, i; 582 spd_id_tbl_entry_t speed_config_entry; 583 uint32_t packed_entry[5]; 584 585 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 586 PHYMOD_IF_ERR_RETURN 587 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 588 589 phy_copy.access.lane_mask = 0x1 << start_lane; 590 /* first read speed id from resolved status */ 591 PHYMOD_IF_ERR_RETURN 592 (tbhmod_speed_id_get(&phy_copy.access, &speed_id)); 593 594 /* first read the speed entry and then decode the speed and FEC type */ 595 phy_copy.access.lane_mask = 1 << 0; 596 PHYMOD_IF_ERR_RETURN 597 (phymod_mem_read(&phy_copy.access, phymodMemSpeedIdTable, speed_id, packed_entry)); 598 599 /*decode speed entry */ 600 spd_ctrl_unpack_spd_id_tbl_entry(packed_entry, &speed_config_entry); 601 602 switch (speed_config_entry.num_lanes) { 603 case 0: num_lane = 1; 604 break; 605 case 1: num_lane = 2; 606 break; 607 case 2: num_lane = 4; 608 break; 609 case 3: num_lane = 8; 610 break; 611 case 4: num_lane = 3; 612 break; 613 case 5: num_lane = 6; 614 break; 615 case 6: num_lane = 7; 616 break; 617 default: 618 PHYMOD_DEBUG_ERROR(("Unsupported number of lane \n")); 619 return PHYMOD_E_UNAVAIL; 620 } 621 622 /* Update lane mask. During AN, lane mask might change. */ 623 phy_copy.access.lane_mask = 0; 624 for (i = 0; i < num_lane; i ++) { 625 phy_copy.access.lane_mask |= 1 << (start_lane + i); 626 } 627 628 PHYMOD_IF_ERR_RETURN 629 (tbhmod_rsfec_symbol_error_counter_get(&phy_copy.access, 630 speed_config_entry.bit_mux_mode, 631 max_count, 632 actual_count, 633 error_count)); 634 635 return PHYMOD_E_NONE; 636 } 637 #endif /* PHYMOD_BLACKHAWK_SUPPORT */