tsce16_diagnostics.c (16574B)
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 "tsce16/tier1/temod16_enum_defines.h" 16 #include "tsce16/tier1/temod16.h" 17 #include "tsce16/tier1/te16PCSRegEnums.h" 18 #include "merlin16/tier1/merlin16_diag.h" 19 #include "merlin16/tier1/merlin16_debug_functions.h" 20 #include "merlin16/tier1/common/srds_api_enum.h" 21 #include "merlin16/tier1/merlin16_prbs.h" 22 23 #ifdef PHYMOD_TSCE16_SUPPORT 24 25 int tsce16_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 26 { 27 int start_lane, num_lane; 28 int tmp_lane_mask; 29 phymod_phy_access_t phy_copy; 30 31 /* struct merlin16_detailed_lane_status_st lane_st[4]; */ 32 int i = 0; 33 uint32_t cmd_type; 34 int is_in_reset = 0; 35 36 37 if (!type) { 38 cmd_type = (uint32_t)TEMOD16_DIAG_DSC; 39 } else if ((!PHYMOD_STRCMP(type, "ber")) || 40 (!PHYMOD_STRCMP(type, "Ber")) || 41 (!PHYMOD_STRCMP(type, "BER"))) { 42 cmd_type = (uint32_t)TEMOD16_DIAG_BER; 43 } else if ((!PHYMOD_STRCMP(type, "config")) || 44 (!PHYMOD_STRCMP(type, "Config")) || 45 (!PHYMOD_STRCMP(type, "CONFIG"))) { 46 cmd_type = (uint32_t)TEMOD16_DIAG_CFG; 47 } else if ((!PHYMOD_STRCMP(type, "cl72")) || 48 (!PHYMOD_STRCMP(type, "Cl72")) || 49 (!PHYMOD_STRCMP(type, "CL72"))) { 50 cmd_type = (uint32_t)TEMOD16_DIAG_CL72; 51 } else if ((!PHYMOD_STRCMP(type, "debug")) || 52 (!PHYMOD_STRCMP(type, "Debug")) || 53 (!PHYMOD_STRCMP(type, "DEBUG"))) { 54 cmd_type = (uint32_t)TEMOD16_DIAG_DEBUG; 55 } else if ((!PHYMOD_STRCMP(type, "state")) || 56 (!PHYMOD_STRCMP(type, "State")) || 57 (!PHYMOD_STRCMP(type, "STATE"))) { 58 cmd_type = (uint32_t)TEMOD16_DIAG_STATE; 59 } else if ((!PHYMOD_STRCMP(type, "verbose")) || 60 (!PHYMOD_STRCMP(type, "Verbose")) || 61 (!PHYMOD_STRCMP(type, "VERBOSE"))) { 62 cmd_type = (uint32_t)TEMOD16_DIAG_ALL; 63 } else if (!PHYMOD_STRCMP(type, "STD")) { 64 cmd_type = (uint32_t)TEMOD16_DIAG_DSC_STD; 65 } else { 66 cmd_type = (uint32_t)TEMOD16_DIAG_STATE; 67 } 68 69 PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask)); 70 71 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 72 73 /*next figure out the lane num and start_lane based on the input*/ 74 PHYMOD_IF_ERR_RETURN 75 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 76 77 if (cmd_type == TEMOD16_DIAG_DSC) { 78 PHYMOD_IF_ERR_RETURN 79 (merlin16_display_core_state(&phy_copy.access)); 80 PHYMOD_IF_ERR_RETURN 81 (merlin16_display_lane_state_hdr()); 82 for (i = 0; i < 4; i++) { 83 phy_copy.access.lane_mask = 0x1 << i ; 84 PHYMOD_IF_ERR_RETURN 85 (temod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 86 if (is_in_reset) { 87 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", i)); 88 continue; 89 } 90 PHYMOD_IF_ERR_RETURN 91 (merlin16_display_lane_state(&phy_copy.access)); 92 } 93 } else if (cmd_type == TEMOD16_DIAG_DSC_STD) { 94 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 95 PHYMOD_DIAG_OUT((" | DSC Phy: 0x%03x lane_mask: 0x%02x |\n", phy->access.addr, phy->access.lane_mask)); 96 PHYMOD_DIAG_OUT((" +--------------------------------------------------------------------+\n")); 97 PHYMOD_IF_ERR_RETURN 98 (merlin16_display_core_state(&phy_copy.access)); 99 PHYMOD_IF_ERR_RETURN 100 (merlin16_display_lane_state_hdr()); 101 for (i = 0; i < num_lane; i++) { 102 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 103 PHYMOD_IF_ERR_RETURN 104 (temod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset)); 105 if (is_in_reset) { 106 PHYMOD_DIAG_OUT((" - skip lane=%0d\n", (i + start_lane))); 107 continue; 108 } 109 PHYMOD_IF_ERR_RETURN 110 (merlin16_display_lane_state(&phy_copy.access)); 111 } 112 113 PHYMOD_IF_ERR_RETURN 114 (merlin16_read_event_log(&phy_copy.access)); 115 } else { 116 for (i = 0; i < num_lane; i++) { 117 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 118 119 switch (cmd_type) { 120 case TEMOD16_DIAG_CFG: 121 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 122 if (i==0) { 123 tmp_lane_mask = phy_copy.access.lane_mask; 124 phy_copy.access.lane_mask = 1; 125 PHYMOD_IF_ERR_RETURN 126 (merlin16_display_core_config(&phy_copy.access)); 127 phy_copy.access.lane_mask = tmp_lane_mask; 128 } 129 PHYMOD_IF_ERR_RETURN 130 (merlin16_display_lane_config(&phy_copy.access)); 131 break; 132 case TEMOD16_DIAG_CL72: 133 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 134 PHYMOD_IF_ERR_RETURN 135 (merlin16_display_cl72_status(&phy_copy.access)); 136 break; 137 case TEMOD16_DIAG_DEBUG: 138 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 139 PHYMOD_IF_ERR_RETURN 140 (merlin16_display_lane_debug_status(&phy_copy.access)); 141 break; 142 case TEMOD16_DIAG_BER: 143 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__)); 144 break; 145 case TEMOD16_DIAG_ALL: 146 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__)); 147 if (i==0) { 148 tmp_lane_mask = phy_copy.access.lane_mask; 149 phy_copy.access.lane_mask = 1; 150 PHYMOD_IF_ERR_RETURN 151 (merlin16_display_core_config(&phy_copy.access)); 152 phy_copy.access.lane_mask = tmp_lane_mask; 153 } 154 PHYMOD_IF_ERR_RETURN 155 (merlin16_display_lane_config(&phy_copy.access)); 156 157 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__)); 158 PHYMOD_IF_ERR_RETURN 159 (merlin16_display_cl72_status(&phy_copy.access)); 160 161 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__)); 162 PHYMOD_IF_ERR_RETURN 163 (merlin16_display_lane_debug_status(&phy_copy.access)); 164 break; 165 case TEMOD16_DIAG_STATE: 166 default: 167 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__)); 168 PHYMOD_IF_ERR_RETURN 169 (merlin16_display_core_state_hdr()); 170 PHYMOD_IF_ERR_RETURN 171 (merlin16_display_core_state_line(&phy_copy.access)); 172 PHYMOD_IF_ERR_RETURN 173 (merlin16_display_core_state(&phy_copy.access)); 174 PHYMOD_IF_ERR_RETURN 175 (merlin16_display_lane_state_hdr()); 176 PHYMOD_IF_ERR_RETURN 177 (merlin16_display_lane_state(&phy_copy.access)); 178 PHYMOD_IF_ERR_RETURN 179 (merlin16_read_event_log(&phy_copy.access)); 180 break; 181 } 182 } 183 } 184 return PHYMOD_E_NONE; 185 } 186 187 int tsce16_phy_pcs_info_dump(const phymod_phy_access_t* phy, const char* type) 188 { 189 phymod_phy_access_t phy_copy; 190 191 PHYMOD_MEMCPY (&phy_copy, phy, sizeof(phy_copy)); 192 PHYMOD_IF_ERR_RETURN (temod16_diag_disp(&phy_copy.access, type)); 193 194 return PHYMOD_E_NONE; 195 } 196 197 STATIC 198 int _tsce16_prbs_poly_phymod_to_merlin16(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *merlin16_poly) 199 { 200 switch(phymod_poly){ 201 case phymodPrbsPoly7: 202 *merlin16_poly = PRBS_7; 203 break; 204 case phymodPrbsPoly9: 205 *merlin16_poly = PRBS_9; 206 break; 207 case phymodPrbsPoly11: 208 *merlin16_poly = PRBS_11; 209 break; 210 case phymodPrbsPoly15: 211 *merlin16_poly = PRBS_15; 212 break; 213 case phymodPrbsPoly23: 214 *merlin16_poly = PRBS_23; 215 break; 216 case phymodPrbsPoly31: 217 *merlin16_poly = PRBS_31; 218 break; 219 case phymodPrbsPoly58: 220 *merlin16_poly = PRBS_58; 221 break; 222 default: 223 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tsce16 %u"), phymod_poly)); 224 } 225 return PHYMOD_E_NONE; 226 } 227 228 STATIC 229 int _tsce16_prbs_poly_merlin16_to_phymod(enum srds_prbs_polynomial_enum merlin16_poly, phymod_prbs_poly_t *phymod_poly) 230 { 231 switch(merlin16_poly){ 232 case PRBS_7: 233 *phymod_poly = phymodPrbsPoly7; 234 break; 235 case PRBS_9: 236 *phymod_poly = phymodPrbsPoly9; 237 break; 238 case PRBS_11: 239 *phymod_poly = phymodPrbsPoly11; 240 break; 241 case PRBS_15: 242 *phymod_poly = phymodPrbsPoly15; 243 break; 244 case PRBS_23: 245 *phymod_poly = phymodPrbsPoly23; 246 break; 247 case PRBS_31: 248 *phymod_poly = phymodPrbsPoly31; 249 break; 250 case PRBS_58: 251 *phymod_poly = phymodPrbsPoly58; 252 break; 253 default: 254 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), merlin16_poly)); 255 } 256 return PHYMOD_E_NONE; 257 } 258 259 int tsce16_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 260 { 261 enum srds_prbs_polynomial_enum merlin16_poly; 262 int i, start_lane, num_lane; 263 phymod_phy_access_t phy_copy; 264 PHYMOD_IF_ERR_RETURN(_tsce16_prbs_poly_phymod_to_merlin16(prbs->poly, &merlin16_poly)); 265 266 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 267 268 /* next figure out the lane num and start_lane based on the input */ 269 PHYMOD_IF_ERR_RETURN 270 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 271 272 /*first check which direction */ 273 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 274 for (i = 0; i < num_lane; i++) { 275 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 276 continue; 277 } 278 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 279 PHYMOD_IF_ERR_RETURN 280 (merlin16_config_rx_prbs(&phy_copy.access, merlin16_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 281 } 282 } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 283 for (i = 0; i < num_lane; i++) { 284 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 285 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 286 continue; 287 } 288 PHYMOD_IF_ERR_RETURN 289 (merlin16_config_tx_prbs(&phy_copy.access, merlin16_poly, prbs->invert)); 290 } 291 } else { 292 for (i = 0; i < num_lane; i++) { 293 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 294 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 295 continue; 296 } 297 PHYMOD_IF_ERR_RETURN 298 (merlin16_config_rx_prbs(&phy_copy.access, merlin16_poly, PRBS_INITIAL_SEED_HYSTERESIS, prbs->invert)); 299 PHYMOD_IF_ERR_RETURN 300 (merlin16_config_tx_prbs(&phy_copy.access, merlin16_poly, prbs->invert)); 301 } 302 } 303 304 return PHYMOD_E_NONE; 305 } 306 307 int tsce16_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 308 { 309 enum srds_prbs_polynomial_enum merlin16_poly; 310 enum srds_prbs_checker_mode_enum merlin16_checker_mode; 311 uint8_t invert; 312 313 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 314 PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_config(&phy->access, &merlin16_poly, &invert)); 315 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 316 PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_config(&phy->access, &merlin16_poly, &merlin16_checker_mode, &invert)); 317 } else { 318 PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_config(&phy->access, &merlin16_poly, &invert)); 319 } 320 321 prbs->invert = (uint32_t) invert; 322 PHYMOD_IF_ERR_RETURN(_tsce16_prbs_poly_merlin16_to_phymod(merlin16_poly, &(prbs->poly))); 323 324 return PHYMOD_E_NONE; 325 } 326 327 328 int tsce16_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 329 { 330 int i, start_lane, num_lane; 331 phymod_phy_access_t phy_copy; 332 333 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 334 /* next figure out the lane num and start_lane based on the input */ 335 PHYMOD_IF_ERR_RETURN 336 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 337 338 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 339 for (i = 0; i < num_lane; i++) { 340 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 341 continue; 342 } 343 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 344 PHYMOD_IF_ERR_RETURN(merlin16_tx_prbs_en(&phy_copy.access, enable)); 345 } 346 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 347 for (i = 0; i < num_lane; i++) { 348 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 349 continue; 350 } 351 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 352 PHYMOD_IF_ERR_RETURN(merlin16_rx_prbs_en(&phy_copy.access, enable)); 353 } 354 } else { 355 for (i = 0; i < num_lane; i++) { 356 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 357 continue; 358 } 359 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 360 PHYMOD_IF_ERR_RETURN(merlin16_tx_prbs_en(&phy_copy.access, enable)); 361 PHYMOD_IF_ERR_RETURN(merlin16_rx_prbs_en(&phy_copy.access, enable)); 362 } 363 } 364 365 return PHYMOD_E_NONE; 366 } 367 368 int tsce16_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 369 { 370 uint8_t enable_tmp; 371 372 if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 373 PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_en(&phy->access, &enable_tmp)); 374 *enable = enable_tmp; 375 } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 376 PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_en(&phy->access, &enable_tmp)); 377 *enable = enable_tmp; 378 } else { 379 PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_en(&phy->access, &enable_tmp)); 380 *enable = enable_tmp; 381 PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_en(&phy->access, &enable_tmp)); 382 *enable &= enable_tmp; 383 } 384 385 return PHYMOD_E_NONE; 386 } 387 388 389 int tsce16_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 390 { 391 uint8_t status = 0; 392 uint32_t prbs_err_count = 0; 393 int i, start_lane, num_lane; 394 phymod_phy_access_t phy_copy; 395 396 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 397 /* next figure out the lane num and start_lane based on the input */ 398 PHYMOD_IF_ERR_RETURN 399 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 400 401 prbs_status->prbs_lock = 0; 402 prbs_status->error_count = 0; 403 prbs_status->prbs_lock_loss = 0; 404 prbs_status->prbs_lock = 1; 405 406 for (i = 0; i < num_lane; i++) { 407 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 408 continue; 409 } 410 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 411 PHYMOD_IF_ERR_RETURN(merlin16_prbs_chk_lock_state(&phy_copy.access, &status)); 412 if (status) { 413 /*next check the lost of lock and error count */ 414 status = 0; 415 PHYMOD_IF_ERR_RETURN 416 (merlin16_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status)); 417 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count)); 418 if (status) { 419 /*temp lost of lock */ 420 prbs_status->prbs_lock_loss = 1; 421 } else { 422 prbs_status->error_count += prbs_err_count; 423 } 424 } else { 425 PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i )); 426 prbs_status->prbs_lock = 0; 427 /* return PHYMOD_E_NONE; */ 428 } 429 } 430 431 return PHYMOD_E_NONE; 432 } 433 434 435 #endif /* PHYMOD_TSCE16_SUPPORT */