tsce_diagnostics.c (26163B)
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_system.h> 11 #include <phymod/phymod_diagnostics.h> 12 #include <phymod/phymod_config.h> 13 #include <phymod/phymod_util.h> 14 #include <phymod/phymod_config.h> 15 #include "../../tsce/tier1/temod_enum_defines.h" 16 #include "../../tsce/tier1/temod.h" 17 #include "../../eagle/tier1/eagle_tsc_common.h" 18 #include "../../eagle/tier1/eagle_tsc_interface.h" 19 #include "../../eagle/tier1/eagle_cfg_seq.h" 20 #include "../../eagle/tier1/eagle_tsc_debug_functions.h" 21 22 /* extern err_code_t eagle_tsc_read_event_log( const phymod_access_t *pa, uint8_t *trace_mem,enum event_log_display_mode_enum display_mode); */ 23 24 #define PATTERN_MAX_LENGTH 240 25 #define TSCE_NOF_LANES_IN_CORE (4) 26 27 #ifdef PHYMOD_TSCE_SUPPORT 28 29 /*phymod, internal enum mappings*/ 30 STATIC 31 int _tsce_prbs_poly_phymod_to_eagle(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *eagle_poly) 32 { 33 switch(phymod_poly){ 34 case phymodPrbsPoly7: 35 *eagle_poly = PRBS_7; 36 break; 37 case phymodPrbsPoly9: 38 *eagle_poly = PRBS_9; 39 break; 40 case phymodPrbsPoly11: 41 *eagle_poly = PRBS_11; 42 break; 43 case phymodPrbsPoly15: 44 *eagle_poly = PRBS_15; 45 break; 46 case phymodPrbsPoly23: 47 *eagle_poly = PRBS_23; 48 break; 49 case phymodPrbsPoly31: 50 *eagle_poly = PRBS_31; 51 break; 52 case phymodPrbsPoly58: 53 *eagle_poly = PRBS_58; 54 break; 55 default: 56 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tsce %u"), phymod_poly)); 57 } 58 return PHYMOD_E_NONE; 59 } 60 61 STATIC 62 int _tsce_prbs_poly_tsce_to_phymod(eagle_prbs_polynomial_type_t tsce_poly, phymod_prbs_poly_t *phymod_poly) 63 { 64 switch(tsce_poly){ 65 case EAGLE_PRBS_POLYNOMIAL_7: 66 *phymod_poly = phymodPrbsPoly7; 67 break; 68 case EAGLE_PRBS_POLYNOMIAL_9: 69 *phymod_poly = phymodPrbsPoly9; 70 break; 71 case EAGLE_PRBS_POLYNOMIAL_11: 72 *phymod_poly = phymodPrbsPoly11; 73 break; 74 case EAGLE_PRBS_POLYNOMIAL_15: 75 *phymod_poly = phymodPrbsPoly15; 76 break; 77 case EAGLE_PRBS_POLYNOMIAL_23: 78 *phymod_poly = phymodPrbsPoly23; 79 break; 80 case EAGLE_PRBS_POLYNOMIAL_31: 81 *phymod_poly = phymodPrbsPoly31; 82 break; 83 case EAGLE_PRBS_POLYNOMIAL_58: 84 *phymod_poly = phymodPrbsPoly58; 85 break; 86 default: 87 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tsce_poly)); 88 } 89 return PHYMOD_E_NONE; 90 } 91 92 #ifdef PHYMOD_TO_TSCE_OS_MODE_TRANS 93 STATIC 94 int _tsce_os_mode_phymod_to_tsce(phymod_osr_mode_t phymod_os_mode, temod_os_mode_type *tsce_os_mode) 95 { 96 switch(phymod_os_mode){ 97 case phymodOversampleMode1: 98 *tsce_os_mode = TEMOD_PMA_OS_MODE_1; 99 break; 100 case phymodOversampleMode2: 101 *tsce_os_mode = TEMOD_PMA_OS_MODE_2; 102 break; 103 case phymodOversampleMode3: 104 *tsce_os_mode = TEMOD_PMA_OS_MODE_3; 105 break; 106 case phymodOversampleMode3P3: 107 *tsce_os_mode = TEMOD_PMA_OS_MODE_3_3; 108 break; 109 case phymodOversampleMode4: 110 *tsce_os_mode = TEMOD_PMA_OS_MODE_4; 111 break; 112 case phymodOversampleMode5: 113 *tsce_os_mode = TEMOD_PMA_OS_MODE_5; 114 break; 115 case phymodOversampleMode8: 116 *tsce_os_mode = TEMOD_PMA_OS_MODE_8; 117 break; 118 case phymodOversampleMode8P25: 119 *tsce_os_mode = TEMOD_PMA_OS_MODE_8_25; 120 break; 121 case phymodOversampleMode10: 122 *tsce_os_mode = TEMOD_PMA_OS_MODE_10; 123 break; 124 default: 125 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported over sample mode for tsce %u"), phymod_os_mode)); 126 } 127 return PHYMOD_E_NONE; 128 } 129 #endif 130 131 /*diagnotics functions*/ 132 133 int tsce_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 134 { 135 136 137 138 /* Place your code here */ 139 140 141 return PHYMOD_E_NONE; 142 143 144 } 145 146 int tsce_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 147 { 148 149 150 151 /* Place your code here */ 152 153 154 return PHYMOD_E_NONE; 155 156 157 } 158 159 160 int tsce_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) 161 { 162 163 164 165 /* Place your code here */ 166 167 168 return PHYMOD_E_NONE; 169 170 171 } 172 173 int tsce_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 174 { 175 phymod_phy_access_t phy_copy; 176 int start_lane, num_lane; 177 int i = 0; 178 179 enum srds_prbs_polynomial_enum eagle_poly; 180 181 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 182 183 /*next figure out the lane num and start_lane based on the input*/ 184 PHYMOD_IF_ERR_RETURN 185 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 186 187 PHYMOD_IF_ERR_RETURN(_tsce_prbs_poly_phymod_to_eagle(prbs->poly, &eagle_poly)); 188 /*first check which direction */ 189 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 190 for (i = 0; i < num_lane; i++) { 191 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 192 continue; 193 } 194 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 195 PHYMOD_IF_ERR_RETURN 196 (eagle_tsc_config_rx_prbs(&phy_copy.access, eagle_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 197 } 198 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 199 for (i = 0; i < num_lane; i++) { 200 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 201 continue; 202 } 203 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 204 PHYMOD_IF_ERR_RETURN 205 (eagle_tsc_config_tx_prbs(&phy_copy.access, eagle_poly, prbs->invert)); 206 } 207 } else { 208 for (i = 0; i < num_lane; i++) { 209 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 210 continue; 211 } 212 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 213 PHYMOD_IF_ERR_RETURN 214 (eagle_tsc_config_rx_prbs(&phy_copy.access, eagle_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 215 PHYMOD_IF_ERR_RETURN 216 (eagle_tsc_config_tx_prbs(&phy_copy.access, eagle_poly, prbs->invert)); 217 } 218 } 219 return PHYMOD_E_NONE; 220 } 221 222 int tsce_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 223 { 224 phymod_prbs_t config_tmp; 225 eagle_prbs_polynomial_type_t tsce_poly; 226 227 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 228 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 229 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_poly_get(&phy->access, &tsce_poly)); 230 PHYMOD_IF_ERR_RETURN(_tsce_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 231 prbs->invert = config_tmp.invert; 232 prbs->poly = config_tmp.poly; 233 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 234 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert)); 235 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_poly_get(&phy->access, &tsce_poly)); 236 PHYMOD_IF_ERR_RETURN(_tsce_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 237 prbs->invert = config_tmp.invert; 238 prbs->poly = config_tmp.poly; 239 } else { 240 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 241 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_poly_get(&phy->access, &tsce_poly)); 242 PHYMOD_IF_ERR_RETURN(_tsce_prbs_poly_tsce_to_phymod(tsce_poly, &config_tmp.poly)); 243 prbs->invert = config_tmp.invert; 244 prbs->poly = config_tmp.poly; 245 } 246 return PHYMOD_E_NONE; 247 } 248 249 250 251 int tsce_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 252 { 253 phymod_phy_access_t phy_copy; 254 int start_lane, num_lane; 255 int i = 0; 256 257 258 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 259 260 /*next figure out the lane num and start_lane based on the input*/ 261 PHYMOD_IF_ERR_RETURN 262 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 263 264 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 265 for (i = 0; i < num_lane; i++) { 266 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 267 continue; 268 } 269 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 270 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_prbs_en(&phy_copy.access, enable)); 271 } 272 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 273 for (i = 0; i < num_lane; i++) { 274 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 275 continue; 276 } 277 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 278 PHYMOD_IF_ERR_RETURN(eagle_tsc_rx_prbs_en(&phy_copy.access, enable)); 279 } 280 } else { 281 for (i = 0; i < num_lane; i++) { 282 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 283 continue; 284 } 285 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 286 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_prbs_en(&phy_copy.access, enable)); 287 PHYMOD_IF_ERR_RETURN(eagle_tsc_rx_prbs_en(&phy_copy.access, enable)); 288 } 289 } 290 return PHYMOD_E_NONE; 291 } 292 293 int tsce_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t *enable) 294 { 295 uint32_t enable_tmp; 296 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 297 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_enable_get(&phy->access, &enable_tmp)); 298 *enable = enable_tmp; 299 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 300 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_enable_get(&phy->access, &enable_tmp)); 301 *enable = enable_tmp; 302 } else { 303 PHYMOD_IF_ERR_RETURN(eagle_prbs_tx_enable_get(&phy->access, &enable_tmp)); 304 *enable = enable_tmp; 305 PHYMOD_IF_ERR_RETURN(eagle_prbs_rx_enable_get(&phy->access, &enable_tmp)); 306 *enable &= enable_tmp; 307 } 308 309 return PHYMOD_E_NONE; 310 } 311 312 313 int tsce_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 314 { 315 uint8_t status = 0; 316 uint32_t prbs_err_count = 0; 317 int i, start_lane, num_lane; 318 phymod_phy_access_t phy_copy; 319 320 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 321 /* next figure out the lane num and start_lane based on the input */ 322 PHYMOD_IF_ERR_RETURN 323 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 324 325 prbs_status->prbs_lock = 1; 326 prbs_status->error_count = 0; 327 prbs_status->prbs_lock_loss = 0; 328 329 for (i = 0; i < num_lane; i++) { 330 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 331 continue; 332 } 333 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 334 PHYMOD_IF_ERR_RETURN(eagle_tsc_prbs_chk_lock_state(&phy_copy.access, &status)); 335 if (status) { 336 /*next check the lost of lock and error count */ 337 status = 0; 338 PHYMOD_IF_ERR_RETURN 339 (eagle_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 340 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d lock_loss=%0d\n", i, prbs_err_count, status)); 341 if (status) { 342 /*temp lost of lock */ 343 prbs_status->prbs_lock_loss = 1; 344 } else { 345 prbs_status->error_count += prbs_err_count; 346 } 347 } else { 348 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i )); 349 prbs_status->prbs_lock = 0; 350 return PHYMOD_E_NONE; 351 } 352 } 353 return PHYMOD_E_NONE; 354 } 355 356 357 int tsce_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 358 { 359 int i,j = 0, bit; 360 char patt[PATTERN_MAX_LENGTH+1]; 361 for (i=0; i< PATTERN_MAX_SIZE; i++) 362 { 363 for (j=0;j<32 && i*32+j <= PATTERN_MAX_LENGTH; j++) { 364 if (i*32+j == pattern->pattern_len) { 365 break; 366 } 367 bit = pattern->pattern[i] >> j & 00000001; 368 switch (bit) { 369 case (1): 370 patt[i*32+j] = '1'; 371 break; 372 default: 373 patt[i*32+j] = '0'; 374 break; 375 } 376 } 377 if (i*32+j == pattern->pattern_len && i*32+j <= PATTERN_MAX_LENGTH) { 378 /* coverity[overrun-local] */ 379 patt[i*32+j] = '\0'; 380 break; 381 } 382 } 383 PHYMOD_IF_ERR_RETURN 384 (eagle_tsc_config_shared_tx_pattern_idx_set(&phy->access, 385 &pattern->pattern_len )); 386 PHYMOD_IF_ERR_RETURN 387 (eagle_tsc_config_shared_tx_pattern (&phy->access, 388 (uint8_t) pattern->pattern_len, (const char *) patt)); 389 390 return PHYMOD_E_NONE; 391 } 392 393 int tsce_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 394 { 395 PHYMOD_IF_ERR_RETURN 396 (eagle_tsc_config_shared_tx_pattern_idx_get(&phy->access, 397 &pattern->pattern_len, 398 pattern->pattern)); 399 400 return PHYMOD_E_NONE; 401 } 402 403 int tsce_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, phymod_pattern_t* pattern) 404 { 405 PHYMOD_IF_ERR_RETURN 406 (eagle_tsc_tx_shared_patt_gen_en(&phy->access, (uint8_t) enable, (uint8_t)pattern->pattern_len)); 407 return PHYMOD_E_NONE; 408 } 409 410 int tsce_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 411 { 412 413 PHYMOD_IF_ERR_RETURN 414 (eagle_tsc_tx_shared_patt_gen_en_get(&phy->access, (uint8_t *) enable)); 415 return PHYMOD_E_NONE; 416 } 417 418 int tsce_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 419 { 420 421 return PHYMOD_E_NONE; 422 } 423 424 int tsce_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 425 { 426 int start_lane, num_lane; 427 int tmp_lane_mask; 428 phymod_phy_access_t phy_copy; 429 430 /* struct eagle_tsc_detailed_lane_status_st lane_st[4]; */ 431 int i = 0; 432 uint32_t cmd_type; 433 uint8_t trace_mem[768]; 434 int is_in_reset = 0; 435 436 437 if (!type) { 438 cmd_type = (uint32_t)TEMOD_DIAG_DSC; 439 } else if ((!PHYMOD_STRCMP(type, "ber")) || 440 (!PHYMOD_STRCMP(type, "Ber")) || 441 (!PHYMOD_STRCMP(type, "BER"))) { 442 cmd_type = (uint32_t)TEMOD_DIAG_BER; 443 } else if ((!PHYMOD_STRCMP(type, "config")) || 444 (!PHYMOD_STRCMP(type, "Config")) || 445 (!PHYMOD_STRCMP(type, "CONFIG"))) { 446 cmd_type = (uint32_t)TEMOD_DIAG_CFG; 447 } else if ((!PHYMOD_STRCMP(type, "cl72")) || 448 (!PHYMOD_STRCMP(type, "Cl72")) || 449 (!PHYMOD_STRCMP(type, "CL72"))) { 450 cmd_type = (uint32_t)TEMOD_DIAG_CL72; 451 } else if ((!PHYMOD_STRCMP(type, "debug")) || 452 (!PHYMOD_STRCMP(type, "Debug")) || 453 (!PHYMOD_STRCMP(type, "DEBUG"))) { 454 cmd_type = (uint32_t)TEMOD_DIAG_DEBUG; 455 } else if ((!PHYMOD_STRCMP(type, "state")) || 456 (!PHYMOD_STRCMP(type, "State")) || 457 (!PHYMOD_STRCMP(type, "STATE"))) { 458 cmd_type = (uint32_t)TEMOD_DIAG_STATE; 459 } else if ((!PHYMOD_STRCMP(type, "verbose")) || 460 (!PHYMOD_STRCMP(type, "Verbose")) || 461 (!PHYMOD_STRCMP(type, "VERBOSE"))) { 462 cmd_type = (uint32_t)TEMOD_DIAG_ALL; 463 } else if (!PHYMOD_STRCMP(type, "STD")) { 464 cmd_type = (uint32_t)TEMOD_DIAG_DSC_STD; 465 } else { 466 cmd_type = (uint32_t)TEMOD_DIAG_STATE; 467 } 468 469 PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask)); 470 471 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 472 473 /*next figure out the lane num and start_lane based on the input*/ 474 PHYMOD_IF_ERR_RETURN 475 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 476 477 if (cmd_type == TEMOD_DIAG_DSC) { 478 PHYMOD_IF_ERR_RETURN 479 (eagle_tsc_display_core_state(&phy_copy.access)); 480 PHYMOD_IF_ERR_RETURN 481 (eagle_tsc_display_lane_state_hdr(&phy_copy.access)); 482 for (i = 0; i < 4; i++) { 483 phy_copy.access.lane_mask = 0x1 << i ; 484 PHYMOD_IF_ERR_RETURN 485 (temod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 486 if (is_in_reset) { 487 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", i)); 488 continue; 489 } 490 PHYMOD_IF_ERR_RETURN 491 (eagle_tsc_display_lane_state(&phy_copy.access)); 492 } 493 } else if (cmd_type == TEMOD_DIAG_DSC_STD ) { 494 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 495 PHYMOD_DIAG_OUT((" | DSC Phy: 0x%03x lane_mask: 0x%02x |\n", phy->access.addr, phy->access.lane_mask)); 496 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 497 PHYMOD_IF_ERR_RETURN 498 (eagle_tsc_display_core_state(&phy_copy.access)); 499 PHYMOD_IF_ERR_RETURN 500 (eagle_tsc_display_lane_state_hdr(&phy_copy.access)); 501 for (i = 0; i < num_lane; i++) { 502 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 503 PHYMOD_IF_ERR_RETURN 504 (temod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 505 if (is_in_reset) { 506 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", (i + start_lane))); 507 continue; 508 } 509 PHYMOD_IF_ERR_RETURN 510 (eagle_tsc_display_lane_state(&phy_copy.access)); 511 } 512 /*in tscf there is falcon_tsc_log_full_pmd_state here, 513 does not exist for eagle/tsce 514 (Support should be added)*/ 515 PHYMOD_IF_ERR_RETURN 516 (eagle_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 517 } else { 518 for (i = 0; i < num_lane; i++) { 519 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 520 521 switch (cmd_type) { 522 case TEMOD_DIAG_CFG: 523 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 524 if (i == 0) { 525 tmp_lane_mask = phy_copy.access.lane_mask; 526 phy_copy.access.lane_mask = 1; 527 PHYMOD_IF_ERR_RETURN 528 (eagle_tsc_display_core_config(&phy_copy.access)); 529 phy_copy.access.lane_mask = tmp_lane_mask; 530 } 531 PHYMOD_IF_ERR_RETURN 532 (eagle_tsc_display_lane_config(&phy_copy.access)); 533 break; 534 535 case TEMOD_DIAG_CL72: 536 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 537 PHYMOD_IF_ERR_RETURN 538 (eagle_tsc_display_cl72_status(&phy_copy.access)); 539 break; 540 541 case TEMOD_DIAG_DEBUG: 542 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 543 PHYMOD_IF_ERR_RETURN 544 (eagle_tsc_display_lane_debug_status(&phy_copy.access)); 545 break; 546 547 case TEMOD_DIAG_BER: 548 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__)); 549 break; 550 551 /* 552 * COVERITY 553 * 554 * TEFMOD_DIAG_ALL branch involve information in TEFMOD_DIAG_STATE branch 555 */ 556 /* coverity[unterminated_case] */ 557 case TEMOD_DIAG_ALL: 558 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 559 if (i == 0) { 560 tmp_lane_mask = phy_copy.access.lane_mask; 561 phy_copy.access.lane_mask = 1; 562 PHYMOD_IF_ERR_RETURN 563 (eagle_tsc_display_core_config(&phy_copy.access)); 564 phy_copy.access.lane_mask = tmp_lane_mask; 565 } 566 PHYMOD_IF_ERR_RETURN 567 (eagle_tsc_display_lane_config(&phy_copy.access)); 568 569 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 570 PHYMOD_IF_ERR_RETURN 571 (eagle_tsc_display_cl72_status(&phy_copy.access)); 572 573 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 574 PHYMOD_IF_ERR_RETURN 575 (eagle_tsc_display_lane_debug_status(&phy_copy.access)); 576 577 case TEMOD_DIAG_STATE: 578 default: 579 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__)); 580 PHYMOD_IF_ERR_RETURN 581 (eagle_tsc_display_core_state_hdr(&phy_copy.access)); 582 PHYMOD_IF_ERR_RETURN 583 (eagle_tsc_display_core_state_line(&phy_copy.access)); 584 PHYMOD_IF_ERR_RETURN 585 (eagle_tsc_display_core_state(&phy_copy.access)); 586 PHYMOD_IF_ERR_RETURN 587 (eagle_tsc_display_lane_state_hdr(&phy_copy.access)); 588 PHYMOD_IF_ERR_RETURN 589 (eagle_tsc_display_lane_state(&phy_copy.access)); 590 /* 591 tmp_ln_msk = phy_copy.access.lane_mask; 592 for (j = 0; j < 4; j++) { 593 phy_copy.access.lane_mask = 0x1 << j; 594 PHYMOD_IF_ERR_RETURN 595 (eagle_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 596 } 597 phy_copy.access.lane_mask = tmp_ln_msk; 598 PHYMOD_IF_ERR_RETURN 599 (eagle_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 600 */ 601 PHYMOD_IF_ERR_RETURN 602 (eagle_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 603 break; 604 } 605 } 606 } 607 return PHYMOD_E_NONE; 608 } 609 610 int tsce_phy_pcs_info_dump(const phymod_phy_access_t* phy, const char* type) 611 { 612 phymod_phy_access_t phy_copy; 613 614 PHYMOD_MEMCPY (&phy_copy, phy, sizeof(phy_copy)); 615 PHYMOD_IF_ERR_RETURN (temod_diag_disp(&phy_copy.access, type)); 616 617 return PHYMOD_E_NONE; 618 } 619 620 /* 621 For TSCE-12 case, *count needs to be initialized to 0 ONLY for the first call. 622 For other cases, *count needs to be initialized to 0 everytime before calling this API. 623 */ 624 int tsce_phy_fec_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 625 { 626 uint32_t lane_count; 627 uint32_t sum = *count; /* Need to aggregate different cores for TSCE12 */ 628 phymod_phy_access_t phy_copy; 629 int start_lane, num_lane; 630 int i = 0; 631 632 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 633 /*next figure out the lane num and start_lane based on the input*/ 634 PHYMOD_IF_ERR_RETURN 635 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 636 637 /* Add counts of all the lanes of the port */ 638 for (i = 0; i < num_lane; i++) { 639 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 640 continue; 641 } 642 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 643 PHYMOD_IF_ERR_RETURN(temod_fec_correctable_counter_get(&phy_copy.access, &lane_count)); 644 /* Check overflow */ 645 if (lane_count > 0xffffffff - sum) { 646 sum = 0xffffffff; 647 break; 648 } else { 649 sum += lane_count; 650 } 651 } 652 653 *count = sum; 654 655 return PHYMOD_E_NONE; 656 } 657 658 /* 659 For TSCE-12 case, *count needs to be initialized to 0 ONLY for the first call. 660 For other cases, *count needs to be initialized to 0 everytime before calling this API. 661 */ 662 int tsce_phy_fec_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 663 { 664 uint32_t lane_count; 665 uint32_t sum = *count; /* Need to aggregate different cores for TSCE12 */ 666 phymod_phy_access_t phy_copy; 667 int start_lane, num_lane; 668 int i = 0; 669 670 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 671 /*next figure out the lane num and start_lane based on the input*/ 672 PHYMOD_IF_ERR_RETURN 673 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 674 675 /* Add counts of all the lanes of the port */ 676 for (i = 0; i < num_lane; i++) { 677 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 678 continue; 679 } 680 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 681 PHYMOD_IF_ERR_RETURN(temod_fec_uncorrectable_counter_get(&phy_copy.access, &lane_count)); 682 /* Check overflow */ 683 if (lane_count > 0xffffffff - sum) { 684 sum = 0xffffffff; 685 break; 686 } else { 687 sum += lane_count; 688 } 689 } 690 691 *count = sum; 692 693 return PHYMOD_E_NONE; 694 } 695 696 int tsce_phy_stat_get(const phymod_phy_access_t* phy, phymod_phy_stat_t* stat) 697 { 698 phymod_phy_access_t phy_copy; 699 temod_encoder_type_t encode_mode; 700 int i = 0; 701 702 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 703 704 for (i = 0; i < TSCE_NOF_LANES_IN_CORE; i++) { 705 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, i)) { 706 continue; 707 } 708 709 phy_copy.access.lane_mask = 0x1 << i; 710 711 PHYMOD_IF_ERR_RETURN(temod_encode_mode_get(&phy_copy.access, &encode_mode)); 712 if (encode_mode == TEMOD_ENCODER_CL49) { 713 /* CL49 has no BIP count */ 714 stat->pcs_bip_err_count[i] = 0; 715 PHYMOD_IF_ERR_RETURN(temod_cl49_ber_counter_get(&phy_copy.access, &stat->pcs_ber_count[i])); 716 } 717 else if (encode_mode == TEMOD_ENCODER_CL82) { 718 PHYMOD_IF_ERR_RETURN(temod_bip_error_counter_get(&phy_copy.access, &stat->pcs_bip_err_count[i])); 719 PHYMOD_IF_ERR_RETURN(temod_cl82_ber_counter_get(&phy_copy.access, &stat->pcs_ber_count[i])); 720 } 721 else { 722 stat->pcs_bip_err_count[i] = 0; 723 stat->pcs_ber_count[i] = 0; 724 } 725 } 726 727 return PHYMOD_E_NONE; 728 } 729 730 #endif /* PHYMOD_TSCE_SUPPORT */