tscf_diagnostics.c (28688B)
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_util.h> 13 #include "../../tscf/tier1/tefmod_enum_defines.h" 14 #include "../../tscf/tier1/tefmod.h" 15 #include "../../falcon/tier1/falcon_tsc_common.h" 16 #include "../../falcon/tier1/falcon_tsc_interface.h" 17 #include "../../falcon/tier1/falcon_cfg_seq.h" 18 #include "../../falcon/tier1/falcon_tsc_debug_functions.h" 19 20 21 #define PATTERN_MAX_LENGTH 240 22 #define TSCF_NOF_LANES_IN_CORE (4) 23 24 #ifdef PHYMOD_TSCF_SUPPORT 25 26 27 28 /*phymod, internal enum mappings*/ 29 STATIC 30 int _tscf_prbs_poly_phymod_to_falcon(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *falcon_poly) 31 { 32 switch(phymod_poly){ 33 case phymodPrbsPoly7: 34 *falcon_poly = PRBS_7; 35 break; 36 case phymodPrbsPoly9: 37 *falcon_poly = PRBS_9; 38 break; 39 case phymodPrbsPoly11: 40 *falcon_poly = PRBS_11; 41 break; 42 case phymodPrbsPoly15: 43 *falcon_poly = PRBS_15; 44 break; 45 case phymodPrbsPoly23: 46 *falcon_poly = PRBS_23; 47 break; 48 case phymodPrbsPoly31: 49 *falcon_poly = PRBS_31; 50 break; 51 case phymodPrbsPoly58: 52 *falcon_poly = PRBS_58; 53 break; 54 default: 55 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly)); 56 } 57 return PHYMOD_E_NONE; 58 } 59 60 STATIC 61 int _tscf_prbs_poly_tscf_to_phymod(falcon_prbs_polynomial_type_t tscf_poly, phymod_prbs_poly_t *phymod_poly) 62 { 63 switch(tscf_poly){ 64 case FALCON_PRBS_POLYNOMIAL_7: 65 *phymod_poly = phymodPrbsPoly7; 66 break; 67 case FALCON_PRBS_POLYNOMIAL_9: 68 *phymod_poly = phymodPrbsPoly9; 69 break; 70 case FALCON_PRBS_POLYNOMIAL_11: 71 *phymod_poly = phymodPrbsPoly11; 72 break; 73 case FALCON_PRBS_POLYNOMIAL_15: 74 *phymod_poly = phymodPrbsPoly15; 75 break; 76 case FALCON_PRBS_POLYNOMIAL_23: 77 *phymod_poly = phymodPrbsPoly23; 78 break; 79 case FALCON_PRBS_POLYNOMIAL_31: 80 *phymod_poly = phymodPrbsPoly31; 81 break; 82 case FALCON_PRBS_POLYNOMIAL_58: 83 *phymod_poly = phymodPrbsPoly58; 84 break; 85 default: 86 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tscf_poly)); 87 } 88 return PHYMOD_E_NONE; 89 } 90 91 #ifdef PHYMOD_TO_TSCE_OS_MODE_TRANS 92 STATIC 93 int _tscf_os_mode_phymod_to_tscf(phymod_osr_mode_t phymod_os_mode, tefmod_os_mode_type *tscf_os_mode) 94 { 95 switch(phymod_os_mode){ 96 case phymodOversampleMode1: 97 *tscf_os_mode = TEFMOD_PMA_OS_MODE_1; 98 break; 99 case phymodOversampleMode2: 100 *tscf_os_mode = TEFMOD_PMA_OS_MODE_2; 101 break; 102 case phymodOversampleMode3: 103 *tscf_os_mode = TEFMOD_PMA_OS_MODE_3; 104 break; 105 case phymodOversampleMode3P3: 106 *tscf_os_mode = TEFMOD_PMA_OS_MODE_3_3; 107 break; 108 case phymodOversampleMode4: 109 *tscf_os_mode = TEFMOD_PMA_OS_MODE_4; 110 break; 111 case phymodOversampleMode5: 112 *tscf_os_mode = TEFMOD_PMA_OS_MODE_5; 113 break; 114 case phymodOversampleMode8: 115 *tscf_os_mode = TEFMOD_PMA_OS_MODE_8; 116 break; 117 case phymodOversampleMode8P25: 118 *tscf_os_mode = TEFMOD_PMA_OS_MODE_8_25; 119 break; 120 case phymodOversampleMode10: 121 *tscf_os_mode = TEFMOD_PMA_OS_MODE_10; 122 break; 123 default: 124 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported over sample mode for tscf %u"), phymod_os_mode)); 125 } 126 return PHYMOD_E_NONE; 127 } 128 129 STATIC 130 int _tscf_os_mode_tscf_to_phymod(tefmod_os_mode_type tscf_os_mode, phymod_osr_mode_t *phymod_os_mode) 131 { 132 switch(tscf_os_mode){ 133 case TEFMOD_PMA_OS_MODE_1: 134 *phymod_os_mode = phymodOversampleMode1; 135 break; 136 case TEFMOD_PMA_OS_MODE_2: 137 *phymod_os_mode = phymodOversampleMode2; 138 break; 139 case TEFMOD_PMA_OS_MODE_3: 140 *phymod_os_mode = phymodOversampleMode3; 141 break; 142 case TEFMOD_PMA_OS_MODE_3_3: 143 *phymod_os_mode = phymodOversampleMode3P3; 144 break; 145 case TEFMOD_PMA_OS_MODE_4: 146 *phymod_os_mode = phymodOversampleMode4; 147 break; 148 case TEFMOD_PMA_OS_MODE_5: 149 *phymod_os_mode = phymodOversampleMode5; 150 break; 151 case TEFMOD_PMA_OS_MODE_8: 152 *phymod_os_mode = phymodOversampleMode8; 153 break; 154 case TEFMOD_PMA_OS_MODE_8_25: 155 *phymod_os_mode = phymodOversampleMode8P25; 156 break; 157 case TEFMOD_PMA_OS_MODE_10: 158 *phymod_os_mode = phymodOversampleMode10; 159 break; 160 default: 161 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown os mode %u"), tscf_os_mode)); 162 } 163 return PHYMOD_E_NONE; 164 } 165 #endif 166 167 /*diagnotics functions*/ 168 169 int tscf_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 170 { 171 172 173 174 /* Place your code here */ 175 176 177 return PHYMOD_E_NONE; 178 179 180 } 181 182 int tscf_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 183 { 184 185 186 187 /* Place your code here */ 188 189 190 return PHYMOD_E_NONE; 191 192 193 } 194 195 196 int tscf_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) 197 { 198 199 200 201 /* Place your code here */ 202 203 204 return PHYMOD_E_NONE; 205 206 207 } 208 209 int tscf_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 210 { 211 enum srds_prbs_polynomial_enum falcon_poly; 212 int i, start_lane, num_lane; 213 phymod_phy_access_t phy_copy; 214 PHYMOD_IF_ERR_RETURN(_tscf_prbs_poly_phymod_to_falcon(prbs->poly, &falcon_poly)); 215 216 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 217 218 /* next figure out the lane num and start_lane based on the input */ 219 PHYMOD_IF_ERR_RETURN 220 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 221 222 /*first check which direction */ 223 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 224 for (i = 0; i < num_lane; i++) { 225 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 226 continue; 227 } 228 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 229 PHYMOD_IF_ERR_RETURN 230 (falcon_tsc_config_rx_prbs(&phy_copy.access, falcon_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 231 } 232 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 233 for (i = 0; i < num_lane; i++) { 234 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 235 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 236 continue; 237 } 238 PHYMOD_IF_ERR_RETURN 239 (falcon_tsc_config_tx_prbs(&phy_copy.access, falcon_poly, prbs->invert)); 240 } 241 } else { 242 for (i = 0; i < num_lane; i++) { 243 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 244 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 245 continue; 246 } 247 PHYMOD_IF_ERR_RETURN 248 (falcon_tsc_config_rx_prbs(&phy_copy.access, falcon_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 249 PHYMOD_IF_ERR_RETURN 250 (falcon_tsc_config_tx_prbs(&phy_copy.access, falcon_poly, prbs->invert)); 251 } 252 } 253 return PHYMOD_E_NONE; 254 } 255 256 int tscf_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 257 { 258 phymod_prbs_t config_tmp; 259 falcon_prbs_polynomial_type_t tscf_poly; 260 261 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 262 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 263 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_poly_get(&phy->access, &tscf_poly)); 264 PHYMOD_IF_ERR_RETURN(_tscf_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 265 prbs->invert = config_tmp.invert; 266 prbs->poly = config_tmp.poly; 267 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 268 PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert)); 269 PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_poly_get(&phy->access, &tscf_poly)); 270 PHYMOD_IF_ERR_RETURN(_tscf_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 271 prbs->invert = config_tmp.invert; 272 prbs->poly = config_tmp.poly; 273 } else { 274 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 275 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_poly_get(&phy->access, &tscf_poly)); 276 PHYMOD_IF_ERR_RETURN(_tscf_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly)); 277 prbs->invert = config_tmp.invert; 278 prbs->poly = config_tmp.poly; 279 } 280 return PHYMOD_E_NONE; 281 } 282 283 284 285 int tscf_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 286 { 287 int i, start_lane, num_lane; 288 phymod_phy_access_t phy_copy; 289 290 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 291 /* next figure out the lane num and start_lane based on the input */ 292 PHYMOD_IF_ERR_RETURN 293 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 294 295 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 296 for (i = 0; i < num_lane; i++) { 297 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 298 continue; 299 } 300 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 301 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_prbs_en(&phy_copy.access, enable)); 302 } 303 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 304 for (i = 0; i < num_lane; i++) { 305 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 306 continue; 307 } 308 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 309 PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_prbs_en(&phy_copy.access, enable)); 310 } 311 } else { 312 for (i = 0; i < num_lane; i++) { 313 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 314 continue; 315 } 316 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 317 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_prbs_en(&phy_copy.access, enable)); 318 PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_prbs_en(&phy_copy.access, enable)); 319 } 320 } 321 return PHYMOD_E_NONE; 322 } 323 324 int tscf_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t *enable) 325 { 326 uint32_t enable_tmp; 327 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 328 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_enable_get(&phy->access, &enable_tmp)); 329 *enable = enable_tmp; 330 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 331 PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_enable_get(&phy->access, &enable_tmp)); 332 *enable = enable_tmp; 333 } else { 334 PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_enable_get(&phy->access, &enable_tmp)); 335 *enable = enable_tmp; 336 PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_enable_get(&phy->access, &enable_tmp)); 337 *enable &= enable_tmp; 338 } 339 340 return PHYMOD_E_NONE; 341 } 342 343 344 int tscf_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 345 { 346 uint8_t status = 0; 347 uint32_t prbs_err_count = 0; 348 int i, start_lane, num_lane; 349 phymod_phy_access_t phy_copy; 350 351 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 352 /* next figure out the lane num and start_lane based on the input */ 353 PHYMOD_IF_ERR_RETURN 354 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 355 356 prbs_status->prbs_lock = 0; 357 prbs_status->error_count = 0; 358 prbs_status->prbs_lock_loss = 0; 359 prbs_status->prbs_lock = 1; 360 361 for (i = 0; i < num_lane; i++) { 362 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 363 continue; 364 } 365 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 366 PHYMOD_IF_ERR_RETURN(falcon_tsc_prbs_chk_lock_state(&phy_copy.access, &status)); 367 if (status) { 368 /*next check the lost of lock and error count */ 369 status = 0; 370 PHYMOD_IF_ERR_RETURN 371 (falcon_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 372 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count)); 373 if (status) { 374 /*temp lost of lock */ 375 prbs_status->prbs_lock_loss = 1; 376 } else { 377 prbs_status->error_count += prbs_err_count; 378 } 379 } else { 380 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i )); 381 prbs_status->prbs_lock = 0; 382 /* return PHYMOD_E_NONE; */ 383 } 384 } 385 return PHYMOD_E_NONE; 386 } 387 388 389 int tscf_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 390 { 391 int i,j = 0, bit; 392 char patt[PATTERN_MAX_LENGTH+1]; 393 for (i=0; i< PATTERN_MAX_SIZE; i++) 394 { 395 for (j=0;j<32 && i*32+j <= PATTERN_MAX_LENGTH; j++) 396 { 397 if (i*32+j == pattern->pattern_len) { 398 break; 399 } 400 bit = pattern->pattern[i] >> j & 00000001; 401 switch (bit) { 402 case (1): 403 patt[i*32+j] = '1'; 404 break; 405 default: 406 patt[i*32+j] = '0'; 407 break; 408 } 409 } 410 if (i*32+j == pattern->pattern_len && i*32+j <= PATTERN_MAX_LENGTH) { 411 /* coverity[overrun-local] */ 412 patt[i*32+j] = '\0'; 413 break; 414 } 415 } 416 PHYMOD_IF_ERR_RETURN 417 (falcon_tsc_config_shared_tx_pattern_idx_set(&phy->access, 418 &pattern->pattern_len )); 419 PHYMOD_IF_ERR_RETURN 420 (falcon_tsc_config_shared_tx_pattern (&phy->access, 421 (uint8_t) pattern->pattern_len, (const char *) patt)); 422 return PHYMOD_E_NONE; 423 } 424 425 426 427 428 int tscf_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 429 { 430 PHYMOD_IF_ERR_RETURN 431 (falcon_tsc_config_shared_tx_pattern_idx_get(&phy->access, 432 &pattern->pattern_len, 433 pattern->pattern)); 434 return PHYMOD_E_NONE; 435 } 436 437 int tscf_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, phymod_pattern_t* pattern) 438 { 439 PHYMOD_IF_ERR_RETURN 440 (falcon_tsc_tx_shared_patt_gen_en(&phy->access, (uint8_t) enable, (uint8_t)pattern->pattern_len)); 441 442 return PHYMOD_E_NONE; 443 } 444 445 int tscf_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 446 { 447 PHYMOD_IF_ERR_RETURN 448 (falcon_tsc_tx_shared_patt_gen_en_get(&phy->access, (uint8_t *) enable)); 449 450 return PHYMOD_E_NONE; 451 } 452 453 int tscf_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 454 { 455 int16_t temperature; 456 falcon_tsc_read_die_temperature(&core->access,&temperature); 457 diag->temperature = temperature ; 458 falcon_tsc_read_pll_range(&core->access, &diag->pll_range); 459 460 return PHYMOD_E_NONE; 461 462 } 463 464 int tscf_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char *type) 465 { 466 int start_lane, num_lane; 467 int tmp_lane_mask; 468 phymod_phy_access_t phy_copy; 469 struct falcon_tsc_detailed_lane_status_st lane_st[4] = {{0}}; 470 int i = 0; 471 int j = 0; 472 int tmp_ln_msk; 473 uint32_t cmd_type; 474 uint8_t trace_mem[768]; 475 int is_in_reset = 0; 476 477 if (!type) { 478 cmd_type = (uint32_t)TEFMOD_DIAG_DSC; 479 } else if ((!PHYMOD_STRCMP(type, "ber")) || 480 (!PHYMOD_STRCMP(type, "Ber")) || 481 (!PHYMOD_STRCMP(type, "BER"))) { 482 cmd_type = (uint32_t)TEFMOD_DIAG_BER; 483 } else if ((!PHYMOD_STRCMP(type, "config")) || 484 (!PHYMOD_STRCMP(type, "Config")) || 485 (!PHYMOD_STRCMP(type, "CONFIG"))) { 486 cmd_type = (uint32_t)TEFMOD_DIAG_CFG; 487 } else if ((!PHYMOD_STRCMP(type, "cl72")) || 488 (!PHYMOD_STRCMP(type, "Cl72")) || 489 (!PHYMOD_STRCMP(type, "CL72"))) { 490 cmd_type = (uint32_t)TEFMOD_DIAG_CL72; 491 } else if ((!PHYMOD_STRCMP(type, "debug")) || 492 (!PHYMOD_STRCMP(type, "Debug")) || 493 (!PHYMOD_STRCMP(type, "DEBUG"))) { 494 cmd_type = (uint32_t)TEFMOD_DIAG_DEBUG; 495 } else if ((!PHYMOD_STRCMP(type, "state")) || 496 (!PHYMOD_STRCMP(type, "State")) || 497 (!PHYMOD_STRCMP(type, "STATE"))) { 498 cmd_type = (uint32_t)TEFMOD_DIAG_STATE; 499 } else if ((!PHYMOD_STRCMP(type, "verbose")) || 500 (!PHYMOD_STRCMP(type, "Verbose")) || 501 (!PHYMOD_STRCMP(type, "VERBOSE"))) { 502 cmd_type = (uint32_t)TEFMOD_DIAG_ALL; 503 } else if (!PHYMOD_STRCMP(type, "STD")) { 504 cmd_type = (uint32_t)TEFMOD_DIAG_DSC_STD; 505 } else { 506 cmd_type = (uint32_t)TEFMOD_DIAG_STATE; 507 } 508 509 PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask = 0x%X, Address = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask, phy->access.addr)); 510 511 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 512 513 /*next figure out the lane num and start_lane based on the input*/ 514 PHYMOD_IF_ERR_RETURN 515 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 516 517 if (cmd_type == TEFMOD_DIAG_DSC) { 518 PHYMOD_IF_ERR_RETURN 519 (falcon_tsc_display_core_state(&phy_copy.access)); 520 PHYMOD_IF_ERR_RETURN 521 (falcon_tsc_display_lane_state_hdr(&phy_copy.access)); 522 for (i = 0; i < 4; i++) { 523 phy_copy.access.lane_mask = 0x1 << i ; 524 PHYMOD_IF_ERR_RETURN 525 (tefmod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 526 if (is_in_reset) { 527 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", i)); 528 continue; 529 } 530 PHYMOD_IF_ERR_RETURN 531 (falcon_tsc_display_lane_state(&phy_copy.access)); 532 } 533 } else if (cmd_type == TEFMOD_DIAG_DSC_STD) { 534 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 535 PHYMOD_DIAG_OUT((" | DSC Phy: 0x%03x lane_mask: 0x%02x |\n", phy->access.addr, phy->access.lane_mask)); 536 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 537 PHYMOD_IF_ERR_RETURN 538 (falcon_tsc_display_core_state(&phy_copy.access)); 539 PHYMOD_IF_ERR_RETURN 540 (falcon_tsc_display_lane_state_hdr(&phy_copy.access)); 541 for (i = 0; i < num_lane; i++) { 542 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 543 PHYMOD_IF_ERR_RETURN 544 (tefmod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 545 if (is_in_reset) { 546 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", (i + start_lane))); 547 continue; 548 } 549 PHYMOD_IF_ERR_RETURN 550 (falcon_tsc_display_lane_state(&phy_copy.access)); 551 } 552 tmp_ln_msk = phy_copy.access.lane_mask; 553 for (j = 0; j < 4; j++) { 554 phy_copy.access.lane_mask = 0x1 << j; 555 PHYMOD_IF_ERR_RETURN 556 (tefmod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 557 if (is_in_reset) { 558 continue; 559 } 560 PHYMOD_IF_ERR_RETURN 561 (falcon_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 562 } 563 phy_copy.access.lane_mask = tmp_ln_msk; 564 PHYMOD_IF_ERR_RETURN 565 (falcon_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 566 PHYMOD_IF_ERR_RETURN 567 (falcon_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 568 } else { 569 for (i = 0; i < num_lane; i++) { 570 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 571 572 switch (cmd_type) { 573 case TEFMOD_DIAG_CFG: 574 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 575 if (i == 0) { 576 tmp_lane_mask = phy_copy.access.lane_mask; 577 phy_copy.access.lane_mask = 1; 578 PHYMOD_IF_ERR_RETURN 579 (falcon_tsc_display_core_config(&phy_copy.access)); 580 phy_copy.access.lane_mask = tmp_lane_mask; 581 } 582 PHYMOD_IF_ERR_RETURN 583 (falcon_tsc_display_lane_config(&phy_copy.access)); 584 break; 585 586 case TEFMOD_DIAG_CL72: 587 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 588 PHYMOD_IF_ERR_RETURN 589 (falcon_tsc_display_cl93n72_status(&phy_copy.access)); 590 break; 591 592 case TEFMOD_DIAG_DEBUG: 593 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 594 PHYMOD_IF_ERR_RETURN 595 (falcon_tsc_display_lane_debug_status(&phy_copy.access)); 596 break; 597 598 case TEFMOD_DIAG_BER: 599 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__)); 600 break; 601 602 /* 603 * COVERITY 604 * 605 * TEFMOD_DIAG_ALL branch involve information in TEFMOD_DIAG_STATE branch 606 */ 607 /* coverity[unterminated_case] */ 608 case TEFMOD_DIAG_ALL: 609 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 610 if (i == 0) { 611 tmp_lane_mask = phy_copy.access.lane_mask; 612 phy_copy.access.lane_mask = 1; 613 PHYMOD_IF_ERR_RETURN 614 (falcon_tsc_display_core_config(&phy_copy.access)); 615 phy_copy.access.lane_mask = tmp_lane_mask; 616 } 617 PHYMOD_IF_ERR_RETURN 618 (falcon_tsc_display_lane_config(&phy_copy.access)); 619 620 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 621 PHYMOD_IF_ERR_RETURN 622 (falcon_tsc_display_cl93n72_status(&phy_copy.access)); 623 624 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 625 PHYMOD_IF_ERR_RETURN 626 (falcon_tsc_display_lane_debug_status(&phy_copy.access)); 627 628 case TEFMOD_DIAG_STATE: 629 default: 630 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__)); 631 PHYMOD_IF_ERR_RETURN 632 (falcon_tsc_display_core_state_hdr(&phy_copy.access)); 633 PHYMOD_IF_ERR_RETURN 634 (falcon_tsc_display_core_state_line(&phy_copy.access)); 635 PHYMOD_IF_ERR_RETURN 636 (falcon_tsc_display_core_state(&phy_copy.access)); 637 PHYMOD_IF_ERR_RETURN 638 (falcon_tsc_display_lane_state_hdr(&phy_copy.access)); 639 PHYMOD_IF_ERR_RETURN 640 (falcon_tsc_display_lane_state(&phy_copy.access)); 641 tmp_ln_msk = phy_copy.access.lane_mask; 642 for (j = 0; j < 4; j++) { 643 phy_copy.access.lane_mask = 0x1 << j; 644 PHYMOD_IF_ERR_RETURN 645 (tefmod_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 646 if (is_in_reset) { 647 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", j)); 648 continue; 649 } 650 PHYMOD_IF_ERR_RETURN 651 (falcon_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 652 } 653 phy_copy.access.lane_mask = tmp_ln_msk; 654 PHYMOD_IF_ERR_RETURN 655 (falcon_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 656 PHYMOD_IF_ERR_RETURN 657 (falcon_tsc_read_event_log((&phy_copy.access), trace_mem, 2)); 658 break; 659 } 660 } 661 } 662 return PHYMOD_E_NONE; 663 } 664 665 int tscf_phy_pcs_info_dump(const phymod_phy_access_t* phy, const char *type) 666 { 667 phymod_phy_access_t phy_copy; 668 669 670 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 671 PHYMOD_IF_ERR_RETURN (tefmod_diag_disp(&phy_copy.access, type)); 672 673 return PHYMOD_E_NONE; 674 } 675 676 677 int tscf_phy_fec_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 678 { 679 uint32_t lane_count; 680 uint32_t sum = 0; 681 int i, start_lane, num_lane; 682 phymod_phy_access_t phy_copy; 683 684 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 685 /* next figure out the lane num and start_lane based on the input */ 686 PHYMOD_IF_ERR_RETURN 687 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 688 689 for (i = 0; i < num_lane; i++) { 690 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 691 continue; 692 } 693 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 694 PHYMOD_IF_ERR_RETURN(tefmod_fec_correctable_counter_get(&phy_copy.access, &lane_count)); 695 /* Check overflow */ 696 if (lane_count > 0xffffffff - sum) { 697 sum = 0xffffffff; 698 break; 699 } else { 700 sum += lane_count; 701 } 702 } 703 704 *count = sum; 705 706 return PHYMOD_E_NONE; 707 } 708 709 int tscf_phy_fec_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 710 { 711 uint32_t lane_count; 712 uint32_t sum = 0; 713 int i, start_lane, num_lane; 714 phymod_phy_access_t phy_copy; 715 716 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 717 /* next figure out the lane num and start_lane based on the input */ 718 PHYMOD_IF_ERR_RETURN 719 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 720 721 for (i = 0; i < num_lane; i++) { 722 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 723 continue; 724 } 725 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 726 PHYMOD_IF_ERR_RETURN(tefmod_fec_uncorrectable_counter_get(&phy_copy.access, &lane_count)); 727 /* Check overflow */ 728 if (lane_count > 0xffffffff - sum) { 729 sum = 0xffffffff; 730 break; 731 } else { 732 sum += lane_count; 733 } 734 } 735 736 *count = sum; 737 738 return PHYMOD_E_NONE; 739 } 740 741 int tscf_phy_fec_cl91_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 742 { 743 int start_lane, num_lane; 744 phymod_phy_access_t phy_copy; 745 746 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 747 /* next figure out the lane num and start_lane based on the input */ 748 PHYMOD_IF_ERR_RETURN 749 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 750 phy_copy.access.lane_mask = 0x1 << start_lane; 751 752 PHYMOD_IF_ERR_RETURN(tefmod_fec_cl91_correctable_counter_get(&phy_copy.access, count)); 753 754 return PHYMOD_E_NONE; 755 } 756 757 int tscf_phy_fec_cl91_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 758 { 759 int start_lane, num_lane; 760 phymod_phy_access_t phy_copy; 761 762 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 763 /* next figure out the lane num and start_lane based on the input */ 764 PHYMOD_IF_ERR_RETURN 765 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 766 phy_copy.access.lane_mask = 0x1 << start_lane; 767 768 PHYMOD_IF_ERR_RETURN(tefmod_fec_cl91_uncorrectable_counter_get(&phy_copy.access, count)); 769 770 return PHYMOD_E_NONE; 771 } 772 773 int tscf_phy_stat_get(const phymod_phy_access_t* phy, phymod_phy_stat_t* stat) 774 { 775 phymod_phy_access_t phy_copy; 776 tefmod_encode_mode encode_mode; 777 int i = 0; 778 779 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 780 781 for (i = 0; i < TSCF_NOF_LANES_IN_CORE; i++) { 782 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, i)) { 783 continue; 784 } 785 786 phy_copy.access.lane_mask = 0x1 << i; 787 788 PHYMOD_IF_ERR_RETURN(tefmod_encode_mode_get(&phy_copy.access, &encode_mode)); 789 if (encode_mode == TEFMOD_ENCODE_MODE_CL49) { 790 /* CL49 has no BIP count */ 791 stat->pcs_bip_err_count[i] = 0; 792 PHYMOD_IF_ERR_RETURN(tefmod_cl49_ber_counter_get(&phy_copy.access, &stat->pcs_ber_count[i])); 793 } 794 else if (encode_mode == TEFMOD_ENCODE_MODE_CL82) { 795 PHYMOD_IF_ERR_RETURN(tefmod_bip_error_counter_get(&phy_copy.access, &stat->pcs_bip_err_count[i])); 796 PHYMOD_IF_ERR_RETURN(tefmod_cl82_ber_counter_get(&phy_copy.access, &stat->pcs_ber_count[i])); 797 } 798 else { 799 stat->pcs_bip_err_count[i] = 0; 800 stat->pcs_ber_count[i] = 0; 801 } 802 } 803 804 return PHYMOD_E_NONE; 805 } 806 807 #endif /* PHYMOD_TSCF_SUPPORT */