dino_diagnostics.c (17903B)
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 15 #ifdef PHYMOD_DINO_SUPPORT 16 #include "../tier1/dino_cfg_seq.h" 17 #include "../tier1/dino_diag_seq.h" 18 #include "../tier1/dino_serdes/common/srds_api_enum.h" 19 20 int _dino_phymod_prbs_poly_to_serdes_prbs_poly(uint16_t phymod_poly, uint16_t *serdes_poly) 21 { 22 switch (phymod_poly) { 23 case phymodPrbsPoly7: 24 *serdes_poly = PRBS_7; 25 break; 26 case phymodPrbsPoly9: 27 *serdes_poly = PRBS_9; 28 break; 29 case phymodPrbsPoly11: 30 *serdes_poly = PRBS_11; 31 break; 32 case phymodPrbsPoly15: 33 *serdes_poly = PRBS_15; 34 break; 35 case phymodPrbsPoly23: 36 *serdes_poly = PRBS_23; 37 break; 38 case phymodPrbsPoly31: 39 *serdes_poly = PRBS_31; 40 break; 41 case phymodPrbsPoly58: 42 *serdes_poly = PRBS_58; 43 break; 44 default: 45 return PHYMOD_E_PARAM; 46 } 47 48 return PHYMOD_E_NONE; 49 } 50 int _dino_serdes_prbs_poly_to_phymod_prbs_poly(uint16_t serdes_poly, phymod_prbs_poly_t *phymod_poly) 51 { 52 switch (serdes_poly) { 53 case PRBS_7: 54 *phymod_poly = phymodPrbsPoly7; 55 break; 56 case PRBS_9: 57 *phymod_poly = phymodPrbsPoly9; 58 break; 59 case PRBS_11: 60 *phymod_poly = phymodPrbsPoly11; 61 break; 62 case PRBS_15: 63 *phymod_poly = phymodPrbsPoly15; 64 break; 65 case PRBS_23: 66 *phymod_poly = phymodPrbsPoly23; 67 break; 68 case PRBS_31: 69 *phymod_poly = phymodPrbsPoly31; 70 break; 71 case PRBS_58: 72 *phymod_poly = phymodPrbsPoly58; 73 break; 74 default: 75 return PHYMOD_E_PARAM; 76 } 77 78 return PHYMOD_E_NONE; 79 } 80 81 int dino_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 82 { 83 uint16_t lane = 0; 84 uint16_t lane_mask = 0; 85 uint16_t if_side = 0; 86 int num_lanes = 0; 87 uint32_t chip_id = 0; 88 uint32_t rev_id = 0; 89 const phymod_access_t *pa = &phy->access; 90 91 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 92 DINO_GET_INTF_SIDE(phy, if_side); 93 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 94 DINO_GET_NUM_LANES(chip_id, num_lanes); 95 96 for (lane = 0; lane < num_lanes ; lane ++) { 97 if (lane_mask & (1 << lane)) { 98 PHYMOD_IF_ERR_RETURN ( 99 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 100 PHYMOD_IF_ERR_RETURN( 101 _dino_phy_prbs_config_set(pa, flags, if_side, lane, prbs)); 102 } 103 } 104 PHYMOD_IF_ERR_RETURN ( 105 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 106 107 return PHYMOD_E_NONE; 108 } 109 110 int dino_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 111 { 112 uint16_t lane = 0; 113 uint16_t lane_mask = 0; 114 uint16_t if_side = 0; 115 uint16_t serdes_poly = 0; 116 uint16_t chkr_mode = 0; 117 int num_lanes = 0; 118 uint32_t chip_id = 0; 119 uint32_t rev_id = 0; 120 const phymod_access_t *pa = &phy->access; 121 122 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 123 DINO_GET_INTF_SIDE(phy, if_side); 124 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 125 DINO_GET_NUM_LANES(chip_id, num_lanes); 126 127 for (lane = 0; lane < num_lanes; lane ++) { 128 if ((lane_mask & (1 << lane))) { 129 PHYMOD_IF_ERR_RETURN ( 130 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 131 PHYMOD_IF_ERR_RETURN( 132 _dino_phy_prbs_config_get(pa, flags, if_side, lane, prbs, &serdes_poly, &chkr_mode)); 133 break; 134 } 135 } 136 PHYMOD_IF_ERR_RETURN ( 137 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 138 PHYMOD_DEBUG_VERBOSE(("Checker POLY:%d\n", serdes_poly)); 139 PHYMOD_DEBUG_VERBOSE(("Checker mode:%d\n", chkr_mode)); 140 PHYMOD_IF_ERR_RETURN ( 141 _dino_serdes_prbs_poly_to_phymod_prbs_poly(serdes_poly, &prbs->poly)); 142 143 return PHYMOD_E_NONE; 144 } 145 146 int dino_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 147 { 148 uint16_t lane = 0; 149 uint16_t lane_mask = 0; 150 uint16_t if_side = 0; 151 int num_lanes = 0; 152 uint32_t chip_id = 0; 153 uint32_t rev_id = 0; 154 const phymod_access_t *pa = &phy->access; 155 156 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 157 DINO_GET_INTF_SIDE(phy, if_side); 158 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 159 DINO_GET_NUM_LANES(chip_id, num_lanes); 160 161 for (lane = 0; lane < num_lanes; lane ++) { 162 if (lane_mask & (1 << lane)) { 163 PHYMOD_IF_ERR_RETURN ( 164 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 165 PHYMOD_IF_ERR_RETURN( 166 _dino_phy_prbs_enable_set(pa, flags, if_side, lane, enable)); 167 } 168 } 169 PHYMOD_IF_ERR_RETURN ( 170 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 171 172 return PHYMOD_E_NONE; 173 } 174 175 int dino_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 176 { 177 uint16_t lane = 0; 178 uint16_t lane_mask = 0; 179 uint16_t if_side = 0; 180 int num_lanes = 0; 181 uint32_t chip_id = 0; 182 uint32_t rev_id = 0; 183 const phymod_access_t *pa = &phy->access; 184 185 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 186 DINO_GET_INTF_SIDE(phy, if_side); 187 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 188 DINO_GET_NUM_LANES(chip_id, num_lanes); 189 190 for (lane = 0; lane < num_lanes; lane ++) { 191 if ((lane_mask & (1 << lane))) { 192 PHYMOD_IF_ERR_RETURN ( 193 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 194 PHYMOD_IF_ERR_RETURN( 195 _dino_phy_prbs_enable_get(pa, flags, if_side, lane, enable)); 196 break; 197 } 198 } 199 PHYMOD_IF_ERR_RETURN ( 200 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 201 202 return PHYMOD_E_NONE; 203 } 204 205 int dino_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 206 { 207 uint16_t lane = 0; 208 uint16_t lane_mask = 0; 209 uint16_t if_side = 0; 210 int num_lanes = 0; 211 uint32_t chip_id = 0; 212 uint32_t rev_id = 0; 213 const phymod_access_t *pa = &phy->access; 214 215 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 216 DINO_GET_INTF_SIDE(phy, if_side); 217 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 218 DINO_GET_NUM_LANES(chip_id, num_lanes); 219 220 prbs_status->prbs_lock = 1; 221 prbs_status->prbs_lock_loss = 1; 222 prbs_status->error_count = 0; 223 224 for (lane = 0; lane < num_lanes; lane ++) { 225 if ((lane_mask & (1 << lane))) { 226 PHYMOD_IF_ERR_RETURN ( 227 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 228 PHYMOD_IF_ERR_RETURN( 229 _dino_phy_prbs_status_get(pa, flags, if_side, lane, prbs_status)); 230 } 231 } 232 PHYMOD_IF_ERR_RETURN ( 233 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 234 235 return PHYMOD_E_NONE; 236 } 237 238 int dino_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag) 239 { 240 phymod_phy_access_t phy; 241 const phymod_access_t *pa = &core->access; 242 uint16_t lane_mask = 0; 243 uint16_t if_side = 0; 244 uint16_t lane = 0; 245 int num_lanes = 0; 246 uint32_t chip_id = 0; 247 uint32_t rev_id = 0; 248 249 PHYMOD_MEMCPY(&phy, core, sizeof(phymod_core_access_t)); 250 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 251 DINO_GET_INTF_SIDE((&phy), if_side); 252 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&core->access, &chip_id, &rev_id)); 253 DINO_GET_NUM_LANES(chip_id, num_lanes); 254 255 for (lane = 0; lane < num_lanes; lane ++) { 256 if ((lane_mask & (1 << lane))) { 257 PHYMOD_IF_ERR_RETURN ( 258 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 259 PHYMOD_IF_ERR_RETURN( 260 _dino_core_diagnostics_get(pa, if_side, lane, diag)); 261 break; 262 } 263 } 264 PHYMOD_IF_ERR_RETURN ( 265 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 266 267 return PHYMOD_E_NONE; 268 } 269 270 int dino_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag) 271 { 272 uint16_t lane = 0; 273 uint16_t lane_mask = 0; 274 uint16_t if_side = 0; 275 int num_lanes = 0; 276 uint32_t chip_id = 0; 277 uint32_t rev_id = 0; 278 const phymod_access_t *pa = &phy->access; 279 280 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 281 DINO_GET_INTF_SIDE(phy, if_side); 282 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 283 DINO_GET_NUM_LANES(chip_id, num_lanes); 284 285 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 286 PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr)); 287 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 288 PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side)); 289 PHYMOD_DEBUG_VERBOSE(("***********************************************\n")); 290 291 for (lane = 0; lane < num_lanes; lane ++) { 292 if ((lane_mask & (1 << lane))) { 293 PHYMOD_IF_ERR_RETURN ( 294 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 295 PHYMOD_IF_ERR_RETURN( 296 _dino_phy_diagnostics_get(pa, if_side, lane, diag)); 297 } 298 } 299 PHYMOD_IF_ERR_RETURN ( 300 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 301 302 return PHYMOD_E_NONE; 303 } 304 305 int dino_phy_eyescan_run (const phymod_phy_access_t* phy, uint32_t flags, phymod_eyescan_mode_t mode, const phymod_phy_eyescan_options_t* eyescan_options) 306 { 307 uint16_t lane = 0; 308 uint16_t lane_mask = 0; 309 uint16_t if_side = 0; 310 int num_lanes = 0; 311 uint32_t chip_id = 0; 312 uint32_t rev_id = 0; 313 const phymod_access_t *pa = &phy->access; 314 315 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 316 DINO_GET_INTF_SIDE(phy, if_side); 317 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 318 DINO_GET_NUM_LANES(chip_id, num_lanes); 319 320 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 321 PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr)); 322 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 323 PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side)); 324 PHYMOD_DEBUG_VERBOSE(("***********************************************\n")); 325 326 for (lane = 0; lane < num_lanes; lane ++) { 327 if ((lane_mask & (1 << lane))) { 328 PHYMOD_IF_ERR_RETURN ( 329 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 330 if (PHYMOD_EYESCAN_F_DONE_GET(flags)) { 331 switch(mode) { 332 case phymodEyescanModeFast: 333 PHYMOD_IF_ERR_RETURN ( 334 _dino_phy_display_eyescan(pa, if_side, lane)); 335 break; 336 case phymodEyescanModeBERProj: 337 PHYMOD_IF_ERR_RETURN ( 338 _dino_ber_proj(phy, if_side, lane, eyescan_options)); 339 break; 340 default: 341 PHYMOD_IF_ERR_RETURN ( 342 _dino_phy_display_eyescan(pa, if_side, lane)); 343 break; 344 } 345 } else { 346 return PHYMOD_E_NONE; 347 } 348 } 349 } 350 PHYMOD_IF_ERR_RETURN ( 351 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 352 353 return PHYMOD_E_NONE; 354 } 355 356 int dino_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 357 { 358 uint16_t lane = 0; 359 uint16_t lane_mask = 0; 360 uint16_t if_side = 0; 361 int num_lanes = 0; 362 uint32_t chip_id = 0; 363 uint32_t rev_id = 0; 364 const phymod_access_t *pa = &phy->access; 365 366 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 367 DINO_GET_INTF_SIDE(phy, if_side); 368 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 369 DINO_GET_NUM_LANES(chip_id, num_lanes); 370 371 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 372 PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr)); 373 PHYMOD_DEBUG_VERBOSE(("**********************************************\n")); 374 PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side)); 375 PHYMOD_DEBUG_VERBOSE(("***********************************************\n")); 376 377 /* For core status dump */ 378 for (lane = 0; lane < num_lanes; lane ++) { 379 if ((lane_mask & (1 << lane))) { 380 PHYMOD_IF_ERR_RETURN ( 381 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 382 PHYMOD_IF_ERR_RETURN( 383 _dino_phy_status_dump(pa, if_side, lane)); 384 } 385 } 386 PHYMOD_IF_ERR_RETURN ( 387 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 388 389 return PHYMOD_E_NONE; 390 } 391 392 /** FC/PCS checker enable set 393 * This function is used to enable or disable FC/PCS checker 394 * 395 * @param phy Pointer to phymod phy access structure 396 * @param fcpcs_chkr_mode FC/PCS checker mode 397 * @param enable Enable or disable 398 * 1 - enable 399 * 0 - disable 400 * 401 * @return PHYMOD_E_NONE successful function execution 402 */ 403 int dino_phy_link_mon_enable_set(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t fcpcs_chkr_mode, uint32_t enable) 404 { 405 uint16_t lane = 0; 406 uint16_t lane_mask = 0; 407 uint16_t if_side = 0; 408 int num_lanes = 0; 409 uint32_t chip_id = 0; 410 uint32_t rev_id = 0; 411 const phymod_access_t *pa = &phy->access; 412 413 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 414 DINO_GET_INTF_SIDE(phy, if_side); 415 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 416 DINO_GET_NUM_LANES(chip_id, num_lanes); 417 418 for (lane = 0; lane < num_lanes; lane ++) { 419 if ((lane_mask & (1 << lane))) { 420 PHYMOD_IF_ERR_RETURN ( 421 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 422 PHYMOD_IF_ERR_RETURN( 423 _dino_phy_link_mon_enable_set(pa, enable)); 424 } 425 } 426 427 PHYMOD_IF_ERR_RETURN ( 428 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 429 430 return PHYMOD_E_NONE; 431 } 432 /** FC/PCS checker enable get 433 * This function is used to check whether or not FC/PCS checker enabled 434 * 435 * @param phy Pointer to phymod phy access structure 436 * @param fcpcs_chkr_mode FC/PCS checker mode 437 * @param enable Enable or disable 438 * 1 - enable 439 * 0 - disable 440 * 441 * @return PHYMOD_E_NONE successful function execution 442 */ 443 int dino_phy_link_mon_enable_get(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t fcpcs_chkr_mode, uint32_t *enable) 444 { 445 uint16_t lane = 0; 446 uint16_t lane_mask = 0; 447 uint16_t if_side = 0; 448 int num_lanes = 0; 449 uint32_t chip_id = 0; 450 uint32_t rev_id = 0; 451 const phymod_access_t *pa = &phy->access; 452 453 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 454 DINO_GET_INTF_SIDE(phy, if_side); 455 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 456 DINO_GET_NUM_LANES(chip_id, num_lanes); 457 *enable = 1; 458 459 for (lane = 0; lane < num_lanes; lane ++) { 460 if ((lane_mask & (1 << lane))) { 461 PHYMOD_IF_ERR_RETURN ( 462 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 463 PHYMOD_IF_ERR_RETURN ( 464 _dino_phy_link_mon_enable_get(pa, enable)); 465 break; 466 } 467 } 468 PHYMOD_IF_ERR_RETURN ( 469 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 470 471 return PHYMOD_E_NONE; 472 } 473 /** FC/PCS checker status get 474 * This function is used to lock, loss of lock, error count status of the FC/PCS checker 475 * 476 * @param phy Pointer to phymod phy access structure 477 * @param lock_status Live lock status 478 * 1 - Locked 479 * 0 - Not locked 480 * @param lock_lost_lh Loss of lock 481 * 1 - Loss of lock happened 482 * 0 - No Loss of lock happended 483 * @param error_count Error count 484 * 485 * @return PHYMOD_E_NONE successful function execution 486 */ 487 int dino_phy_link_mon_status_get(const phymod_phy_access_t* phy, uint32_t* lock_status, uint32_t* lock_lost_lh, uint32_t* error_count) 488 { 489 uint16_t lane = 0; 490 uint16_t lane_mask = 0; 491 uint16_t if_side = 0; 492 int num_lanes = 0; 493 uint32_t chip_id = 0; 494 uint32_t rev_id = 0; 495 uint32_t enable = 0; 496 const phymod_access_t *pa = &phy->access; 497 498 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 499 DINO_GET_INTF_SIDE(phy, if_side); 500 PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id)); 501 DINO_GET_NUM_LANES(chip_id, num_lanes); 502 503 *lock_status = 1; 504 *lock_lost_lh = 1; 505 *error_count = 0; 506 enable = 1; 507 508 for (lane = 0; lane < num_lanes; lane ++) { 509 if ((lane_mask & (1 << lane))) { 510 PHYMOD_IF_ERR_RETURN ( 511 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane)); 512 PHYMOD_IF_ERR_RETURN ( 513 _dino_phy_link_mon_enable_get(pa, &enable)); 514 if (enable) { 515 PHYMOD_IF_ERR_RETURN ( 516 _dino_phy_link_mon_status_get(pa, lock_status, lock_lost_lh, error_count)); 517 } else { 518 *lock_status &= 0; 519 *lock_lost_lh &= 1; 520 *error_count = 0; 521 } 522 } 523 } 524 PHYMOD_IF_ERR_RETURN ( 525 _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0)); 526 527 return PHYMOD_E_NONE; 528 } 529 #endif /* PHYMOD_DINO_SUPPORT */