qsgmiie_diagnostics.c (16007B)
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 #include <phymod/chip/eagle_diagnostics.h> 17 18 #include "../tier1/tqmod_cfg_seq.h" 19 #include "../../tsce/tier1/temod_enum_defines.h" 20 #include "../../tsce/tier1/temod.h" 21 #include "../../tsce/tier1/tePCSRegEnums.h" 22 #include "../../eagle/tier1/eagle_cfg_seq.h" 23 #include "../../eagle/tier1/eagle_tsc_interface.h" 24 #include "../../eagle/tier1/eagle_tsc_dependencies.h" 25 #include "../../eagle/tier1/eagle_tsc_debug_functions.h" 26 27 #ifdef PHYMOD_QSGMIIE_SUPPORT 28 29 int qsgmiie_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 30 { 31 32 33 /* Place your code here */ 34 35 36 return PHYMOD_E_NONE; 37 38 } 39 40 int qsgmiie_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 41 { 42 43 44 /* Place your code here */ 45 46 47 return PHYMOD_E_NONE; 48 49 } 50 51 52 int qsgmiie_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) 53 { 54 55 56 /* Place your code here */ 57 58 59 return PHYMOD_E_NONE; 60 61 } 62 63 STATIC 64 int _qsgmiie_prbs_poly_phymod_to_eagle(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *eagle_poly) 65 { 66 switch(phymod_poly){ 67 case phymodPrbsPoly7: 68 *eagle_poly = PRBS_7; 69 break; 70 case phymodPrbsPoly9: 71 *eagle_poly = PRBS_9; 72 break; 73 case phymodPrbsPoly11: 74 *eagle_poly = PRBS_11; 75 break; 76 case phymodPrbsPoly15: 77 *eagle_poly = PRBS_15; 78 break; 79 case phymodPrbsPoly23: 80 *eagle_poly = PRBS_23; 81 break; 82 case phymodPrbsPoly31: 83 *eagle_poly = PRBS_31; 84 break; 85 case phymodPrbsPoly58: 86 *eagle_poly = PRBS_58; 87 break; 88 default: 89 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tsce %u"), phymod_poly)); 90 } 91 return PHYMOD_E_NONE; 92 } 93 94 STATIC 95 int _qsgmiie_prbs_poly_tsce_to_phymod(eagle_prbs_polynomial_type_t tsce_poly, phymod_prbs_poly_t *phymod_poly) 96 { 97 switch(tsce_poly){ 98 case EAGLE_PRBS_POLYNOMIAL_7: 99 *phymod_poly = phymodPrbsPoly7; 100 break; 101 case EAGLE_PRBS_POLYNOMIAL_9: 102 *phymod_poly = phymodPrbsPoly9; 103 break; 104 case EAGLE_PRBS_POLYNOMIAL_11: 105 *phymod_poly = phymodPrbsPoly11; 106 break; 107 case EAGLE_PRBS_POLYNOMIAL_15: 108 *phymod_poly = phymodPrbsPoly15; 109 break; 110 case EAGLE_PRBS_POLYNOMIAL_23: 111 *phymod_poly = phymodPrbsPoly23; 112 break; 113 case EAGLE_PRBS_POLYNOMIAL_31: 114 *phymod_poly = phymodPrbsPoly31; 115 break; 116 case EAGLE_PRBS_POLYNOMIAL_58: 117 *phymod_poly = phymodPrbsPoly58; 118 break; 119 default: 120 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tsce_poly)); 121 } 122 return PHYMOD_E_NONE; 123 } 124 125 126 int qsgmiie_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_prbs_t* prbs) 127 { 128 129 phymod_phy_access_t phy_copy; 130 int start_lane, num_lane; 131 132 enum srds_prbs_polynomial_enum eagle_poly; 133 134 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 135 136 /*next figure out the lane num and start_lane based on the input*/ 137 PHYMOD_IF_ERR_RETURN 138 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 139 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 140 141 PHYMOD_IF_ERR_RETURN(_qsgmiie_prbs_poly_phymod_to_eagle(prbs->poly, &eagle_poly)); 142 /*first check which direction */ 143 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 144 PHYMOD_IF_ERR_RETURN 145 (eagle_tsc_config_rx_prbs(&phy_copy.access, eagle_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 146 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 147 PHYMOD_IF_ERR_RETURN 148 (eagle_tsc_config_tx_prbs(&phy_copy.access, eagle_poly, prbs->invert)); 149 } else { 150 PHYMOD_IF_ERR_RETURN 151 (eagle_tsc_config_rx_prbs(&phy_copy.access, eagle_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 152 PHYMOD_IF_ERR_RETURN 153 (eagle_tsc_config_tx_prbs(&phy_copy.access, eagle_poly, prbs->invert)); 154 } 155 156 return PHYMOD_E_NONE; 157 158 } 159 160 161 int qsgmiie_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_t* prbs) 162 { 163 phymod_prbs_t config_tmp; 164 phymod_phy_access_t phy_copy; 165 int start_lane, num_lane; 166 eagle_prbs_polynomial_type_t tsce_poly; 167 168 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 169 170 PHYMOD_IF_ERR_RETURN 171 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 172 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 173 174 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 175 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_inv_data_get(&phy_copy.access, &config_tmp.invert)); 176 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_poly_get(&phy_copy.access, &tsce_poly)); 177 PHYMOD_IF_ERR_RETURN(_qsgmiie_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 178 prbs->invert = config_tmp.invert; 179 prbs->poly = config_tmp.poly; 180 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 181 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_inv_data_get(&phy_copy.access, &config_tmp.invert)); 182 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_poly_get(&phy_copy.access, &tsce_poly)); 183 PHYMOD_IF_ERR_RETURN(_qsgmiie_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 184 prbs->invert = config_tmp.invert; 185 prbs->poly = config_tmp.poly; 186 } else { 187 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_inv_data_get(&phy_copy.access, &config_tmp.invert)); 188 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_poly_get(&phy_copy.access, &tsce_poly)); 189 PHYMOD_IF_ERR_RETURN(_qsgmiie_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 190 prbs->invert = config_tmp.invert; 191 prbs->poly = config_tmp.poly; 192 } 193 194 return PHYMOD_E_NONE; 195 196 } 197 198 199 int qsgmiie_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags, uint32_t enable) 200 { 201 202 phymod_phy_access_t phy_copy; 203 int start_lane, num_lane; 204 205 206 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 207 208 /*next figure out the lane num and start_lane based on the input*/ 209 PHYMOD_IF_ERR_RETURN 210 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 211 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 212 213 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 214 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_prbs_en(&phy_copy.access, enable)); 215 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 216 PHYMOD_IF_ERR_RETURN(eagle_tsc_rx_prbs_en(&phy_copy.access, enable)); 217 } else { 218 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_prbs_en(&phy_copy.access, enable)); 219 PHYMOD_IF_ERR_RETURN(eagle_tsc_rx_prbs_en(&phy_copy.access, enable)); 220 } 221 222 return PHYMOD_E_NONE; 223 224 } 225 226 227 int qsgmiie_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags, uint32_t* enable) 228 { 229 phymod_phy_access_t phy_copy; 230 int start_lane, num_lane; 231 uint32_t enable_tmp; 232 233 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 234 235 /*next figure out the lane num and start_lane based on the input*/ 236 PHYMOD_IF_ERR_RETURN 237 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 238 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 239 240 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 241 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_enable_get(&phy_copy.access, &enable_tmp)); 242 *enable = enable_tmp; 243 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 244 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_enable_get(&phy_copy.access, &enable_tmp)); 245 *enable = enable_tmp; 246 } else { 247 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_enable_get(&phy_copy.access, &enable_tmp)); 248 *enable = enable_tmp; 249 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_enable_get(&phy_copy.access, &enable_tmp)); 250 *enable &= enable_tmp; 251 } 252 253 254 255 return PHYMOD_E_NONE; 256 257 } 258 259 260 int qsgmiie_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 261 { 262 263 uint8_t status = 0; 264 uint32_t prbs_err_count = 0; 265 int start_lane, num_lane; 266 phymod_phy_access_t phy_copy; 267 268 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 269 /* next figure out the lane num and start_lane based on the input */ 270 PHYMOD_IF_ERR_RETURN 271 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 272 273 prbs_status->prbs_lock = 1; 274 prbs_status->error_count = 0; 275 prbs_status->prbs_lock_loss = 0; 276 277 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 278 PHYMOD_IF_ERR_RETURN(eagle_tsc_prbs_chk_lock_state(&phy_copy.access, &status)); 279 if (status) { 280 /*next check the lost of lock and error count */ 281 status = 0; 282 PHYMOD_IF_ERR_RETURN 283 (eagle_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 284 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d lock_loss=%0d\n", (start_lane / 4), prbs_err_count, status)); 285 if (status) { 286 /*temp lost of lock */ 287 prbs_status->prbs_lock_loss = 1; 288 } else { 289 prbs_status->error_count += prbs_err_count; 290 } 291 } else { 292 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", (start_lane / 4))); 293 prbs_status->prbs_lock = 0; 294 return PHYMOD_E_NONE; 295 } 296 return PHYMOD_E_NONE; 297 } 298 299 300 int qsgmiie_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 301 { 302 303 304 /* Place your code here */ 305 306 307 return PHYMOD_E_NONE; 308 309 } 310 311 int qsgmiie_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 312 { 313 314 315 /* Place your code here */ 316 317 318 return PHYMOD_E_NONE; 319 320 } 321 322 323 int qsgmiie_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 324 { 325 326 327 /* Place your code here */ 328 329 330 return PHYMOD_E_NONE; 331 332 } 333 334 int qsgmiie_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 335 { 336 337 338 /* Place your code here */ 339 340 341 return PHYMOD_E_NONE; 342 343 } 344 345 346 int qsgmiie_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 347 { 348 349 350 /* Place your code here */ 351 352 353 return PHYMOD_E_NONE; 354 355 } 356 357 358 int qsgmiie_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag) 359 { 360 361 unsigned char rx_lock; 362 int osr_mode; 363 phymod_diag_eyescan_t_init(&diag->eyescan); 364 phymod_diag_slicer_offset_t_init(&diag->slicer_offset); 365 366 PHYMOD_IF_ERR_RETURN(eagle_tsc_pmd_lock_status(&phy->access, &rx_lock)); 367 diag->rx_lock = (uint32_t ) rx_lock; 368 PHYMOD_IF_ERR_RETURN(eagle_osr_mode_get(&phy->access, &osr_mode)); 369 switch(osr_mode) { 370 case 0: diag->osr_mode = phymodOversampleMode1; break; 371 case 1: diag->osr_mode = phymodOversampleMode2; break; 372 case 2: diag->osr_mode = phymodOversampleMode3; break; 373 case 3: diag->osr_mode = phymodOversampleMode3P3; break; 374 case 4: diag->osr_mode = phymodOversampleMode4; break; 375 case 5: diag->osr_mode = phymodOversampleMode5; break; 376 case 6: diag->osr_mode = phymodOversampleMode7P5; break; 377 case 7: diag->osr_mode = phymodOversampleMode8; break; 378 case 8: diag->osr_mode = phymodOversampleMode8P25; break; 379 case 9: diag->osr_mode = phymodOversampleMode10; break; 380 default: 381 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode)); 382 } 383 PHYMOD_IF_ERR_RETURN(eagle_tsc_signal_detect(&phy->access, &diag->signal_detect)); 384 385 return PHYMOD_E_NONE; 386 387 } 388 389 int qsgmiie_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 390 { 391 int start_lane, num_lane; 392 phymod_phy_access_t phy_copy; 393 int i = 0; 394 uint32_t cmd_type; 395 uint8_t trace_mem[768]; 396 397 if (!type) { 398 cmd_type = (uint32_t)TEMOD_DIAG_DSC; 399 } else if (!PHYMOD_STRCMP(type, "ber")) { 400 cmd_type = (uint32_t)TEMOD_DIAG_BER; 401 } else if (!PHYMOD_STRCMP(type, "config")) { 402 cmd_type = (uint32_t)TEMOD_DIAG_CFG; 403 } else if (!PHYMOD_STRCMP(type, "CL72") || !PHYMOD_STRCMP(type, "cl72")) { 404 cmd_type = (uint32_t)TEMOD_DIAG_CL72; 405 } else if (!PHYMOD_STRCMP(type, "debug")) { 406 cmd_type = (uint32_t)TEMOD_DIAG_DEBUG; 407 } else if (!PHYMOD_STRCMP(type, "state")) { 408 cmd_type = (uint32_t)TEMOD_DIAG_STATE; 409 } else { 410 cmd_type = (uint32_t)TEMOD_DIAG_DSC; 411 } 412 413 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 414 415 /*next figure out the lane num and start_lane based on the input*/ 416 PHYMOD_IF_ERR_RETURN 417 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 418 419 if (cmd_type == TEMOD_DIAG_DSC) { 420 phy_copy.access.lane_mask = 0x1 << (start_lane/4); 421 PHYMOD_IF_ERR_RETURN 422 (eagle_tsc_display_core_state(&phy_copy.access)); 423 PHYMOD_IF_ERR_RETURN 424 (eagle_tsc_display_lane_state_hdr(&phy_copy.access)); 425 PHYMOD_IF_ERR_RETURN 426 (eagle_tsc_display_lane_state(&phy_copy.access)); 427 } else { 428 for (i = 0; i < num_lane; i++) { 429 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 430 431 switch(cmd_type) { 432 case TEMOD_DIAG_CFG: 433 PHYMOD_IF_ERR_RETURN 434 (eagle_tsc_display_core_config(&phy_copy.access)); 435 PHYMOD_IF_ERR_RETURN 436 (eagle_tsc_display_lane_config(&phy_copy.access)); 437 break; 438 439 case TEMOD_DIAG_CL72: 440 PHYMOD_IF_ERR_RETURN 441 (eagle_tsc_display_cl72_status(&phy_copy.access)); 442 break; 443 444 case TEMOD_DIAG_DEBUG: 445 PHYMOD_IF_ERR_RETURN 446 (eagle_tsc_display_lane_debug_status(&phy_copy.access)); 447 break; 448 449 case TEMOD_DIAG_BER: 450 break; 451 452 case TEMOD_DIAG_STATE: 453 default: 454 PHYMOD_IF_ERR_RETURN 455 (eagle_tsc_display_core_state_hdr(&phy_copy.access)); 456 PHYMOD_IF_ERR_RETURN 457 (eagle_tsc_display_core_state_line(&phy_copy.access)); 458 PHYMOD_IF_ERR_RETURN 459 (eagle_tsc_display_core_state(&phy_copy.access)); 460 PHYMOD_IF_ERR_RETURN 461 (eagle_tsc_display_lane_state_hdr(&phy_copy.access)); 462 PHYMOD_IF_ERR_RETURN 463 (eagle_tsc_display_lane_state(&phy_copy.access)); 464 PHYMOD_IF_ERR_RETURN 465 (eagle_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 466 break; 467 } 468 } 469 } 470 return PHYMOD_E_NONE; 471 } 472 473 int qsgmiie_phy_eyescan_run(const phymod_phy_access_t* phy, 474 uint32_t flags, 475 phymod_eyescan_mode_t mode, 476 const phymod_phy_eyescan_options_t* eyescan_options) 477 { 478 phymod_phy_access_t phy_copy; 479 int start_lane, num_lane; 480 481 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 482 483 /*next figure out the lane num and start_lane based on the input*/ 484 PHYMOD_IF_ERR_RETURN 485 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 486 phy_copy.access.lane_mask = 0x1 << (start_lane / 4); 487 488 PHYMOD_IF_ERR_RETURN 489 (eagle_phy_eyescan_run(&phy_copy, flags, mode, eyescan_options)); 490 491 return PHYMOD_E_NONE; 492 } 493 494 #endif /* PHYMOD_QSGMIIE_SUPPORT */