tscf16_diagnostics.c (27859B)
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_diagnostics.h> 13 #include <phymod/phymod_diagnostics_dispatch.h> 14 #include <phymod/phymod_util.h> 15 #include "../../tscf16/tier1/tefmod16.h" 16 #include "../../tscf16/tier1/tefmod16_enum_defines.h" 17 #include "../../tscf16/tier1/tefmod16_device.h" 18 #include "../../falcon16/tier1/src/falcon16_cfg_seq.h" 19 #include "../../falcon16/tier1/include/falcon16_tsc_common.h" 20 #include "../../falcon16/tier1/include/falcon16_tsc_interface.h" 21 #include "../../falcon16/tier1/include/falcon16_tsc_internal.h" 22 #include "../../falcon16/tier1/include/falcon16_tsc_dependencies.h" 23 #include "../../falcon16/tier1/include/falcon16_tsc_types.h" 24 #include "../../falcon16/tier1/include/common/srds_api_enum.h" 25 26 #ifdef PHYMOD_TSCF16_SUPPORT 27 28 #define PATTERN_MAX_LENGTH 240 29 30 31 STATIC 32 int _tscf16_prbs_poly_phymod_to_falcon16(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *falcon16_poly) 33 { 34 switch(phymod_poly){ 35 case phymodPrbsPoly7: 36 *falcon16_poly = PRBS_7; 37 break; 38 case phymodPrbsPoly9: 39 *falcon16_poly = PRBS_9; 40 break; 41 case phymodPrbsPoly11: 42 *falcon16_poly = PRBS_11; 43 break; 44 case phymodPrbsPoly15: 45 *falcon16_poly = PRBS_15; 46 break; 47 case phymodPrbsPoly23: 48 *falcon16_poly = PRBS_23; 49 break; 50 case phymodPrbsPoly31: 51 *falcon16_poly = PRBS_31; 52 break; 53 case phymodPrbsPoly58: 54 *falcon16_poly = PRBS_58; 55 break; 56 default: 57 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly)); 58 } 59 return PHYMOD_E_NONE; 60 } 61 62 STATIC 63 int _tscf16_prbs_poly_tscf16_to_phymod(falcon16_prbs_polynomial_type_t tscf_poly, phymod_prbs_poly_t *phymod_poly) 64 { 65 switch(tscf_poly){ 66 case FALCON16_PRBS_POLYNOMIAL_7: 67 *phymod_poly = phymodPrbsPoly7; 68 break; 69 case FALCON16_PRBS_POLYNOMIAL_9: 70 *phymod_poly = phymodPrbsPoly9; 71 break; 72 case FALCON16_PRBS_POLYNOMIAL_11: 73 *phymod_poly = phymodPrbsPoly11; 74 break; 75 case FALCON16_PRBS_POLYNOMIAL_15: 76 *phymod_poly = phymodPrbsPoly15; 77 break; 78 case FALCON16_PRBS_POLYNOMIAL_23: 79 *phymod_poly = phymodPrbsPoly23; 80 break; 81 case FALCON16_PRBS_POLYNOMIAL_31: 82 *phymod_poly = phymodPrbsPoly31; 83 break; 84 case FALCON16_PRBS_POLYNOMIAL_58: 85 *phymod_poly = phymodPrbsPoly58; 86 break; 87 default: 88 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tscf_poly)); 89 } 90 return PHYMOD_E_NONE; 91 } 92 93 #ifdef PHYMOD_TO_TSCE16_OS_MODE_TRANS 94 STATIC 95 int _tscf16_os_mode_phymod_to_tscf16(phymod_osr_mode_t phymod_os_mode, tefmod16_os_mode_type *tscf_os_mode) 96 { 97 switch(phymod_os_mode){ 98 case phymodOversampleMode1: 99 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_1; 100 break; 101 case phymodOversampleMode2: 102 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_2; 103 break; 104 /*case phymodOversampleMode3: 105 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_3; 106 break; 107 case phymodOversampleMode3P3: 108 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_3_3; 109 break;*/ 110 case phymodOversampleMode4: 111 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_4; 112 break; 113 /*case phymodOversampleMode5: 114 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_5; 115 break; 116 case phymodOversampleMode8: 117 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_8; 118 break; 119 case phymodOversampleMode8P25: 120 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_8_25; 121 break; 122 case phymodOversampleMode10: 123 *tscf_os_mode = TEFMOD16_PMA_OS_MODE_10; 124 break;*/ 125 default: 126 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported over sample mode for tscf16 %u"), phymod_os_mode)); 127 } 128 return PHYMOD_E_NONE; 129 } 130 131 TATIC 132 int _tscf16_os_mode_tscf16_to_phymod(tefmod16_os_mode_type tscf_os_mode, phymod_osr_mode_t *phymod_os_mode) 133 { 134 switch(tscf_os_mode){ 135 case TEFMOD16_PMA_OS_MODE_1: 136 *phymod_os_mode = phymodOversampleMode1; 137 break; 138 case TEFMOD16_PMA_OS_MODE_2: 139 *phymod_os_mode = phymodOversampleMode2; 140 break; 141 /*case TEFMOD16_PMA_OS_MODE_3: 142 *phymod_os_mode = phymodOversampleMode3; 143 break; 144 case TEFMOD16_PMA_OS_MODE_3_3: 145 *phymod_os_mode = phymodOversampleMode3P3; 146 break;*/ 147 case TEFMOD16_PMA_OS_MODE_4: 148 *phymod_os_mode = phymodOversampleMode4; 149 break; 150 /*case TEFMOD16_PMA_OS_MODE_5: 151 *phymod_os_mode = phymodOversampleMode5; 152 break; 153 case TEFMOD16_PMA_OS_MODE_8: 154 *phymod_os_mode = phymodOversampleMode8; 155 break; 156 case TEFMOD16_PMA_OS_MODE_8_25: 157 *phymod_os_mode = phymodOversampleMode8P25; 158 break; 159 case TEFMOD16_PMA_OS_MODE_10: 160 *phymod_os_mode = phymodOversampleMode10; 161 break;*/ 162 default: 163 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown os mode %u"), tscf_os_mode)); 164 } 165 return PHYMOD_E_NONE; 166 } 167 #endif 168 169 int tscf16_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position) 170 { 171 172 173 /* Place your code here */ 174 175 176 return PHYMOD_E_NONE; 177 178 } 179 180 int tscf16_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position) 181 { 182 183 184 /* Place your code here */ 185 186 187 return PHYMOD_E_NONE; 188 189 } 190 191 192 int tscf16_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) 193 { 194 195 196 /* Place your code here */ 197 198 199 return PHYMOD_E_NONE; 200 201 } 202 203 204 int tscf16_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 205 { 206 enum srds_prbs_polynomial_enum falcon16_poly; 207 int i, start_lane, num_lane; 208 phymod_phy_access_t phy_copy; 209 PHYMOD_IF_ERR_RETURN(_tscf16_prbs_poly_phymod_to_falcon16(prbs->poly, &falcon16_poly)); 210 211 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 212 213 /* next figure out the lane num and start_lane based on the input */ 214 PHYMOD_IF_ERR_RETURN 215 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 216 217 /*first check which direction */ 218 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 219 for (i = 0; i < num_lane; i++) { 220 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 221 continue; 222 } 223 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 224 PHYMOD_IF_ERR_RETURN 225 (falcon16_tsc_config_rx_prbs(&phy_copy.access, falcon16_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 226 } 227 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 228 for (i = 0; i < num_lane; i++) { 229 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 230 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 231 continue; 232 } 233 PHYMOD_IF_ERR_RETURN 234 (falcon16_tsc_config_tx_prbs(&phy_copy.access, falcon16_poly, prbs->invert)); 235 } 236 } else { 237 for (i = 0; i < num_lane; i++) { 238 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 239 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 240 continue; 241 } 242 PHYMOD_IF_ERR_RETURN 243 (falcon16_tsc_config_rx_prbs(&phy_copy.access, falcon16_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 244 PHYMOD_IF_ERR_RETURN 245 (falcon16_tsc_config_tx_prbs(&phy_copy.access, falcon16_poly, prbs->invert)); 246 } 247 } 248 249 return PHYMOD_E_NONE; 250 251 } 252 253 int tscf16_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 254 { 255 phymod_prbs_t config_tmp; 256 falcon16_prbs_polynomial_type_t tscf_poly; 257 258 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 259 PHYMOD_IF_ERR_RETURN(falcon16_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 260 PHYMOD_IF_ERR_RETURN(falcon16_prbs_tx_poly_get(&phy->access, &tscf_poly)); 261 PHYMOD_IF_ERR_RETURN(_tscf16_prbs_poly_tscf16_to_phymod(tscf_poly, &config_tmp.poly)); 262 prbs->invert = config_tmp.invert; 263 prbs->poly = config_tmp.poly; 264 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 265 PHYMOD_IF_ERR_RETURN(falcon16_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert)); 266 PHYMOD_IF_ERR_RETURN(falcon16_prbs_rx_poly_get(&phy->access, &tscf_poly)); 267 PHYMOD_IF_ERR_RETURN(_tscf16_prbs_poly_tscf16_to_phymod(tscf_poly, &config_tmp.poly)); 268 prbs->invert = config_tmp.invert; 269 prbs->poly = config_tmp.poly; 270 } else { 271 PHYMOD_IF_ERR_RETURN(falcon16_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert)); 272 PHYMOD_IF_ERR_RETURN(falcon16_prbs_tx_poly_get(&phy->access, &tscf_poly)); 273 PHYMOD_IF_ERR_RETURN(_tscf16_prbs_poly_tscf16_to_phymod(tscf_poly, &config_tmp.poly)); 274 prbs->invert = config_tmp.invert; 275 prbs->poly = config_tmp.poly; 276 } 277 278 return PHYMOD_E_NONE; 279 280 } 281 282 283 int tscf16_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 284 { 285 int i, start_lane, num_lane; 286 phymod_phy_access_t phy_copy; 287 288 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 289 /* next figure out the lane num and start_lane based on the input */ 290 PHYMOD_IF_ERR_RETURN 291 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 292 293 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 294 for (i = 0; i < num_lane; i++) { 295 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 296 continue; 297 } 298 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 299 PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_prbs_en(&phy_copy.access, enable)); 300 } 301 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 302 for (i = 0; i < num_lane; i++) { 303 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 304 continue; 305 } 306 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 307 PHYMOD_IF_ERR_RETURN(falcon16_tsc_rx_prbs_en(&phy_copy.access, enable)); 308 } 309 } else { 310 for (i = 0; i < num_lane; i++) { 311 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 312 continue; 313 } 314 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 315 PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_prbs_en(&phy_copy.access, enable)); 316 PHYMOD_IF_ERR_RETURN(falcon16_tsc_rx_prbs_en(&phy_copy.access, enable)); 317 } 318 } 319 320 return PHYMOD_E_NONE; 321 322 } 323 324 int tscf16_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 325 { 326 uint8_t enable_tmp; 327 328 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 329 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_tx_prbs_en(&phy->access, &enable_tmp)); 330 *enable = enable_tmp; 331 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 332 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_rx_prbs_en(&phy->access, &enable_tmp)); 333 *enable = enable_tmp; 334 } else { 335 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_tx_prbs_en(&phy->access, &enable_tmp)); 336 *enable = enable_tmp; 337 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_rx_prbs_en(&phy->access, &enable_tmp)); 338 *enable &= enable_tmp; 339 } 340 341 return PHYMOD_E_NONE; 342 343 } 344 345 346 int tscf16_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 347 { 348 uint8_t status = 0; 349 uint32_t prbs_err_count = 0; 350 int i, start_lane, num_lane; 351 phymod_phy_access_t phy_copy; 352 353 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 354 /* next figure out the lane num and start_lane based on the input */ 355 PHYMOD_IF_ERR_RETURN 356 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 357 358 prbs_status->prbs_lock = 0; 359 prbs_status->error_count = 0; 360 prbs_status->prbs_lock_loss = 0; 361 prbs_status->prbs_lock = 1; 362 363 for (i = 0; i < num_lane; i++) { 364 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 365 continue; 366 } 367 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 368 PHYMOD_IF_ERR_RETURN(falcon16_tsc_prbs_chk_lock_state(&phy_copy.access, &status)); 369 if (status) { 370 /*next check the lost of lock and error count */ 371 status = 0; 372 PHYMOD_IF_ERR_RETURN 373 (falcon16_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 374 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count)); 375 if (status) { 376 /*temp lost of lock */ 377 prbs_status->prbs_lock_loss = 1; 378 } else { 379 prbs_status->error_count += prbs_err_count; 380 } 381 } else { 382 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i )); 383 prbs_status->prbs_lock = 0; 384 /* return PHYMOD_E_NONE; */ 385 } 386 } 387 388 return PHYMOD_E_NONE; 389 390 } 391 392 393 int tscf16_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern) 394 { 395 int i,j, bit; 396 char patt[PATTERN_MAX_LENGTH+1]; 397 for (i=0; i< PATTERN_MAX_SIZE; i++) 398 { 399 for (j=0; (j<32) && (i*32+j <= PATTERN_MAX_LENGTH); j++) 400 { 401 if (i*32+j == pattern->pattern_len) 402 break; 403 bit = pattern->pattern[i] >> j & 00000001; 404 switch (bit) { 405 case (1): 406 patt[i*32+j]='1'; 407 break; 408 default: 409 patt[i*32+j] = '0'; 410 break; 411 } 412 } 413 if (i*32+j == pattern->pattern_len && i*32+j <= PATTERN_MAX_LENGTH) { 414 /* coverity[overrun-local] */ 415 patt[i*32+j] = '\0'; 416 break; 417 } 418 } 419 420 PHYMOD_IF_ERR_RETURN 421 (falcon16_tsc_config_shared_tx_pattern_idx_set(&phy->access, 422 &pattern->pattern_len )); 423 /* Coverity: divide_by_zero */ 424 if (pattern->pattern_len == 0){ 425 PHYMOD_DEBUG_ERROR (("Invalid pattern length %d\n", pattern->pattern_len)); 426 427 return ERR_CODE_DIAG; 428 } 429 PHYMOD_IF_ERR_RETURN 430 (falcon16_tsc_config_shared_tx_pattern (&phy->access, 431 (uint8_t) pattern->pattern_len, (const char *) patt)); 432 433 return PHYMOD_E_NONE; 434 435 } 436 437 int tscf16_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern) 438 { 439 PHYMOD_IF_ERR_RETURN 440 (falcon16_tsc_config_shared_tx_pattern_idx_get(&phy->access, 441 &pattern->pattern_len, 442 pattern->pattern)); 443 444 return PHYMOD_E_NONE; 445 446 } 447 448 449 int tscf16_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, const phymod_pattern_t* pattern) 450 { 451 PHYMOD_IF_ERR_RETURN 452 (falcon16_tsc_tx_shared_patt_gen_en(&phy->access, (uint8_t) enable, (uint8_t)pattern->pattern_len)); 453 454 return PHYMOD_E_NONE; 455 456 } 457 458 int tscf16_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 459 { 460 PHYMOD_IF_ERR_RETURN 461 (falcon16_tsc_tx_shared_patt_gen_en_get(&phy->access, (uint8_t *) enable)); 462 463 return PHYMOD_E_NONE; 464 465 } 466 467 468 int tscf16_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 469 { 470 int16_t temperature; 471 falcon16_tsc_read_die_temperature(&core->access,&temperature); 472 diag->temperature = temperature ; 473 falcon16_tsc_read_pll_range(&core->access, &diag->pll_range); 474 475 return PHYMOD_E_NONE; 476 477 } 478 479 480 int tscf16_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 481 { 482 phymod_phy_access_t phy_copy; 483 struct falcon16_tsc_detailed_lane_status_st lane_st[4] = {{0}}; 484 int start_lane, num_lane; 485 int tmp_lane_mask; 486 int i = 0; 487 int j = 0; 488 int tmp_ln_msk; 489 uint32_t cmd_type; 490 int is_in_reset = 0; 491 492 if (!type) { 493 cmd_type = (uint32_t)TEFMOD16_DIAG_DSC; 494 } else if ((!PHYMOD_STRCMP(type, "ber")) || 495 (!PHYMOD_STRCMP(type, "Ber")) || 496 (!PHYMOD_STRCMP(type, "BER"))) { 497 cmd_type = (uint32_t)TEFMOD16_DIAG_BER; 498 } else if ((!PHYMOD_STRCMP(type, "config")) || 499 (!PHYMOD_STRCMP(type, "Config")) || 500 (!PHYMOD_STRCMP(type, "CONFIG"))) { 501 cmd_type = (uint32_t)TEFMOD16_DIAG_CFG; 502 } else if ((!PHYMOD_STRCMP(type, "cl72")) || 503 (!PHYMOD_STRCMP(type, "Cl72")) || 504 (!PHYMOD_STRCMP(type, "CL72"))) { 505 cmd_type = (uint32_t)TEFMOD16_DIAG_CL72; 506 } else if ((!PHYMOD_STRCMP(type, "debug")) || 507 (!PHYMOD_STRCMP(type, "Debug")) || 508 (!PHYMOD_STRCMP(type, "DEBUG"))) { 509 cmd_type = (uint32_t)TEFMOD16_DIAG_DEBUG; 510 } else if ((!PHYMOD_STRCMP(type, "state")) || 511 (!PHYMOD_STRCMP(type, "State")) || 512 (!PHYMOD_STRCMP(type, "STATE"))) { 513 cmd_type = (uint32_t)TEFMOD16_DIAG_STATE; 514 } else if ((!PHYMOD_STRCMP(type, "verbose")) || 515 (!PHYMOD_STRCMP(type, "Verbose")) || 516 (!PHYMOD_STRCMP(type, "VERBOSE"))) { 517 cmd_type = (uint32_t)TEFMOD16_DIAG_ALL; 518 } else if (!PHYMOD_STRCMP(type, "STD")) { 519 cmd_type = (uint32_t)TEFMOD16_DIAG_DSC_STD; 520 } else { 521 cmd_type = (uint32_t)TEFMOD16_DIAG_STATE; 522 } 523 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)); 524 525 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 526 527 /*next figure out the lane num and start_lane based on the input*/ 528 PHYMOD_IF_ERR_RETURN 529 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 530 531 if (cmd_type == TEFMOD16_DIAG_DSC) { 532 PHYMOD_IF_ERR_RETURN 533 (falcon16_tsc_display_core_state(&phy_copy.access)); 534 PHYMOD_IF_ERR_RETURN 535 (falcon16_tsc_display_lane_state_hdr()); 536 for (i = 0; i < 4; i++) { 537 phy_copy.access.lane_mask = 0x1 << i ; 538 PHYMOD_IF_ERR_RETURN 539 (tefmod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 540 if (is_in_reset) { 541 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", i)); 542 continue; 543 } 544 PHYMOD_IF_ERR_RETURN 545 (falcon16_tsc_display_lane_state(&phy_copy.access)); 546 } 547 PHYMOD_IF_ERR_RETURN 548 (falcon16_tsc_display_lane_state_legend()); 549 } else if (cmd_type == TEFMOD16_DIAG_DSC_STD) { 550 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 551 PHYMOD_DIAG_OUT((" | DSC Phy: 0x%03x lane_mask: 0x%02x |\n", phy->access.addr, phy->access.lane_mask)); 552 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 553 PHYMOD_IF_ERR_RETURN 554 (falcon16_tsc_display_core_state(&phy_copy.access)); 555 PHYMOD_IF_ERR_RETURN 556 (falcon16_tsc_display_lane_state_hdr()); 557 for (i = 0; i < num_lane; i++) { 558 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 559 PHYMOD_IF_ERR_RETURN 560 (tefmod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 561 if (is_in_reset) { 562 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", (i + start_lane))); 563 continue; 564 } 565 PHYMOD_IF_ERR_RETURN 566 (falcon16_tsc_display_lane_state(&phy_copy.access)); 567 } 568 tmp_ln_msk = phy_copy.access.lane_mask; 569 for (j = 0; j < 4; j++) { 570 phy_copy.access.lane_mask = 0x1 << j; 571 PHYMOD_IF_ERR_RETURN 572 (tefmod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 573 if (is_in_reset) { 574 continue; 575 } 576 PHYMOD_IF_ERR_RETURN 577 (falcon16_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 578 } 579 phy_copy.access.lane_mask = tmp_ln_msk; 580 PHYMOD_IF_ERR_RETURN 581 (falcon16_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 582 PHYMOD_IF_ERR_RETURN 583 (falcon16_tsc_read_event_log(&phy_copy.access)); 584 } else { 585 for (i = 0; i < num_lane; i++) { 586 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 587 588 switch (cmd_type) { 589 case TEFMOD16_DIAG_CFG: 590 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 591 if (i == 0) { 592 tmp_lane_mask = phy_copy.access.lane_mask; 593 phy_copy.access.lane_mask = 1; 594 PHYMOD_IF_ERR_RETURN 595 (falcon16_tsc_display_core_config(&phy_copy.access)); 596 phy_copy.access.lane_mask = tmp_lane_mask; 597 } 598 PHYMOD_IF_ERR_RETURN 599 (falcon16_tsc_display_lane_config(&phy_copy.access)); 600 break; 601 602 case TEFMOD16_DIAG_CL72: 603 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 604 PHYMOD_IF_ERR_RETURN 605 (falcon16_tsc_display_cl93n72_status(&phy_copy.access)); 606 break; 607 608 case TEFMOD16_DIAG_DEBUG: 609 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 610 PHYMOD_IF_ERR_RETURN 611 (falcon16_tsc_display_lane_debug_status(&phy_copy.access)); 612 break; 613 614 case TEFMOD16_DIAG_BER: 615 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__)); 616 break; 617 618 619 case TEFMOD16_DIAG_ALL: 620 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 621 if (i == 0) { 622 tmp_lane_mask = phy_copy.access.lane_mask; 623 phy_copy.access.lane_mask = 1; 624 PHYMOD_IF_ERR_RETURN 625 (falcon16_tsc_display_core_config(&phy_copy.access)); 626 phy_copy.access.lane_mask = tmp_lane_mask; 627 } 628 PHYMOD_IF_ERR_RETURN 629 (falcon16_tsc_display_lane_config(&phy_copy.access)); 630 631 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 632 PHYMOD_IF_ERR_RETURN 633 (falcon16_tsc_display_cl93n72_status(&phy_copy.access)); 634 635 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 636 PHYMOD_IF_ERR_RETURN 637 (falcon16_tsc_display_lane_debug_status(&phy_copy.access)); 638 639 break; 640 case TEFMOD16_DIAG_STATE: 641 default: 642 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__)); 643 PHYMOD_IF_ERR_RETURN 644 (falcon16_tsc_display_core_state(&phy_copy.access)); 645 PHYMOD_IF_ERR_RETURN 646 (falcon16_tsc_display_lane_state_hdr()); 647 PHYMOD_IF_ERR_RETURN 648 (falcon16_tsc_display_lane_state(&phy_copy.access)); 649 tmp_ln_msk = phy_copy.access.lane_mask; 650 for (j = 0; j < 4; j++) { 651 phy_copy.access.lane_mask = 0x1 << j; 652 PHYMOD_IF_ERR_RETURN 653 (tefmod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 654 if (is_in_reset) { 655 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", j)); 656 continue; 657 } 658 PHYMOD_IF_ERR_RETURN 659 (falcon16_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j])); 660 } 661 phy_copy.access.lane_mask = tmp_ln_msk; 662 PHYMOD_IF_ERR_RETURN 663 (falcon16_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4)); 664 PHYMOD_IF_ERR_RETURN 665 (falcon16_tsc_read_event_log(&phy_copy.access)); 666 break; 667 } 668 } 669 } 670 671 return PHYMOD_E_NONE; 672 673 } 674 675 676 int tscf16_phy_pcs_info_dump(const phymod_phy_access_t* phy, const char* type) 677 { 678 679 phymod_phy_access_t phy_copy; 680 681 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 682 PHYMOD_IF_ERR_RETURN (tefmod16_diag_disp(&phy_copy.access, type)); 683 684 685 return PHYMOD_E_NONE; 686 687 } 688 689 int tscf16_phy_fec_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 690 { 691 uint32_t lane_count; 692 uint32_t sum = 0; 693 int i, start_lane, num_lane; 694 phymod_phy_access_t phy_copy; 695 696 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 697 /* next figure out the lane num and start_lane based on the input */ 698 PHYMOD_IF_ERR_RETURN 699 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 700 701 for (i = 0; i < num_lane; i++) { 702 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 703 continue; 704 } 705 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 706 PHYMOD_IF_ERR_RETURN(tefmod16_fec_correctable_counter_get(&phy_copy.access, &lane_count)); 707 /* Check overflow */ 708 if (lane_count > 0xffffffff - sum) { 709 sum = 0xffffffff; 710 break; 711 } else { 712 sum += lane_count; 713 } 714 } 715 716 *count = sum; 717 718 return PHYMOD_E_NONE; 719 } 720 721 int tscf16_phy_fec_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 722 { 723 uint32_t lane_count; 724 uint32_t sum = 0; 725 int i, start_lane, num_lane; 726 phymod_phy_access_t phy_copy; 727 728 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 729 /* next figure out the lane num and start_lane based on the input */ 730 PHYMOD_IF_ERR_RETURN 731 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 732 733 for (i = 0; i < num_lane; i++) { 734 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 735 continue; 736 } 737 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 738 PHYMOD_IF_ERR_RETURN(tefmod16_fec_uncorrectable_counter_get(&phy_copy.access, &lane_count)); 739 /* Check overflow */ 740 if (lane_count > 0xffffffff - sum) { 741 sum = 0xffffffff; 742 break; 743 } else { 744 sum += lane_count; 745 } 746 } 747 748 *count = sum; 749 750 return PHYMOD_E_NONE; 751 } 752 753 int tscf16_phy_fec_cl91_correctable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 754 { 755 int start_lane, num_lane; 756 phymod_phy_access_t phy_copy; 757 758 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 759 /* next figure out the lane num and start_lane based on the input */ 760 PHYMOD_IF_ERR_RETURN 761 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 762 phy_copy.access.lane_mask = 0x1 << start_lane; 763 764 PHYMOD_IF_ERR_RETURN(tefmod16_fec_cl91_correctable_counter_get(&phy_copy.access, count)); 765 766 return PHYMOD_E_NONE; 767 } 768 769 int tscf16_phy_fec_cl91_uncorrectable_counter_get(const phymod_phy_access_t* phy, uint32_t* count) 770 { 771 int start_lane, num_lane; 772 phymod_phy_access_t phy_copy; 773 774 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 775 /* next figure out the lane num and start_lane based on the input */ 776 PHYMOD_IF_ERR_RETURN 777 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 778 phy_copy.access.lane_mask = 0x1 << start_lane; 779 780 PHYMOD_IF_ERR_RETURN(tefmod16_fec_cl91_uncorrectable_counter_get(&phy_copy.access, count)); 781 782 return PHYMOD_E_NONE; 783 } 784 785 #endif /* PHYMOD_TSCF16_SUPPORT */