blackhawk_tsc_diag.c (93512B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : blackhawk_tsc_diag.c * 4 * Created On : 03 Nov 2015 * 5 * Created By : Brent Roberts * 6 * Description : Diagnostic APIs for Serdes IPs * 7 * Revision : * 8 * * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. * 12 * No portions of this material may be reproduced in any form without * 13 * the written permission of: * 14 * Broadcom Corporation * 15 * 5300 California Avenue * 16 * Irvine, CA 92617 * 17 * * 18 * All information contained in this document is Broadcom Corporation * 19 * company private proprietary, and trade secret. * 20 */ 21 22 /** @file blackhawk_tsc_diag.c 23 * Implementation of API functions 24 */ 25 26 #ifdef EXCLUDE_STD_HEADERS 27 #include <stdio.h> 28 #include <math.h> 29 #endif 30 31 #ifdef SERDES_API_FLOATING_POINT 32 #include <math.h> 33 #endif 34 35 #include <phymod/phymod_system.h> 36 #include "blackhawk_tsc_diag.h" 37 #include "blackhawk_tsc_access.h" 38 #include "blackhawk_tsc_config.h" 39 #include "blackhawk_tsc_debug_functions.h" 40 #include "blackhawk_tsc_functions.h" 41 #include "blackhawk_tsc_internal.h" 42 #include "blackhawk_tsc_internal_error.h" 43 #include "blackhawk_tsc_prbs.h" 44 #include "blackhawk_tsc_select_defns.h" 45 46 47 /************************************/ 48 /* Display Eye Scan */ 49 /************************************/ 50 51 52 /* Timestamp check to see if heartbeat timer is programmed correctly for the COMCLK frequency it is running at */ 53 err_code_t blackhawk_tsc_test_uc_timestamp(srds_access_t *sa__) { 54 55 #ifdef SERDES_API_FLOATING_POINT 56 uint16_t time; 57 USR_DOUBLE resolution; 58 const uint16_t test_delay=400; 59 60 const USR_DOUBLE max_resolution=11.0; 61 const USR_DOUBLE min_resolution=9.0; 62 63 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_UC_DBG,CMD_UC_DBG_TIMESTAMP,100)); 64 ESTM(time=rd_uc_dsc_data()); 65 USR_DELAY_MS(test_delay); 66 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_UC_DBG,CMD_UC_DBG_TIMESTAMP,100)); 67 ESTM(time=rd_uc_dsc_data()-time); 68 resolution=test_delay*1000.0/(double)time; 69 if((resolution<min_resolution)||(resolution>max_resolution)){ 70 EFUN_PRINTF(("\nERROR : Lane %i:\tuC timestamp: %i\t\tResolution: %.1fms/count. Passing resolution limits:\tMax: %.1fms/count\tMin: %.1fms/count\n",blackhawk_tsc_get_lane(sa__),time,resolution,max_resolution,min_resolution)); 71 return(ERR_CODE_DIAG_TIMESTAMP_FAIL); 72 } 73 else { 74 EFUN_PRINTF(("\nPassed timestamp check : Lane %i:\tuC timestamp: %i\t\tResolution: %.1fms/count. Passing resolution limits:\tMax: %.1fms/count\tMin: %.1fms/count\n",blackhawk_tsc_get_lane(sa__),time,resolution,max_resolution,min_resolution)); 75 } 76 #else 77 EFUN_PRINTF(("This function needs SERDES_API_FLOATING_POINT define to operate \n")); 78 #endif 79 return(ERR_CODE_NONE); 80 } 81 82 83 /* This is best method for terminal ASCII display */ 84 err_code_t blackhawk_tsc_display_eye_scan(srds_access_t *sa__) { 85 uint32_t stripe[64] = {0}; 86 uint16_t status = 0; 87 int8_t y,y_max,y_step; 88 89 y_max = EYE_SCAN_NRZ_VERTICAL_IDX_MAX; 90 y_step = EYE_SCAN_NRZ_VERTICAL_STEP; 91 { 92 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 93 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 94 if (pam_mode == PAM4_NS) { 95 y_max = EYE_SCAN_PAM_VERTICAL_IDX_MAX; 96 y_step = EYE_SCAN_PAM_VERTICAL_STEP; 97 } 98 else if (pam_mode == PAM4_ES) { 99 y_max = EYE_SCAN_PAM_VERTICAL_IDX_MAX; 100 y_step = EYE_SCAN_PAM_VERTICAL_STEP; 101 { 102 uint32_t version=0; 103 ESTM(version = rdcv_common_ucode_version() & 0x0FFF); 104 ESTM(version = (version<<8) | rdcv_common_ucode_minor_version()); 105 if(version<0x0200) { 106 EFUN_PRINTF(("\n!!!2-D EYE SCAN IS NOT SUPPORTED FOR PAM4 ES MODE WITH THE CURRENT VERSION OF UCODE!!!\n\n")); 107 return (ERR_CODE_NONE); 108 } 109 } 110 } 111 } 112 113 EFUN(blackhawk_tsc_display_eye_scan_header(1)); 114 115 /* start horizontal acquisition */ 116 { err_code_t err_code = blackhawk_tsc_meas_eye_scan_start(sa__, EYE_SCAN_HORIZ); 117 if (err_code) { 118 EFUN((blackhawk_tsc_meas_eye_scan_done(sa__), err_code)); 119 } 120 } 121 122 for (y = y_max;y>=-y_max;y=y-y_step) 123 { 124 { err_code_t err_code = blackhawk_tsc_read_eye_scan_stripe(sa__, &stripe[0], &status); 125 if (err_code) { 126 EFUN((blackhawk_tsc_meas_eye_scan_done(sa__), err_code)); 127 } 128 } 129 EFUN(blackhawk_tsc_display_eye_scan_stripe(sa__, y,&stripe[0])); 130 EFUN_PRINTF(("\n")); 131 } 132 /* stop acquisition */ 133 EFUN(blackhawk_tsc_meas_eye_scan_done(sa__)); 134 EFUN(blackhawk_tsc_display_eye_scan_footer(1)); 135 136 return(ERR_CODE_NONE); 137 } 138 139 err_code_t blackhawk_tsc_meas_eye_scan_start(srds_access_t *sa__, uint8_t direction) { 140 uint8_t lock; 141 142 ESTM(lock = rd_pmd_rx_lock()); 143 if(lock == 0) { 144 EFUN_PRINTF(("Error: No PMD_RX_LOCK on lane requesting 2D eye scan\n")); 145 return(ERR_CODE_DIAG_SCAN_NOT_COMPLETE); 146 } 147 if(direction == EYE_SCAN_VERTICAL) { 148 EFUN(blackhawk_tsc_pmd_uc_diag_cmd(sa__, CMD_UC_DIAG_START_VSCAN_EYE,GRACEFUL_STOP_TIME)); 149 } else if(direction == EYE_SCAN_HORIZ) { 150 EFUN(blackhawk_tsc_pmd_uc_diag_cmd(sa__, CMD_UC_DIAG_START_HSCAN_EYE,GRACEFUL_STOP_TIME)); 151 } else if(direction == EYE_SCAN_SLICE) { 152 EFUN(blackhawk_tsc_pmd_uc_diag_cmd(sa__, CMD_UC_DIAG_START_EYE_SLICE,GRACEFUL_STOP_TIME)); 153 } 154 return(ERR_CODE_NONE); 155 } 156 157 err_code_t blackhawk_tsc_INTERNAL_poll_diag_data(srds_access_t *sa__, srds_info_t *blackhawk_tsc_info_ptr, uint16_t *status, uint8_t *diag_rd_ptr, uint8_t byte_count, uint32_t timeout_ms) { 158 uint32_t lane_diag_size; 159 uint16_t loop; 160 161 CHECK_AND_RETURN_IF_NULL(blackhawk_tsc_info_ptr, ERR_CODE_INVALID_INFO_TABLE_ADDR); 162 lane_diag_size = blackhawk_tsc_info_ptr->diag_mem_ram_size; 163 *diag_rd_ptr = 0; 164 165 if(!status) { 166 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 167 } 168 169 /** If the byte_count is too high, then there might be problems not updating 170 * the read pointer fast enough. 171 */ 172 if (byte_count > (lane_diag_size / 2)) { 173 ESTM_PRINTF(("\nERROR : blackhawk_tsc_INTERNAL_poll_diag_data() has excessive byte count of %d.\n", byte_count)); 174 return (blackhawk_tsc_error(sa__, ERR_CODE_DIAG_TIMEOUT)); 175 } 176 177 ESTM(*diag_rd_ptr = rdv_usr_diag_rd_ptr()); 178 179 /* Wait until byte_count bytes are available to be read in the diagnostic memory. */ 180 loop = 0; 181 while (1) { 182 uint8_t diag_wr_ptr, full_count; 183 184 ESTM(diag_wr_ptr = rdv_usr_diag_wr_ptr()); 185 if (diag_wr_ptr >= *diag_rd_ptr) { 186 full_count = diag_wr_ptr - *diag_rd_ptr; 187 } else { 188 full_count = (uint16_t)diag_wr_ptr + lane_diag_size - *diag_rd_ptr; 189 } 190 if (full_count >= byte_count) { 191 break; 192 } 193 194 ++loop; 195 if (loop > 10) { 196 EFUN(USR_DELAY_US(10*timeout_ms)); 197 } 198 if (loop > 1000) { 199 return(blackhawk_tsc_error(sa__, ERR_CODE_DIAG_TIMEOUT)); 200 } 201 } 202 ESTM(*status = rdv_usr_diag_status() & 0xFF); 203 return(ERR_CODE_NONE); 204 } 205 206 typedef struct { 207 uint32_t *buffer_ptr; 208 } blackhawk_tsc_read_eye_scan_stripe_callback_arg_t; 209 210 static err_code_t blackhawk_tsc_read_eye_scan_stripe_callback(void *arg, uint8_t byte_count, uint16_t data) { 211 blackhawk_tsc_read_eye_scan_stripe_callback_arg_t * const cast_arg = (blackhawk_tsc_read_eye_scan_stripe_callback_arg_t *)arg; 212 *(cast_arg->buffer_ptr++) = blackhawk_tsc_INTERNAL_float8_to_int32((float8_t)(data & 0xFF)); 213 if (byte_count > 1) { 214 *(cast_arg->buffer_ptr++) = blackhawk_tsc_INTERNAL_float8_to_int32((float8_t)(data >> 8)); 215 } 216 return (ERR_CODE_NONE); 217 } 218 219 err_code_t blackhawk_tsc_read_eye_scan_stripe(srds_access_t *sa__, uint32_t *buffer, uint16_t *status) { 220 srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(sa__); 221 const uint8_t lane = blackhawk_tsc_get_lane(sa__); 222 const uint8_t stripe_size = 64; 223 224 blackhawk_tsc_read_eye_scan_stripe_callback_arg_t arg; 225 uint32_t lane_diag_base; 226 uint8_t diag_rd_ptr; 227 228 #ifdef PHYMOD_SUPPORT 229 if ( blackhawk_tsc_info_ptr == NULL ) { 230 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 231 } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 232 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 233 } 234 #endif /* PHYMOD_SUPPORT */ 235 236 if(!buffer || !status) { 237 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 238 } 239 240 EFUN(blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(blackhawk_tsc_info_ptr, sa__)); 241 242 lane_diag_base = blackhawk_tsc_info_ptr->diag_mem_ram_base + ((lane%blackhawk_tsc_info_ptr->lane_count) * blackhawk_tsc_info_ptr->diag_mem_ram_size) + 243 blackhawk_tsc_info_ptr->grp_ram_size*blackhawk_tsc_INTERNAL_grp_idx_from_lane(blackhawk_tsc_get_physical_lane(sa__)); 244 245 EFUN(blackhawk_tsc_INTERNAL_poll_diag_data(sa__, blackhawk_tsc_info_ptr, status, &diag_rd_ptr, stripe_size, 400)); 246 247 arg.buffer_ptr = buffer; 248 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 249 lane_diag_base, 250 blackhawk_tsc_info_ptr->diag_mem_ram_size, 251 diag_rd_ptr, 252 stripe_size, 253 &arg, 254 blackhawk_tsc_read_eye_scan_stripe_callback)); 255 256 diag_rd_ptr = ((uint32_t)diag_rd_ptr + stripe_size) % blackhawk_tsc_info_ptr->diag_mem_ram_size; 257 EFUN(wrv_usr_diag_rd_ptr(diag_rd_ptr)); 258 ESTM(*status = rdv_usr_diag_status() & 0xFF); 259 return(ERR_CODE_NONE); 260 } 261 262 err_code_t blackhawk_tsc_display_eye_scan_stripe(srds_access_t *sa__, int8_t y,uint32_t *buffer) { 263 264 265 uint32_t limits[7] = {1835008, 183501, 18350, 1835, 184, 18, 2}; 266 267 int8_t x,i; 268 int16_t level; 269 270 enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ; 271 EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode)); 272 if (pam_mode != NRZ) { 273 for (i=0;i<7;i++) { 274 limits[i] = limits[i] * 2; 275 } 276 } 277 278 level = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, y,0); 279 280 if(!buffer) { 281 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 282 } 283 284 EFUN_PRINTF(("%6dmV : ", level)); 285 286 for (x=-31;x<32;x++) { 287 for (i=0;i<7;i++) { 288 if (buffer[x+31]>=limits[i]) { 289 EFUN_PRINTF(("%c", '0'+i+1)); 290 break; 291 } 292 } 293 if (i==7) { 294 if ((x%5)==0 && (y%5)==0) {EFUN_PRINTF(("+"));} 295 else if ((x%5)!=0 && (y%5)==0) {EFUN_PRINTF(("-"));} 296 else if ((x%5)==0 && (y%5)!=0) {EFUN_PRINTF((":"));} 297 else {EFUN_PRINTF((" "));} 298 } 299 } 300 return(ERR_CODE_NONE); 301 } 302 303 err_code_t blackhawk_tsc_display_eye_scan_header(int8_t i) { 304 int8_t x; 305 EFUN_PRINTF(("\n")); 306 EFUN_PRINTF((" Each character N represents approximate error rate 1e-N at that location\n")); 307 for(x=1;x<=i;x++) { 308 EFUN_PRINTF((" UI/64 : -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30")); 309 } 310 EFUN_PRINTF(("\n")); 311 for(x=1;x<=i;x++) { 312 EFUN_PRINTF((" : -|----|----|----|----|----|----|----|----|----|----|----|----|-")); 313 } 314 EFUN_PRINTF(("\n")); 315 return(ERR_CODE_NONE); 316 } 317 318 err_code_t blackhawk_tsc_display_eye_scan_footer(int8_t i) { 319 int8_t x; 320 for(x=1;x<=i;x++) { 321 EFUN_PRINTF((" : -|----|----|----|----|----|----|----|----|----|----|----|----|-")); 322 } 323 EFUN_PRINTF(("\n")); 324 for(x=1;x<=i;x++) { 325 EFUN_PRINTF((" UI/64 : -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30")); 326 } 327 EFUN_PRINTF(("\n")); 328 return(ERR_CODE_NONE); 329 } 330 331 332 err_code_t blackhawk_tsc_read_eye_scan_status(srds_access_t *sa__, uint16_t *status) { 333 334 if(!status) { 335 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 336 } 337 338 ESTM(*status=rdv_usr_diag_status()); 339 340 return(ERR_CODE_NONE); 341 } 342 343 344 err_code_t blackhawk_tsc_meas_eye_scan_done(srds_access_t *sa__) { 345 EFUN(blackhawk_tsc_pmd_uc_diag_cmd(sa__, CMD_UC_DIAG_DISABLE,GRACEFUL_STOP_TIME)); 346 return(ERR_CODE_NONE); 347 } 348 349 350 err_code_t blackhawk_tsc_start_ber_scan_test(srds_access_t *sa__, uint8_t ber_scan_mode, uint8_t timer_control, uint8_t max_error_control) { 351 uint8_t lock,sts; 352 ESTM(lock = rd_pmd_rx_lock()); 353 if(lock == 0) { 354 EFUN_PRINTF(("Error: No PMD_RX_LOCK on lane requesting BER scan\n")); 355 return(ERR_CODE_DIAG_SCAN_NOT_COMPLETE); 356 } 357 ESTM(sts =rdv_usr_sts_micro_stopped()); 358 if(sts > 1) { 359 EFUN_PRINTF(("Error: Lane is busy (%d) requesting BER scan\n",sts)); 360 return(ERR_CODE_DIAG_SCAN_NOT_COMPLETE); 361 } 362 363 EFUN(wrcv_diag_max_time_control(timer_control)); 364 EFUN(wrcv_diag_max_err_control(max_error_control)); 365 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_CAPTURE_BER_START, ber_scan_mode,GRACEFUL_STOP_TIME)); 366 return(ERR_CODE_NONE); 367 } 368 369 err_code_t blackhawk_tsc_read_ber_scan_data(srds_access_t *sa__, uint32_t *errors, uint32_t *timer_values, uint8_t *cnt, uint32_t timeout) { 370 uint8_t i,prbs_byte,prbs_multi,time_byte,time_multi; 371 uint16_t sts,dataword; 372 373 374 if(!errors || !timer_values || !cnt) { 375 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 376 } 377 /* init data arrays */ 378 for(i=0;i< DIAG_MAX_SAMPLES;i++) { 379 errors[i]=0; 380 timer_values[i]=0; 381 } 382 /* Check for completion read ln.diag_status byte?*/ 383 ESTM(sts = rdv_usr_diag_status()); 384 if((sts & 0x8000) == 0) { 385 return(blackhawk_tsc_error(sa__, ERR_CODE_DATA_NOTAVAIL)); 386 } 387 *cnt = (sts & 0x00FF)/3; 388 for(i=0;i < *cnt;i++) { 389 /* Read 2 bytes of data */ 390 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_READ_DIAG_DATA_WORD, 0, timeout)); 391 ESTM(dataword = rd_uc_dsc_data()); /* LSB contains 2 -4bit nibbles */ 392 time_byte = (uint8_t)(dataword>>8); /* MSB is time byte */ 393 prbs_multi = (uint8_t)dataword & 0x0F; /* split nibbles */ 394 time_multi = (uint8_t)dataword>>4; 395 /* Read 1 bytes of data */ 396 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_READ_DIAG_DATA_BYTE, 0, timeout)); 397 ESTM(prbs_byte = (uint8_t)rd_uc_dsc_data()); 398 errors[i] = blackhawk_tsc_INTERNAL_float12_to_uint32(prbs_byte,prbs_multi); /* convert 12bits to uint32 */ 399 timer_values[i] = (blackhawk_tsc_INTERNAL_float12_to_uint32(time_byte,time_multi)<<3); 400 /* EFUN_PRINTF(("Err=%d (%02x<<%d); Time=%d (%02x<<%d)\n",errors[i],prbs_byte,prbs_multi,timer_values[i],time_byte,time_multi<<3)); */ 401 /*if(timer_values[i] == 0 && errors[i] == 0) break;*/ 402 } 403 404 return(ERR_CODE_NONE); 405 } 406 407 408 /* This is good example function to do BER extrapolation */ 409 err_code_t blackhawk_tsc_eye_margin_proj(srds_access_t *sa__, USR_DOUBLE rate, uint8_t ber_scan_mode, uint8_t timer_control, uint8_t max_error_control) { 410 uint32_t errs[DIAG_MAX_SAMPLES]; 411 uint32_t time[DIAG_MAX_SAMPLES]; 412 uint8_t i,cnt=0; 413 uint16_t sts; 414 int16_t offset_start; 415 /* Below 'DIAG_VERBOSE' level is intended to be modified only within a debug */ 416 /* session immediately after a breakpoint, and to retain its state only */ 417 /* through function exit: therefore it must be 'volatile' to prevent a */ 418 /* compiler from eliding code conditioned on it, but NOT 'static'. */ 419 420 421 for(i=0;i<DIAG_MAX_SAMPLES;i++) { 422 errs[i]=0; 423 time[i]=0; 424 } 425 /* start UC acquisition */ 426 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("start begin\n")); 427 EFUN(blackhawk_tsc_start_ber_scan_test(sa__, ber_scan_mode, timer_control, max_error_control)); 428 ESTM(offset_start = rd_uc_dsc_data()); 429 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("offset_start = %d:%dmV\n",offset_start,blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)offset_start,0))); 430 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("start done\n")); 431 432 /* This wait is VERY LONG and should be replaced with interupt or something */ 433 if(DIAG_VERBOSE > 5) { 434 do { 435 EFUN(USR_DELAY_US(2000000)); 436 ESTM(sts = rdv_usr_diag_status()); 437 EFUN_PRINTF(("sts=%04x\n",sts)); 438 439 } while ((sts & 0x8000) == 0); 440 } else { 441 EFUN_PRINTF(("Waiting for measurement time approx %d seconds",timer_control+(timer_control>>1))); 442 EFUN(blackhawk_tsc_INTERNAL_poll_diag_done(sa__, &sts,timer_control*2000)); 443 } 444 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("delay done\n")); 445 446 EFUN(blackhawk_tsc_read_ber_scan_data(sa__, &errs[0], &time[0], &cnt, 2000)); 447 448 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("read done cnt=%d\n",cnt)); 449 450 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_CAPTURE_BER_END,0x00,200)); 451 452 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("end function done\n")); 453 /* if(cnt == 1) { */ 454 /* EFUN_PRINTF(("Not enough points found to extrapolate BER\n")); */ 455 /* return(ERR_CODE_NONE); */ 456 /* } */ 457 458 EFUN(blackhawk_tsc_display_ber_scan_data(sa__, rate, ber_scan_mode, &errs[0], &time[0],(uint8_t)SRDS_ABS(offset_start))); 459 460 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("display done\n")); 461 462 return(ERR_CODE_NONE); 463 } 464 465 466 467 err_code_t blackhawk_tsc_display_ber_scan_data (srds_access_t *sa__, USR_DOUBLE rate, uint8_t ber_scan_mode, uint32_t *total_errs, uint32_t *total_time, uint8_t max_offset) { 468 469 #ifdef SERDES_API_FLOATING_POINT 470 /* 'margins_mv[]' vector maps the p1 threshold code with actual mV 471 Only relevant when mode=0 472 This is not totally linear: for code 0~25 step=6mV; code 25~30 step=18mV; code 30~31 step=12 473 'margins_mv[]' is valid only for Merlin. This vector would need to be modified accordingly for different Serdes 474 USR_DOUBLE margins_mv[] = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84, 475 90,96,102,108,114,120,126,132,138,144,150,168,186,204,222,240,252}; 476 const USR_DOUBLE narrow_margins_mv[] = {0,3.6,7.2,10.8,14.4,18,21.6,25.5,28.8,32.4,36,39.6,43.2,46.8,50.4, 477 54,57.6,61.2,64.8,68.4,72,75.6,79.2,82.8,86.4,90,100.8,111.6,122.4,133.2,144,151.2}; */ 478 479 const unsigned int HI_CONFIDENCE_ERR_CNT = 100; /* bit errors */ 480 const unsigned int HI_CONFIDENCE_MIN_ERR_CNT = 20; /* bit errors */ 481 const unsigned int MAX_CLIPPED_ERR_CNT = 8355840; 482 const USR_DOUBLE ARTIFICIAL_BER = 0.5; /* used along ARTIFICIAL_MARGIN(_V/_H) when not enough points to extrapolate */ 483 const int ARTIFICIAL_MARGIN_V = 500; /* Used along ARTIFICIAL_BER when not enough points to extrapolate. Unit: mV. Based on the concept of max Vpp of 1 Volt */ 484 const int ARTIFICIAL_MARGIN_H = 1; /* Used along ARTIFICIAL_BER when not enough points to extrapolate. Unit: UI. Based on the concept of two consecutive scrambled bits (1 UI appart) being uncorrelated */ 485 const int MIN_BER_TO_REPORT = -24; /* we clip the projected BER using this number */ 486 const USR_DOUBLE MIN_BER_FOR_FIT = -8.0; /* all points with BER <= 10^MIN_BER_FOR_FIT will be used for line fit (i.e used for extrapolation) */ 487 488 /* BER confidence scale */ 489 const USR_DOUBLE ber_conf_scale[104] = { 490 2.9957,5.5717,3.6123,2.9224,2.5604,2.3337,2.1765,2.0604,1.9704,1.8983, 491 1.8391,1.7893,1.7468,1.7100,1.6778,1.6494,1.6239,1.6011,1.5804,1.5616, 492 1.5444,1.5286,1.5140,1.5005,1.4879,1.4762,1.4652,1.4550,1.4453,1.4362, 493 1.4276,1.4194,1.4117,1.4044,1.3974,1.3908,1.3844,1.3784,1.3726,1.3670, 494 1.3617,1.3566,1.3517,1.3470,1.3425,1.3381,1.3339,1.3298,1.3259,1.3221, 495 1.3184,1.3148,1.3114,1.3080,1.3048,1.3016,1.2986,1.2956,1.2927,1.2899, 496 1.2872,1.2845,1.2820,1.2794,1.2770,1.2746,1.2722,1.2700,1.2677,1.2656, 497 1.2634,1.2614,1.2593,1.2573,1.2554,1.2535,1.2516,1.2498,1.2481,1.2463, 498 1.2446,1.2429,1.2413,1.2397,1.2381,1.2365,1.2350,1.2335,1.2320,1.2306, 499 1.2292,1.2278,1.2264,1.2251,1.2238,1.2225,1.2212,1.2199,1.2187,1.2175, 500 1.2163, /* starts in index: 100 for #errors: 100,200,300,400 */ 501 1.1486, /* 200 */ 502 1.1198, /* 300 */ 503 1.1030}; /*400 */ 504 505 506 /* Define variables */ 507 USR_DOUBLE lbers[DIAG_MAX_SAMPLES] = {0}; /* Internal linear scale sqrt(-log(ber)) */ 508 USR_DOUBLE margins[DIAG_MAX_SAMPLES] = {0}; /* Eye margin @ each measurement */ 509 USR_DOUBLE bers[DIAG_MAX_SAMPLES] = {0}; /* computed bit error rate */ 510 uint32_t i; 511 int8_t offset[DIAG_MAX_SAMPLES]; 512 int8_t mono_flags[DIAG_MAX_SAMPLES]; 513 514 int8_t direction; 515 uint8_t heye; 516 int8_t delta_n=1; 517 USR_DOUBLE Exy = 0.0; 518 USR_DOUBLE Eyy = 0.0; 519 USR_DOUBLE Exx = 0.0; 520 USR_DOUBLE Ey = 0.0; 521 USR_DOUBLE Ex = 0.0; 522 USR_DOUBLE alpha = 0.0; 523 USR_DOUBLE gauss_noise = -1; 524 USR_DOUBLE beta = 0.0; 525 USR_DOUBLE sq_r = 0.0, alpha2 = 0.0; 526 USR_DOUBLE proj_ber = 0.0, proj_ber_aux = 0.0; 527 USR_DOUBLE proj_margin_12 = 0.0; 528 USR_DOUBLE proj_margin_15 = 0.0; 529 USR_DOUBLE proj_margin_18 = 0.0; 530 USR_DOUBLE sq_err1 = 0.0, sq_err2 = 0.0; 531 USR_DOUBLE ierr; 532 uint8_t start_n; 533 uint8_t stop_n; 534 uint8_t low_confidence=1; 535 uint8_t loop_index; 536 uint8_t n_mono = 0; 537 uint8_t eye_cnt; 538 uint8_t hi_confidence_cnt = 0; 539 int8_t first_good_ber_idx = -1; 540 int8_t first_small_errcnt_idx = -1; 541 int8_t first_non_clipped_errcnt_idx = -1; 542 uint8_t range250; 543 uint8_t intrusive; 544 uint8_t ber_clipped = 0; 545 uint8_t last_point_discard; 546 uint8_t fit_count; 547 int artificial_margin; 548 int proj_case = 0; /* this variable will be used to signal what particular extrapolation case has happened at the end (after discarding invalid points of all sorts). To avoid potential issues: NEVER RE-USE VALUES... new cases should receive brand-new integer value */ 549 USR_DOUBLE artificial_lber; 550 char message[256] = "NO MESSAGE"; 551 char unit[5]; 552 553 if(!total_errs || !total_time ) { 554 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 555 } 556 557 /* Initialize BER array */ 558 for (i = 0; i < DIAG_MAX_SAMPLES; i++) { 559 bers[i] = 0; 560 mono_flags[i] = 0; 561 } 562 563 /* Decode mode/direction/etc. */ 564 heye = (ber_scan_mode & DIAG_BER_HORZ)>>1; 565 direction = (ber_scan_mode & DIAG_BER_NEG) ? -1 : 1 ; 566 range250 = (ber_scan_mode & DIAG_BER_P1_NARROW) ? 0 : 1; 567 intrusive = (ber_scan_mode & DIAG_BER_INTR) ? 1 : 0; 568 569 /* Prepare artificial points in case they are needed */ 570 if (heye == 1) { 571 artificial_margin = direction*ARTIFICIAL_MARGIN_H; 572 } else { 573 artificial_margin = direction*ARTIFICIAL_MARGIN_V; 574 } 575 artificial_lber = (USR_DOUBLE)sqrt(-log10(ARTIFICIAL_BER)); 576 577 /* Printing on-screen message */ 578 if (heye == 1) { 579 if (direction==-1) EFUN_PRINTF(("\n\n********** HORIZONTAL PROJECTION: LEFT SIDE ******************\n")); 580 if (direction== 1) EFUN_PRINTF(("\n\n********** HORIZONTAL PROJECTION: RIGHT SIDE *****************\n")); 581 } else { 582 if (direction==-1) EFUN_PRINTF(("\n\n********** VERTICAL PROJECTION: BOTTOM ***********************\n")); 583 if (direction== 1) EFUN_PRINTF(("\n\n********** VERTICAL PROJECTION: TOP **************************\n")); 584 } 585 586 /* ******************************************* 587 * Generate margins[] 588 * Generate ber[] 589 * Find first and last points for linear fit 590 */ 591 i=0; 592 do { 593 if(heye == 1) { 594 ENULL_STRCPY(unit,"mUI"); 595 offset[i] = (int8_t)(max_offset-i*2); 596 #ifndef STANDALONE_EVENT 597 margins[i] = direction*offset[i]*1000.0/128.0; 598 #else 599 margins[i] = info_out->margins[i]; 600 #endif 601 } else { 602 ENULL_STRCPY(unit,"mV"); 603 offset[i] = (int8_t)(max_offset-i); 604 #ifndef STANDALONE_EVENT 605 if(intrusive) { 606 607 margins[i] = direction*blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, offset[i], 0); 608 } else { 609 margins[i] = direction*blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, offset[i], range250); 610 } 611 #else 612 margins[i] = info_out->margins[i]; 613 #endif 614 } 615 if (total_errs[i] == 0) { 616 bers[i] = 1.0/(((USR_DOUBLE)total_time[i])*0.00001*rate); 617 } else { 618 bers[i] = (USR_DOUBLE)total_errs[i]/(((USR_DOUBLE)total_time[i])*0.00001*rate); 619 } 620 621 /* Find the first data point with good BER (BER <= 10^MIN_BER_FOR_FIT) 622 NOTE: no need for lower bound on BER, since correction factors will be applied for all total_errs>=0 */ 623 if ((log10(bers[i]) <= MIN_BER_FOR_FIT) && (first_good_ber_idx == -1)) { 624 first_good_ber_idx = (int8_t)i; 625 } 626 627 /* Determine high-confidence iterations */ 628 if (total_errs[i] >= HI_CONFIDENCE_ERR_CNT) { 629 hi_confidence_cnt++; 630 } else if ((total_errs[i] < HI_CONFIDENCE_MIN_ERR_CNT) && (first_small_errcnt_idx == -1)) { 631 /* find the first data point with small error count */ 632 first_small_errcnt_idx = (int8_t)i; 633 } 634 635 /* Determine first NON-clipped error count 636 NOTE: Originally this limit was created for post processing of micro-generated data; however, this could be used for PC-generated data as well */ 637 if ((total_errs[i] < MAX_CLIPPED_ERR_CNT) && (first_non_clipped_errcnt_idx == -1) ) { 638 first_non_clipped_errcnt_idx = (int8_t)i; 639 } 640 641 i++; 642 643 } while(((total_errs[i] != 0) || (total_time[i] != 0)) && (i<=max_offset)); 644 645 eye_cnt = (int8_t) i; 646 647 648 /* ******************************************* 649 Setting up stop_n variable. 650 Check if: 651 - There is only one point in measurement vector (i.e. eye_cnt = 1) 652 - The very last point's measurement time was "too short" 653 */ 654 655 i = eye_cnt - 1; 656 if (i>=1) { 657 if ((total_time[i] >= 0.5*total_time[i-1]) || (total_errs[i] >= HI_CONFIDENCE_MIN_ERR_CNT) ){ 658 stop_n = eye_cnt; /* last point will be included in linear fit */ 659 last_point_discard = 0; 660 } else { 661 stop_n = eye_cnt - 1; /* discards the very last point */ 662 last_point_discard = 1; 663 } 664 } else { 665 stop_n = 1; /* there is ONLY one measurement */ 666 last_point_discard = 0; 667 } 668 669 670 /* ******************************************* 671 Print on screen (prints RAW BER data. i.e. conf factors) 672 */ 673 i = 0; 674 do { 675 if (total_errs[i] == 0) { 676 EFUN_PRINTF(("BER @ %4.0f %s < 1e%-6.2f (%u errors in %0.2f sec)\n", margins[i], unit, log10(bers[i]), total_errs[i], ((USR_DOUBLE)total_time[i])*0.00001)); 677 } else if (total_errs[i] >= MAX_CLIPPED_ERR_CNT) { 678 EFUN_PRINTF(("BER @ %4.0f %s > 1e%-6.2f (%u errors in %0.2f sec)\n", margins[i], unit, log10(bers[i]), total_errs[i], ((USR_DOUBLE)total_time[i])*0.00001)); 679 } else { 680 EFUN_PRINTF(("BER @ %4.0f %s = 1e%-6.2f (%u errors in %0.2f sec)\n", margins[i], unit, log10(bers[i]), total_errs[i], ((USR_DOUBLE)total_time[i])*0.00001)); 681 } 682 i++; 683 } while (i<stop_n); 684 685 /* ******************************************* 686 Correcting *all* BER values using confidence factors in 'ber_conf_scale' vector 687 This step is done for extrapolation purposes 688 */ 689 for (loop_index=0; loop_index < eye_cnt; loop_index++) { 690 if (total_errs[loop_index] <= 100) { 691 bers[loop_index] = ber_conf_scale[total_errs[loop_index]] * bers[loop_index]; 692 } else if (total_errs[loop_index] > 100 && total_errs[loop_index] < 200) { 693 bers[loop_index] = ber_conf_scale[100] * bers[loop_index]; 694 } else if (total_errs[loop_index] >= 200 && total_errs[loop_index] < 300) { 695 bers[loop_index] = ber_conf_scale[101] * bers[loop_index]; 696 } else if (total_errs[loop_index] >= 300 && total_errs[loop_index] < 400) { 697 bers[loop_index] = ber_conf_scale[102] * bers[loop_index]; 698 } else if (total_errs[loop_index] >= 400) { 699 bers[loop_index] = ber_conf_scale[103] * bers[loop_index]; 700 } 701 } 702 703 /* ******************************************* 704 Computes the "linearised" ber vector 705 */ 706 for (loop_index=0; loop_index<eye_cnt; loop_index++) { 707 lbers[loop_index] = (USR_DOUBLE)sqrt(-log10(bers[loop_index])); 708 } 709 710 /* ******************************************* 711 Assign highest data point to use 712 */ 713 if (first_good_ber_idx == -1) { 714 start_n = stop_n; 715 } else { 716 start_n = first_good_ber_idx; 717 } 718 719 720 721 /* ****************************************************** 722 *********** EXTRAPOLATION (START) ********************** 723 ********************************************************* 724 Different data set profiles can be received by this code. 725 Each case is processed accordingly here (IF-ELSE IF cases) 726 */ 727 728 /* ====> Errors encountered all the way to sampling point */ 729 if (start_n >= eye_cnt) { 730 proj_case = 1; 731 ENULL_STRCPY(message,"No low-BER point measured"); 732 733 /* confidence factor of 0.96 is applied in this case to set a LOWER bound and report accordingly. 734 This factor corresponds to approximately 3000 errors @95% confidence 735 For reference: factors for 900, 2000, 3000, 5000, 20000 and 50000 errors are: 0.96, 0.96, 0.97, 0.99, 0.99, respectively */ 736 proj_ber = 0.96*log10(bers[eye_cnt-1]); 737 proj_ber_aux = proj_ber; 738 EFUN_PRINTF(("BER *worse* than 1e%0.2f\n", proj_ber)); 739 EFUN_PRINTF(("No margin @ 1e-12, 1e-15 & 1e-18\n\n\n")); 740 fit_count = 1; 741 } 742 743 else { 744 745 /* ====> Only ONE measured point. Typically when the eye is wide open. 746 Artificial points will be used to make extrapolation possible */ 747 if (stop_n==1) { 748 proj_case = 2; 749 ENULL_STRCPY(message,"Not enough points (single measured point). Using artificial point"); 750 751 low_confidence = 1; 752 delta_n = 1; /* 'delta_n' and 'fit_count' variables were kept for future use in case a new approach to handle low confidence case is adopted */ 753 fit_count = 2; 754 755 /* Compute covariances and means... but only for two points: artificial and the single measured point */ 756 Exy = ((margins[0]*lbers[0] + artificial_margin*artificial_lber)/2.0); 757 Eyy = ((lbers[0]*lbers[0] + artificial_lber*artificial_lber)/2.0); 758 Exx = ((margins[0]*margins[0] + artificial_margin*artificial_margin)/2.0); 759 Ey = ((lbers[0] + artificial_lber)/2.0); 760 Ex = ((margins[0] + artificial_margin)/2.0); 761 } 762 763 /* ====> "NORMAL" case (when there are more than 1 measurements) */ 764 else { 765 766 /* Detect and record nonmonotonic data points */ 767 for (loop_index=0; loop_index < stop_n; loop_index++) { 768 if ((loop_index > start_n) && (log10(bers[loop_index]) > log10(bers[loop_index-1]))) { 769 mono_flags[loop_index] = 1; 770 if (first_good_ber_idx != -1) { 771 n_mono++; 772 } 773 } 774 } 775 776 /* Finds number of MEASURED points available for extrapolation */ 777 delta_n = (stop_n-start_n-n_mono); 778 779 780 /* HIGH CONFIDENCE case */ 781 782 if (delta_n >= 2) { /* there are at least 2 points to trace a line */ 783 proj_case = 3; 784 ENULL_STRCPY(message,"Normal case"); 785 low_confidence = 0; 786 787 /* Compute covariances and means */ 788 fit_count = 0; 789 for (loop_index=start_n; loop_index < stop_n; loop_index++) { 790 if (mono_flags[loop_index] == 0) { 791 Exy += (margins[loop_index]*lbers[loop_index]/(USR_DOUBLE)delta_n); 792 Eyy += (lbers[loop_index]*lbers[loop_index]/(USR_DOUBLE)delta_n); 793 Exx += (margins[loop_index]*margins[loop_index]/(USR_DOUBLE)delta_n); 794 Ey += (lbers[loop_index]/(USR_DOUBLE)delta_n); 795 Ex += (margins[loop_index]/(USR_DOUBLE)delta_n); 796 fit_count++; 797 } 798 } 799 } 800 801 /* LOW CONFIDENCE case */ 802 803 else { /* NEW APPROACH (08/28/2014): consider very first point (error count < MAX_CLIPPED_ERR_CNT) and very last point for linear fit. This will give pessimistic/conservative extrapolation */ 804 low_confidence = 1; 805 if ( (first_non_clipped_errcnt_idx>=0) && (first_non_clipped_errcnt_idx < start_n)) { 806 proj_case = 4; 807 ENULL_STRCPY(message,"Not enough points. Using first measured point for conservative estimation"); 808 fit_count = 2; 809 /* Compute covariances and means... but only for two points: first and last */ 810 Exy = ((margins[stop_n-1]*lbers[stop_n-1] + margins[first_non_clipped_errcnt_idx]*lbers[first_non_clipped_errcnt_idx])/2.0); 811 Eyy = ((lbers[stop_n-1]*lbers[stop_n-1] + lbers[first_non_clipped_errcnt_idx]*lbers[first_non_clipped_errcnt_idx])/2.0); 812 Exx = ((margins[stop_n-1]*margins[stop_n-1] + margins[first_non_clipped_errcnt_idx]*margins[first_non_clipped_errcnt_idx])/2.0); 813 Ey = ((lbers[stop_n-1] + lbers[first_non_clipped_errcnt_idx])/2.0); 814 Ex = ((margins[stop_n-1] + margins[first_non_clipped_errcnt_idx])/2.0); 815 } else { 816 proj_case = 5; 817 ENULL_STRCPY(message,"Not enough points (cannot use non-clipped ErrorCount point). Using artificial point"); 818 /* Compute covariances and means... but only for two points: artificial and the single measured point */ 819 Exy = (artificial_margin*artificial_lber)/2.0; 820 Eyy = (artificial_lber*artificial_lber)/2.0; 821 Exx = (artificial_margin*artificial_margin)/2.0; 822 Ey = (artificial_lber)/2.0; 823 Ex = (artificial_margin)/2.0; 824 fit_count = 1; 825 /* This FOR loop checks for monotonicity as well */ 826 for (loop_index=start_n; loop_index < stop_n; loop_index++) { 827 if (mono_flags[loop_index] == 0) { 828 Exy += (margins[loop_index]*lbers[loop_index]/2.0); 829 Eyy += (lbers[loop_index]*lbers[loop_index]/2.0); 830 Exx += (margins[loop_index]*margins[loop_index]/2.0); 831 Ey += (lbers[loop_index]/2.0); 832 Ex += (margins[loop_index]/2.0); 833 fit_count++; 834 } 835 } 836 } 837 } 838 } 839 840 /* Compute fit slope and offset: ber = alpha*margin + beta */ 841 alpha = (Exy - Ey*Ex) / (Exx - Ex*Ex); 842 beta = Ey - Ex*alpha; 843 /* Compute alpha2: slope of regression: margin = alpha2*ber + beta2 */ 844 alpha2 = (Exy - Ey*Ex) / (Eyy - Ey*Ey); 845 /* Compute correlation index sq_r */ 846 sq_r = alpha*alpha2; 847 848 proj_ber = pow(10,(-beta*beta)); 849 proj_margin_12 = direction*(sqrt(-log10(1e-12))-beta)/alpha; 850 proj_margin_15 = direction*(sqrt(-log10(1e-15))-beta)/alpha; 851 proj_margin_18 = direction*(sqrt(-log10(1e-18))-beta)/alpha; 852 853 /* Estimate modeled gaussian noise. 854 855 The following is based on the Q-function model and the following table: 856 Q | log10(BER) 857 ======================= 858 7.033 | -12 859 7.941 | -15 860 8.757 | -18 861 862 Based on the above, we solve for sigma: 863 7.033*sigma = u - proj_margin_12 , and 864 7.941*sigma = u - proj_margin_15 865 */ 866 gauss_noise = (proj_margin_12 - proj_margin_15)/0.908; 867 868 sq_err1 = (Eyy + (beta*beta) + (Exx*alpha*alpha) - 869 (2*Ey*beta) - (2*Exy*alpha) + (2*Ex*beta*alpha)); 870 sq_err2 = 0; 871 for (loop_index=start_n; loop_index<stop_n; loop_index++) { 872 ierr = (lbers[loop_index] - (alpha*margins[loop_index] + beta)); 873 sq_err2 += (ierr*ierr/(USR_DOUBLE)delta_n); 874 } 875 876 proj_ber = log10(proj_ber); 877 proj_ber_aux = proj_ber; 878 879 if (proj_ber < MIN_BER_TO_REPORT) { 880 proj_ber = MIN_BER_TO_REPORT; 881 ber_clipped = 1; 882 } 883 884 /* Extrapolated results, low confidence */ 885 if (low_confidence == 1) { 886 887 EFUN_PRINTF(("BER(extrapolated) < 1e%0.2f\n", proj_ber)); 888 EFUN_PRINTF(("Margin @ 1e-12 > %0.2f %s\n", (proj_ber < -12)? SRDS_ABS(proj_margin_12) : 0, unit)); 889 EFUN_PRINTF(("Margin @ 1e-15 > %0.2f %s\n", (proj_ber < -15)? SRDS_ABS(proj_margin_15) : 0, unit)); 890 EFUN_PRINTF(("Margin @ 1e-18 > %0.2f %s\n", (proj_ber < -18)? SRDS_ABS(proj_margin_18) : 0, unit)); 891 892 /* Extrapolated results, HIGH confidence */ 893 } else { 894 895 if (ber_clipped == 1) { 896 EFUN_PRINTF(("BER(extrapolated) < 1e%0.2f\n", proj_ber)); 897 } else { 898 EFUN_PRINTF(("BER(extrapolated) = 1e%0.2f\n", proj_ber)); 899 } 900 EFUN_PRINTF(("Margin @ 1e-12 = %0.2f %s\n", (proj_ber < -12)? SRDS_ABS(proj_margin_12) : 0, unit)); 901 EFUN_PRINTF(("Margin @ 1e-15 = %0.2f %s\n", (proj_ber < -15)? SRDS_ABS(proj_margin_15) : 0, unit)); 902 EFUN_PRINTF(("Margin @ 1e-18 = %0.2f %s\n", (proj_ber < -18)? SRDS_ABS(proj_margin_18) : 0, unit)); 903 } 904 905 EFUN_PRINTF(("\n\n")); 906 907 /* Print non-monotonic outliers */ 908 if (n_mono != 0) { 909 EFUN_PRINTF(("Detected non-monotonicity at { ")); 910 for (loop_index = start_n; loop_index < stop_n; loop_index++) { 911 if (mono_flags[loop_index] == 1) { 912 EFUN_PRINTF(("%0.2f ", margins[loop_index])); 913 } 914 } 915 EFUN_PRINTF(("} %s\n\n\n",unit)); 916 } 917 918 } 919 /* ******************************************* 920 *********** EXTRAPOLATION (END) ************* 921 */ 922 923 924 925 /* SUMMARY (for debugging purposes */ 926 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("\t=====> DEBUG INFO (start)\n\n")); 927 if (DIAG_VERBOSE > 2) { 928 EFUN_PRINTF((" loop Margin total_errors time(sec) logBER lber")); 929 for (loop_index=0; loop_index < stop_n+last_point_discard; loop_index++) { 930 EFUN_PRINTF(("\n%5d %11.0f %14d %10.3f %8.2f %10.3f", loop_index, margins[loop_index], total_errs[loop_index], ((USR_DOUBLE)total_time[loop_index])*0.00001, log10(bers[loop_index]), lbers[loop_index])); 931 } 932 EFUN_PRINTF(("\n\n")); 933 } 934 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("Max Offset = %d\n",max_offset)); 935 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("ber_clipped: %d, Projected BER (proj_ber_aux) = %.2f\n", ber_clipped, proj_ber_aux)); 936 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("first good ber idx at %d, ber = 1e%f\n", first_good_ber_idx, ((first_good_ber_idx>=0) ? log10(bers[first_good_ber_idx]) : 0.0))); 937 { 938 char aux_str[20]; 939 USR_SPRINTF(aux_str, "%d", total_errs[first_small_errcnt_idx]); 940 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("first small errcnt idx at %d, errors = %s\n", first_small_errcnt_idx, ((first_small_errcnt_idx>=0) ? aux_str : "-1"))); 941 } 942 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("last point discarded?: %d, low_confidence: %d, first_non_clipped_errcnt_idx: %d, start_n: %d, stop_n: %d, eye_cnt: %d, n_mono: %d, first_good_ber_idx = %d, first_small_errcnt_idx = %d, fit_count: %d, delta_n: %d\n", 943 last_point_discard, low_confidence, first_non_clipped_errcnt_idx, start_n, stop_n, eye_cnt, n_mono, first_good_ber_idx, first_small_errcnt_idx, fit_count, delta_n)); 944 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("Exy=%.2f, Eyy=%.4f, Exx=%.2f, Ey=%.4f, Ex=%.2f, alpha=%.4f, beta=%.4f, alpha2=%.3f, sq_r=%.3f, sq_err1=%g, sq_err2=%g, gauss_noise=%.3f\n", Exy,Eyy,Exx,Ey,Ex,alpha,beta,alpha2,sq_r,sq_err1,sq_err2,gauss_noise)); 945 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("%s\n", message)); 946 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("proj_case %d\n",proj_case)); 947 if (DIAG_VERBOSE > 2) EFUN_PRINTF(("\n\t=====> DEBUG INFO (end)\n\n")); 948 EFUN_PRINTF(("\n\n\n")); 949 950 951 #else 952 UNUSED(rate); 953 UNUSED(ber_scan_mode); 954 UNUSED(max_offset); 955 956 EFUN_PRINTF(("This function needs SERDES_API_FLOATING_POINT define to operate \n")); 957 958 if(!total_errs || !total_time ) { 959 return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 960 } 961 #endif 962 return(ERR_CODE_NONE); 963 } 964 965 /*****************************/ 966 /* Display Lane/Core State */ 967 /*****************************/ 968 969 err_code_t blackhawk_tsc_display_lane_state_hdr(void) { 970 EFUN_PRINTF(("LN (RX , CDRxN , UC_CFG,UC_STS,TX_RX_RST,STP,PLL) ")); 971 EFUN_PRINTF(("SD LCK RXPPM ")); 972 EFUN_PRINTF(("CLK90 ")); 973 EFUN_PRINTF((" PF(MLHR) ")); 974 EFUN_PRINTF(("VGA ")); 975 EFUN_PRINTF(("DCO P1mV ")); 976 EFUN_PRINTF((" TP(0,1,2,3,4) ")); 977 EFUN_PRINTF((" DFE(1,2,3,4,5,6) ")); 978 EFUN_PRINTF((" TXPPM TXEQ(n2,n1,m,p1,p2,p3) EYE(L,R,U,D) ")); 979 EFUN_PRINTF(("LINK_TIME BER")); 980 EFUN_PRINTF(("\n")); 981 return (ERR_CODE_NONE); 982 } 983 984 err_code_t blackhawk_tsc_display_lane_state_legend(void) { 985 EFUN_PRINTF(("\n")); 986 EFUN_PRINTF(("**********************************************************************************************\n")); 987 EFUN_PRINTF(("**** Legend of Entries in display_lane_state() ****\n")); 988 EFUN_PRINTF(("**********************************************************************************************\n")); 989 EFUN_PRINTF(("LN : Lane index within IP core\n")); 990 EFUN_PRINTF(("RX : RX PAM mode (NRZ - NRZ; P4N - PAM4_NS; P4E - PAM4_ES)\n")); 991 EFUN_PRINTF(("CDRxN : CDR type x OSR ratio [xG-OSx16; xH-OSx16p5; xJ-OSx21.2; xK-OSx20p6; xW-OSx32] \n")); 992 EFUN_PRINTF(("UC_CFG : Micro lane configuration variable\n")); 993 EFUN_PRINTF(("UC_STS : Micro lane status variable\n")); 994 #if defined(SERDES_TX_RS_SEPARATE) 995 EFUN_PRINTF(("TX_RX_RST : TX and RX Reset State{reset_active, reset_occured, reset_held}\n")); 996 #else 997 EFUN_PRINTF(("RST : Reset State{reset_active, reset_occured, reset_held}\n")); 998 #endif 999 EFUN_PRINTF(("STP : uC Stopped State\n")); 1000 EFUN_PRINTF(("PLL : TX and RX PLL select\n")); 1001 EFUN_PRINTF(("SD : Signal Detect\n")); 1002 EFUN_PRINTF(("LCK : pmd_rx_lock\n")); 1003 EFUN_PRINTF(("RXPPM : Frequency offset of local reference clock with respect to RX data in ppm\n")); 1004 EFUN_PRINTF(("CLK90 : Delay of zero crossing slicer, m1, wrt to data in PI codes\n")); 1005 EFUN_PRINTF(("CLKP1 : Delay of diagnostic/lms slicer, p1, wrt to data in PI codes\n")); 1006 EFUN_PRINTF(("PF(MLHR) : Peaking Filter Main (0..15), Low Freq (0..7), High Freq (0..7), Peaking/BW Reduction settings\n")); 1007 #if defined(RX_VGA_CTRL_VAL_MIN) 1008 EFUN_PRINTF(("VGA : Variable Gain Amplifier settings (%d..%d)\n", RX_VGA_CTRL_VAL_MIN, RX_VGA_CTRL_VAL_MAX)); 1009 #else 1010 EFUN_PRINTF(("VGA : Variable Gain Amplifier settings (0..%d)\n", RX_VGA_CTRL_VAL_MAX)); 1011 #endif 1012 EFUN_PRINTF(("DCO : DC offset DAC control value\n")); 1013 EFUN_PRINTF(("P1mV : Vertical threshold voltage of p1 slicer\n")); 1014 EFUN_PRINTF(("TP(0,1,2,3,4):\n")); 1015 EFUN_PRINTF((" 0 - Echos user provided 'RX_Channel_Loss_hint' in PAM4 mode, 'M1 vertical threshold voltage (mV)' in NRZ mode\n")); 1016 EFUN_PRINTF((" 1 - Initial Channel Loss Estimate from 0-15 -- min to max within the AFE BW's operating range, negative value is an indicator of over-equalization\n")); 1017 EFUN_PRINTF((" 2 - AFE BW, For NR mode (0 to 5 - for shortest to longest), For ER mode (0, 1 - shorter/longer)\n")); 1018 EFUN_PRINTF((" 3 - usr_status_eq_debug1\n")); 1019 EFUN_PRINTF((" 4 - usr_status_tp_metric_1\n")); 1020 EFUN_PRINTF(("DFE taps : ISI correction taps in units of 2mV\n")); 1021 EFUN_PRINTF(("TXPPM : Frequency offset of local reference clock with respect to TX data in ppm\n")); 1022 EFUN_PRINTF(("TXEQ(n2,n1,m,p1,p2,p3) : TX equalization FIR tap weights in units of 1Vpp/168 for PAM4 or 1Vpp/127 for NRZ\n")); 1023 EFUN_PRINTF((" : A 'P' preceding the tap weights denotes TX Precoder is enabled\n")); 1024 EFUN_PRINTF((" : A 'T' preceding the tap weights denotes TX Training is enabled\n")); 1025 EFUN_PRINTF(("EYE(L,R,U,D) : Eye margin @ 1e-5 as seen by internal diagnostic slicer in mUI and mV\n")); 1026 EFUN_PRINTF(("LINK_TIME : Link time in milliseconds\n")); 1027 EFUN_PRINTF(("BER : Bit Error Rate calculated based on 100ms test time; displayed only if prbs_chk_en=1.\n")); 1028 EFUN_PRINTF(("**********************************************************************************************\n")); 1029 return (ERR_CODE_NONE); 1030 } 1031 1032 err_code_t blackhawk_tsc_display_lane_state(srds_access_t *sa__) { 1033 err_code_t err_code = blackhawk_tsc_INTERNAL_display_lane_state_no_newline(sa__); 1034 EFUN_PRINTF(("\n")); 1035 return (err_code); 1036 } 1037 1038 err_code_t blackhawk_tsc_display_core_state_hdr(void) { 1039 char core_type[20] = "blackhawk_tsc"; 1040 COMPILER_REFERENCE(core_type); 1041 EFUN_PRINTF(("SerDes type = %s\n",core_type)); 1042 1043 EFUN_PRINTF(("CORE RST_ST PLL_PWDN UC_ATV COM_CLK UCODE_VER API_VER AFE_VER LIVE_TEMP AVG_TMON RESCAL VCO_RATE ANA_VCO_RANGE PLL0_DIV PLL1_DIV PLL_LOCK")); 1044 EFUN_PRINTF((" PLL_COMP_THRESH\n")); 1045 return (ERR_CODE_NONE); 1046 } 1047 1048 err_code_t blackhawk_tsc_display_core_state_line(srds_access_t *sa__) { 1049 err_code_t err_code = blackhawk_tsc_INTERNAL_display_core_state_no_newline(sa__); 1050 EFUN_PRINTF(("\n")); 1051 return (err_code); 1052 } 1053 1054 err_code_t blackhawk_tsc_display_core_state_legend(void) { 1055 EFUN_PRINTF(("\n")); 1056 EFUN_PRINTF(("**************************************************************************************************************\n")); 1057 EFUN_PRINTF(("**** Legend of Entries in display_core_state() ****\n")); 1058 EFUN_PRINTF(("**************************************************************************************************************\n")); 1059 EFUN_PRINTF(("* RST_ST : Core Reset State PLL0{active,occured,held}, Reset State PLL1, Core uC Status byte(hex) *\n")); 1060 EFUN_PRINTF(("* PLL_PWDN : PLL Powerdown Control Bit (active high) *\n")); 1061 EFUN_PRINTF(("* UC_ATV : UC Active bit *\n")); 1062 EFUN_PRINTF(("* COM_CLK : COM Clock frequency in MHz *\n")); 1063 EFUN_PRINTF(("* UCODE_VER : Microcode Version [majorversion_minorversion] *\n")); 1064 EFUN_PRINTF(("* API_VER : API Version *\n")); 1065 EFUN_PRINTF(("* AFE_VER : AFE Hardware Vesrion *\n")); 1066 EFUN_PRINTF(("* LIVE_TEMP : Live Die temperature in Celsius *\n")); 1067 EFUN_PRINTF(("* AVG_TMON : uC Temp_idx, Average temperature in Celsius *\n")); 1068 EFUN_PRINTF(("* RESCAL : Analog Resistor Calibration value *\n")); 1069 EFUN_PRINTF(("* VCO_RATE : uC VCO Rate in GHz (approximate) *\n")); 1070 EFUN_PRINTF(("* ANA_VCO_RANGE : Analog VCO Range *\n")); 1071 EFUN_PRINTF(("* REFCLK_2x : Refclk doubler enabler *\n")); 1072 EFUN_PRINTF(("* PLL_DIV : (Register Value) Actual PLL Divider Value *\n")); 1073 EFUN_PRINTF(("* PLL_Lock : PLL Lock *\n")); 1074 1075 EFUN_PRINTF(("**************************************************************************************************************\n")); 1076 return (ERR_CODE_NONE); 1077 } 1078 1079 /**********************************************/ 1080 /* Display Lane/Core Config and Debug Status */ 1081 /**********************************************/ 1082 err_code_t blackhawk_tsc_display_core_config(srds_access_t *sa__) { 1083 EFUN_PRINTF(("\n\n***********************************\n" )); 1084 EFUN_PRINTF(( "**** SERDES CORE CONFIGURATION ****\n" )); 1085 EFUN_PRINTF(( "***********************************\n\n")); 1086 { 1087 struct blackhawk_tsc_uc_core_config_st core_cfg; 1088 struct blackhawk_tsc_uc_core_config_st pll1_cfg; 1089 1090 ENULL_MEMSET(&pll1_cfg, 0, sizeof(pll1_cfg)); 1091 ENULL_MEMSET(&core_cfg, 0, sizeof(core_cfg)); 1092 { 1093 uint8_t pll_orig; 1094 ESTM(pll_orig = blackhawk_tsc_get_pll_idx(sa__)); 1095 EFUN(blackhawk_tsc_set_pll_idx(sa__, 0)); 1096 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_cfg)); 1097 EFUN(blackhawk_tsc_set_pll_idx(sa__, 1)); 1098 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &pll1_cfg)); 1099 EFUN(blackhawk_tsc_set_pll_idx(sa__, pll_orig)); 1100 } 1101 { 1102 uint16_t vco_mhz = (uint16_t)core_cfg.vco_rate_in_Mhz; 1103 uint16_t vco1_mhz = (uint16_t)pll1_cfg.vco_rate_in_Mhz; 1104 COMPILER_REFERENCE(vco_mhz); 1105 COMPILER_REFERENCE(vco1_mhz); 1106 EFUN_PRINTF(( "uC Config VCO Rate = %d (~%d.%03dGHz), %d (~%d.%03dGHz)\n", core_cfg.field.vco_rate 1107 , (vco_mhz / 1000) 1108 , (vco_mhz % 1000) 1109 , pll1_cfg.field.vco_rate 1110 , (vco1_mhz / 1000) 1111 , (vco1_mhz % 1000) )); 1112 EFUN_PRINTF(( "Core Config from PCS = %d, %d\n\n" , core_cfg.field.core_cfg_from_pcs 1113 , pll1_cfg.field.core_cfg_from_pcs)); 1114 } 1115 } 1116 ESTM_PRINTF(( "Tx Lane Addr 0 = %d\n" , rdc_tx_lane_addr_0())); 1117 ESTM_PRINTF(( "Rx Lane Addr 0 = %d\n" , rdc_rx_lane_addr_0())); 1118 ESTM_PRINTF(( "Tx Lane Addr 1 = %d\n" , rdc_tx_lane_addr_1())); 1119 ESTM_PRINTF(( "Rx Lane Addr 1 = %d\n" , rdc_rx_lane_addr_1())); 1120 ESTM_PRINTF(( "Tx Lane Addr 2 = %d\n" , rdc_tx_lane_addr_2())); 1121 ESTM_PRINTF(( "Rx Lane Addr 2 = %d\n" , rdc_rx_lane_addr_2())); 1122 ESTM_PRINTF(( "Tx Lane Addr 3 = %d\n" , rdc_tx_lane_addr_3())); 1123 ESTM_PRINTF(( "Rx Lane Addr 3 = %d\n" , rdc_rx_lane_addr_3())); 1124 #ifdef rdc_tx_lane_addr_4 1125 ESTM_PRINTF(( "Tx Lane Addr 4 = %d\n" , rdc_tx_lane_addr_4())); 1126 ESTM_PRINTF(( "Rx Lane Addr 4 = %d\n" , rdc_rx_lane_addr_4())); 1127 #endif 1128 #ifdef rdc_tx_lane_addr_5 1129 ESTM_PRINTF(( "Tx Lane Addr 5 = %d\n" , rdc_tx_lane_addr_5())); 1130 ESTM_PRINTF(( "Rx Lane Addr 5 = %d\n" , rdc_rx_lane_addr_5())); 1131 #endif 1132 #ifdef rdc_tx_lane_addr_6 1133 ESTM_PRINTF(( "Tx Lane Addr 6 = %d\n" , rdc_tx_lane_addr_6())); 1134 ESTM_PRINTF(( "Rx Lane Addr 6 = %d\n" , rdc_rx_lane_addr_6())); 1135 #endif 1136 #ifdef rdc_tx_lane_addr_7 1137 ESTM_PRINTF(( "Tx Lane Addr 7 = %d\n" , rdc_tx_lane_addr_7())); 1138 ESTM_PRINTF(( "Rx Lane Addr 7 = %d\n" , rdc_rx_lane_addr_7())); 1139 #endif 1140 return(ERR_CODE_NONE); 1141 } 1142 1143 1144 err_code_t blackhawk_tsc_display_lane_config(srds_access_t *sa__) { 1145 struct blackhawk_tsc_uc_lane_config_st lane_cfg; 1146 1147 ENULL_MEMSET(&lane_cfg, 0, sizeof(lane_cfg)); 1148 1149 EFUN_PRINTF(("\n\n*************************************\n" )); 1150 ESTM_PRINTF(( "**** SERDES LANE %d CONFIGURATION ****\n" , blackhawk_tsc_get_lane(sa__) )); 1151 EFUN_PRINTF(( "*************************************\n\n" )); 1152 EFUN( blackhawk_tsc_get_uc_lane_cfg(sa__, &lane_cfg)); 1153 EFUN_PRINTF(( "Lane Config from PCS = %d\n\n" , lane_cfg.field.lane_cfg_from_pcs )); 1154 EFUN_PRINTF(( "Auto-Neg Enabled = %d\n" , lane_cfg.field.an_enabled )); 1155 EFUN_PRINTF(( "DFE on = %d\n" , lane_cfg.field.dfe_on )); 1156 1157 EFUN_PRINTF(( "DFE low power mode = %d\n" , lane_cfg.field.dfe_lp_mode )); 1158 EFUN_PRINTF(( "Brdfe_on = %d\n" , lane_cfg.field.force_brdfe_on )); 1159 EFUN_PRINTF(( "Media Type = %d\n" , lane_cfg.field.media_type )); 1160 EFUN_PRINTF(( "Unreliable LOS = %d\n" , lane_cfg.field.unreliable_los )); 1161 EFUN_PRINTF(( "Scrambling Disable = %d\n" , lane_cfg.field.scrambling_dis )); 1162 ESTM_PRINTF(( "Link Training Enable = %d\n" , rd_linktrn_ieee_training_enable() )); 1163 EFUN_PRINTF(( "CL72 Auto Polarity Enable = %d\n" , lane_cfg.field.cl72_auto_polarity_en )); 1164 EFUN_PRINTF(( "CL72 Restart timeout Enable = %d\n" , lane_cfg.field.cl72_restart_timeout_en)); 1165 1166 EFUN_PRINTF(( "Force ES Mode = %d\n" , lane_cfg.field.force_es )); 1167 EFUN_PRINTF(( "Force NS Mode = %d\n" , lane_cfg.field.force_ns )); 1168 EFUN_PRINTF(( "Link Partner has Precoder En= %d\n" , lane_cfg.field.lp_has_prec_en )); 1169 EFUN_PRINTF(( "Force PAM4 mode = %d\n" , lane_cfg.field.force_pam4_mode )); 1170 EFUN_PRINTF(( "Force NRZ mode = %d\n" , lane_cfg.field.force_nrz_mode )); 1171 1172 ESTM_PRINTF(( "RX PLL Select = %d\n" , rd_rx_pll_select() )); 1173 ESTM_PRINTF(( "TX PLL Select = %d\n" , rd_tx_pll_select() )); 1174 ESTM_PRINTF(( "TX OSR Mode Force = %d\n" , rd_tx_osr_mode_frc() )); 1175 ESTM_PRINTF(( "TX OSR Mode Force Val = %d\n" , rd_tx_osr_mode_frc_val() )); 1176 ESTM_PRINTF(( "RX OSR Mode Force = %d\n" , rd_rx_osr_mode_frc() )); 1177 ESTM_PRINTF(( "RX OSR Mode Force Val = %d\n" , rd_rx_osr_mode_frc_val() )); 1178 ESTM_PRINTF(( "TX Polarity Invert = %d\n" , rd_tx_pmd_dp_invert() )); 1179 ESTM_PRINTF(( "RX Polarity Invert = %d\n\n" , rd_rx_pmd_dp_invert() )); 1180 ESTM_PRINTF(( "TXFIR Range = %s\n" , rd_txfir_nrz_tap_range_sel() ? "NRZ" : "PAM4")); 1181 ESTM_PRINTF(( "TXFIR Tap0 = %d\n" , rd_txfir_tap0_coeff() )); 1182 ESTM_PRINTF(( "TXFIR Tap1 = %d\n" , rd_txfir_tap1_coeff() )); 1183 ESTM_PRINTF(( "TXFIR Tap2 = %d\n" , rd_txfir_tap2_coeff() )); 1184 ESTM_PRINTF(( "TXFIR Tap3 = %d\n" , rd_txfir_tap3_coeff() )); 1185 ESTM_PRINTF(( "TXFIR Tap4 = %d\n" , rd_txfir_tap4_coeff() )); 1186 ESTM_PRINTF(( "TXFIR Tap5 = %d\n" , rd_txfir_tap5_coeff() )); 1187 ESTM_PRINTF(( "TXFIR Tap6 = %d\n" , rd_txfir_tap6_coeff() )); 1188 ESTM_PRINTF(( "TXFIR Tap7 = %d\n" , rd_txfir_tap7_coeff() )); 1189 ESTM_PRINTF(( "TXFIR Tap8 = %d\n" , rd_txfir_tap8_coeff() )); 1190 ESTM_PRINTF(( "TXFIR Tap9 = %d\n" , rd_txfir_tap9_coeff() )); 1191 ESTM_PRINTF(( "TXFIR Tap10 = %d\n" , rd_txfir_tap10_coeff() )); 1192 ESTM_PRINTF(( "TXFIR Tap11 = %d\n" , rd_txfir_tap11_coeff() )); 1193 return(ERR_CODE_NONE); 1194 } 1195 1196 1197 err_code_t blackhawk_tsc_display_core_state(srds_access_t *sa__) { 1198 EFUN(blackhawk_tsc_display_core_state_hdr()); 1199 EFUN(blackhawk_tsc_display_core_state_line(sa__)); 1200 EFUN(blackhawk_tsc_display_core_state_legend()); 1201 return ERR_CODE_NONE; 1202 } 1203 1204 1205 err_code_t blackhawk_tsc_display_lane_debug_status(srds_access_t *sa__) { 1206 /* startup */ 1207 struct blackhawk_tsc_usr_ctrl_disable_functions_st ds; 1208 struct blackhawk_tsc_usr_ctrl_disable_dfe_functions_st dsd; 1209 /* steady state */ 1210 struct blackhawk_tsc_usr_ctrl_disable_functions_st dss; 1211 struct blackhawk_tsc_usr_ctrl_disable_dfe_functions_st dssd; 1212 1213 ENULL_MEMSET(&ds , 0, sizeof(ds )); 1214 ENULL_MEMSET(&dsd , 0, sizeof(dsd )); 1215 ENULL_MEMSET(&dss , 0, sizeof(dss )); 1216 ENULL_MEMSET(&dssd, 0, sizeof(dssd)); 1217 1218 EFUN_PRINTF(("\n\n************************************\n" )); 1219 ESTM_PRINTF(( "**** SERDES LANE %d DEBUG STATUS ****\n" , blackhawk_tsc_get_lane(sa__) )); 1220 EFUN_PRINTF(( "************************************\n\n" )); 1221 ESTM_PRINTF(( "Restart Count = %d\n" , rdv_usr_sts_restart_counter() )); 1222 ESTM_PRINTF(( "Reset Count = %d\n" , rdv_usr_sts_reset_counter() )); 1223 ESTM_PRINTF(( "PMD Lock Count = %d\n\n", rdv_usr_sts_pmd_lock_counter() )); 1224 EFUN(blackhawk_tsc_get_usr_ctrl_disable_startup(sa__, &ds)); 1225 1226 EFUN_PRINTF(( "Disable Startup PF Adaptation = %d\n" , ds.field.pf_adaptation )); 1227 EFUN_PRINTF(( "Disable Startup PF2 Adaptation = %d\n" , ds.field.pf2_adaptation )); 1228 EFUN_PRINTF(( "Disable Startup PF3 Adaptation = %d\n" , ds.field.pf3_adaptation )); 1229 EFUN_PRINTF(( "Disable Startup DC Adaptation = %d\n" , ds.field.dc_adaptation )); 1230 EFUN_PRINTF(( "Disable Startup VGA Adaptation = %d\n" , ds.field.vga_adaptation )); 1231 EFUN_PRINTF(( "Disable Startup Slicer vOffset Tuning = %d\n" , ds.field.slicer_voffset_tuning )); 1232 EFUN_PRINTF(( "Disable Startup Slicer hOffset Tuning = %d\n" , ds.field.slicer_hoffset_tuning )); 1233 EFUN_PRINTF(( "Disable Startup Phase offset Adaptation = %d\n" , ds.field.phase_offset_adaptation )); 1234 EFUN_PRINTF(( "Disable Startup Eye Adaptation = %d\n" , ds.field.eye_adaptation )); 1235 EFUN_PRINTF(( "Disable Startup All Adaptation = %d\n\n", ds.field.all_adaptation )); 1236 EFUN( blackhawk_tsc_get_usr_ctrl_disable_startup_dfe(sa__, &dsd)); 1237 1238 EFUN_PRINTF(( "Disable Startup DFE Tap1 Adaptation = %d\n" , dsd.field.dfe_tap1_adaptation )); 1239 EFUN_PRINTF(( "Disable Startup DFE FX Taps Adaptation = %d\n" , dsd.field.dfe_fx_taps_adaptation )); 1240 EFUN_PRINTF(( "Disable Startup DFE FL Taps Adaptation = %d\n" , dsd.field.dfe_fl_taps_adaptation )); 1241 EFUN_PRINTF(( "Disable Startup DFE Tap DCD = %d\n" , dsd.field.dfe_dcd_adaptation )); 1242 EFUN( blackhawk_tsc_get_usr_ctrl_disable_steady_state(sa__, &dss)); 1243 1244 EFUN_PRINTF(( "Disable Steady State PF Adaptation = %d\n" , dss.field.pf_adaptation )); 1245 EFUN_PRINTF(( "Disable Steady State PF2 Adaptation = %d\n" , dss.field.pf2_adaptation )); 1246 EFUN_PRINTF(( "Disable Steady State PF3 Adaptation = %d\n" , dss.field.pf3_adaptation )); 1247 EFUN_PRINTF(( "Disable Steady State DC Adaptation = %d\n" , dss.field.dc_adaptation )); 1248 EFUN_PRINTF(( "Disable Steady State VGA Adaptation = %d\n" , dss.field.vga_adaptation )); 1249 EFUN_PRINTF(( "Disable Steady State Slicer vOffset Tuning = %d\n" , dss.field.slicer_voffset_tuning )); 1250 EFUN_PRINTF(( "Disable Steady State Slicer hOffset Tuning = %d\n" , dss.field.slicer_hoffset_tuning )); 1251 EFUN_PRINTF(( "Disable Steady State Phase offset Adaptation = %d\n" , dss.field.phase_offset_adaptation )); 1252 EFUN_PRINTF(( "Disable Steady State Eye Adaptation = %d\n" , dss.field.eye_adaptation )); 1253 EFUN_PRINTF(( "Disable Steady State All Adaptation = %d\n\n", dss.field.all_adaptation )); 1254 EFUN( blackhawk_tsc_get_usr_ctrl_disable_steady_state_dfe(sa__, &dssd)); 1255 1256 EFUN_PRINTF(( "Disable Steady State DFE Tap1 Adaptation = %d\n" , dssd.field.dfe_tap1_adaptation )); 1257 EFUN_PRINTF(( "Disable Steady State DFE FX Taps Adaptation = %d\n" , dssd.field.dfe_fx_taps_adaptation )); 1258 EFUN_PRINTF(( "Disable Steady State DFE FL Taps Adaptation = %d\n" , dssd.field.dfe_fl_taps_adaptation )); 1259 EFUN_PRINTF(( "Disable Steady State DFE Tap DCD = %d\n" , dssd.field.dfe_dcd_adaptation )); 1260 ESTM_PRINTF(( "Clk90 offset Adjust = %d\n" , rdv_usr_ctrl_clk90_offset_adjust() )); 1261 ESTM_PRINTF(( "Clk90 offset Override = %d\n" , rdv_usr_ctrl_clk90_offset_override())); 1262 ESTM_PRINTF(( "Lane Event Log Level = %d\n" , rdv_usr_ctrl_lane_event_log_level() )); 1263 1264 return(ERR_CODE_NONE); 1265 } 1266 1267 static err_code_t _display_ber_scan_data(srds_access_t *sa__, uint8_t ber_scan_mode, uint8_t timer_control, uint8_t max_error_control) { 1268 uint8_t i,prbs_byte,prbs_multi,time_byte,time_multi; 1269 uint16_t sts,dataword; 1270 int16_t offset_start; 1271 uint8_t cnt; 1272 uint32_t errors,timer_values; 1273 int rate,direction; 1274 uint8_t range250; 1275 blackhawk_tsc_osr_mode_st osr_mode; 1276 struct blackhawk_tsc_uc_core_config_st core_config; 1277 1278 ENULL_MEMSET(&core_config,0,sizeof(core_config)); 1279 ENULL_MEMSET(&osr_mode,0,sizeof(osr_mode)); 1280 1281 EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_config)); 1282 EFUN(blackhawk_tsc_INTERNAL_get_osr_mode(sa__, &osr_mode)); 1283 1284 #ifdef wr_ams_rx_rxclk_div2p5 1285 if((osr_mode.rx > BLACKHAWK_TSC_OSX4) && (osr_mode.rx != BLACKHAWK_TSC_OSX2P5)) { 1286 #else 1287 if(osr_mode.rx > BLACKHAWK_TSC_OSX4) { 1288 #endif 1289 EFUN_PRINTF(("ERROR DIAG display_ber_data: osr mode too high\n")); 1290 return(ERR_CODE_BAD_PTR_OR_INVALID_INPUT); 1291 } 1292 if (osr_mode.rx > BLACKHAWK_TSC_OSX4) { /* BER supported for only BLACKHAWK_TSC_OSX2P5 mode when osr_mode > osx4 */ 1293 rate = (int)(core_config.vco_rate_in_Mhz/2.5); 1294 } 1295 else { 1296 rate = core_config.vco_rate_in_Mhz/(1<<osr_mode.rx); 1297 } 1298 direction = (ber_scan_mode & DIAG_BER_NEG) ? -1 : 1 ; 1299 range250 = (ber_scan_mode & DIAG_BER_P1_NARROW) ? 0 : 1; 1300 1301 EFUN_PRINTF(("\n**** SERDES BER DATA ****\n")); 1302 EFUN_PRINTF(("BER MODE = %x %d %d\n",ber_scan_mode,timer_control,max_error_control)); 1303 EFUN_PRINTF(("DATA RATE = %d Mhz\n",rate)); 1304 /* start UC acquisition */ 1305 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("start begin\n")); 1306 EFUN(blackhawk_tsc_start_ber_scan_test(sa__, ber_scan_mode, timer_control, max_error_control)); 1307 ESTM(offset_start = rd_uc_dsc_data()); 1308 if(ber_scan_mode & DIAG_BER_HORZ) { 1309 EFUN_PRINTF(("STARTING OFFSET = %d : %d mUI\n",offset_start,(offset_start*1000)>>6)); 1310 } else { 1311 EFUN_PRINTF(("STARTING OFFSET = %d : %d mV\n",offset_start,blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)offset_start, range250))); 1312 } 1313 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("start done\n")); 1314 1315 1316 /* This wait is VERY LONG and should be replaced with interupt or something */ 1317 if(DIAG_VERBOSE > 5) { 1318 do { 1319 EFUN(USR_DELAY_US(2000000)); 1320 ESTM(sts = rdv_usr_diag_status()); 1321 EFUN_PRINTF(("sts=%04x\n",sts)); 1322 1323 } while ((sts & 0x8000) == 0); 1324 } else { 1325 EFUN_PRINTF(("Waiting for measurement time approx %d seconds",timer_control+(timer_control>>1))); 1326 EFUN(blackhawk_tsc_INTERNAL_poll_diag_done(sa__, &sts,timer_control*2000)); 1327 } 1328 if(DIAG_VERBOSE > 2) EFUN_PRINTF(("delay done\n")); 1329 1330 /* Check for completion read ln.diag_status byte?*/ 1331 ESTM(sts = rdv_usr_diag_status()); 1332 if((sts & 0x8000) == 0) { 1333 return(blackhawk_tsc_error(sa__, ERR_CODE_DATA_NOTAVAIL)); 1334 } 1335 cnt = (sts & 0x00FF)/3; 1336 for(i=0;i < cnt;i++) { 1337 /* Read 2 bytes of data */ 1338 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_READ_DIAG_DATA_WORD, 0, 200)); 1339 ESTM(dataword = rd_uc_dsc_data()); /* LSB contains 2 -4bit nibbles */ 1340 time_byte = (uint8_t)(dataword>>8); /* MSB is time byte */ 1341 prbs_multi = (uint8_t)dataword & 0x0F; /* split nibbles */ 1342 time_multi = (uint8_t)dataword>>4; 1343 /* Read 1 bytes of data */ 1344 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_READ_DIAG_DATA_BYTE, 0, 200)); 1345 ESTM(prbs_byte = (uint8_t)rd_uc_dsc_data()); 1346 errors = blackhawk_tsc_INTERNAL_float12_to_uint32(prbs_byte,prbs_multi); /* convert 12bits to uint32 */ 1347 timer_values = (blackhawk_tsc_INTERNAL_float12_to_uint32(time_byte,time_multi)<<3); 1348 if(DIAG_VERBOSE < 5) { 1349 if (!(i % 4)) { 1350 EFUN_PRINTF(("\n")); 1351 } 1352 if(ber_scan_mode & DIAG_BER_HORZ) { 1353 EFUN_PRINTF(("%d %d %d ",direction*(((SRDS_ABS(offset_start)-i)*1000)>>6),errors,timer_values)); 1354 } else { 1355 EFUN_PRINTF(("%d %d %d ",direction*blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)SRDS_ABS(offset_start)-i, range250),errors,timer_values)); 1356 } 1357 1358 } else { 1359 EFUN_PRINTF(("BER Errors=%d (%02x<<%d): Time=%d (%02x<<%d)\n",errors,prbs_byte,prbs_multi,timer_values,time_byte,time_multi<<3)); 1360 } 1361 /*if(timer_values == 0 && errors == 0) break;*/ 1362 } 1363 EFUN_PRINTF(("\n")); 1364 EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_CAPTURE_BER_END,0x00,2000)); 1365 1366 return(ERR_CODE_NONE); 1367 } 1368 1369 /*******************************************/ 1370 /* Diagnostic Functions Required for SDK */ 1371 /*******************************************/ 1372 1373 /* Required Diagnostic Functions */ 1374 err_code_t blackhawk_tsc_display_diag_data(srds_access_t *sa__, uint16_t diag_level) { 1375 uint8_t rx_lock, micro_stop, core, lane; 1376 uint32_t api_version; 1377 EFUN_PRINTF(("\n**** SERDES DISPLAY DIAG DATA ****\n")); 1378 ESTM_PRINTF(("Rev ID Letter = %02X\n", rdc_revid_rev_letter())); 1379 ESTM_PRINTF(("Rev ID Process = %02X\n", rdc_revid_process())); 1380 ESTM_PRINTF(("Rev ID Model = %02X\n", rdc_revid_model())); 1381 ESTM_PRINTF(("Rev ID Model = %02X\n", rdc_revid2())); 1382 ESTM_PRINTF(("Rev ID # Lanes = %d\n" ,rdc_revid_multiplicity())); 1383 ESTM_PRINTF(("Core = %d; LANE = %d\n",blackhawk_tsc_get_core(sa__),blackhawk_tsc_get_lane(sa__))); 1384 EFUN(blackhawk_tsc_version(sa__, &api_version)); 1385 EFUN_PRINTF(("SERDES API Version = %06X\n",api_version)); 1386 ESTM_PRINTF(("Common Ucode Version = %04X", rdcv_common_ucode_version())); 1387 ESTM_PRINTF(("_%02X\n", rdcv_common_ucode_minor_version())); 1388 ESTM_PRINTF(("AFE Hardware Version = 0x%X\n\n", rdcv_afe_hardware_version())); 1389 1390 /* stop micro so all accesses are consistent */ 1391 ESTM(rx_lock = rd_pmd_rx_lock()); 1392 { 1393 err_code_t err_code=ERR_CODE_NONE; 1394 micro_stop = blackhawk_tsc_INTERNAL_stop_micro(sa__,rx_lock,&err_code); 1395 if(err_code) USR_PRINTF(("Unable to stop microcontroller, following data is suspect\n")); 1396 } 1397 1398 EFUN(blackhawk_tsc_display_lane_state_hdr()); 1399 EFUN(blackhawk_tsc_display_lane_state(sa__)); 1400 1401 if(diag_level & SRDS_DIAG_LANE) { 1402 struct blackhawk_tsc_detailed_lane_status_st lane_st; 1403 1404 ENULL_MEMSET(&lane_st, 0, sizeof(lane_st)); 1405 EFUN(blackhawk_tsc_log_full_pmd_state(sa__, &lane_st)); 1406 1407 EFUN(blackhawk_tsc_disp_full_pmd_state(sa__, &lane_st, 1)); 1408 } 1409 1410 if(diag_level & SRDS_DIAG_CORE) { 1411 EFUN(blackhawk_tsc_display_core_state_hdr()); 1412 EFUN(blackhawk_tsc_display_core_state_line(sa__)); 1413 } 1414 if(diag_level & SRDS_DIAG_TIMESTAMP) { 1415 EFUN(blackhawk_tsc_test_uc_timestamp(sa__)); 1416 } 1417 if(diag_level & SRDS_DIAG_EVENT_SAFE) { 1418 blackhawk_tsc_INTERNAL_event_log_dump_state_t state; 1419 uint8_t micro_num = 0; 1420 srds_info_t *blackhawk_tsc_info_ptr; 1421 blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(sa__); 1422 #ifdef PHYMOD_SUPPORT 1423 if ( blackhawk_tsc_info_ptr == NULL ) { 1424 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 1425 } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 1426 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 1427 } 1428 #endif /* PHYMOD_SUPPORT */ 1429 for (; micro_num<blackhawk_tsc_info_ptr->micro_count; ++micro_num) 1430 { 1431 state.index = 0; 1432 state.line_start_index = 0; 1433 EFUN(blackhawk_tsc_INTERNAL_read_event_log_with_callback(sa__, micro_num, 1, &state, blackhawk_tsc_INTERNAL_event_log_dump_callback)); 1434 EFUN(blackhawk_tsc_INTERNAL_event_log_dump_callback(&state, 0, 0)); 1435 } 1436 } 1437 if(diag_level & SRDS_DIAG_EVENT) { 1438 EFUN(blackhawk_tsc_read_event_log(sa__)); 1439 } 1440 if(diag_level & SRDS_DIAG_EYE) { 1441 EFUN(blackhawk_tsc_display_eye_scan(sa__)); 1442 } 1443 /* currently REG_CORE and REG_LANE dump same data. */ 1444 core = blackhawk_tsc_get_core(sa__); 1445 lane = blackhawk_tsc_get_lane(sa__); 1446 1447 if((diag_level & SRDS_DIAG_REG_CORE) 1448 || (diag_level & SRDS_DIAG_REG_LANE)) { 1449 EFUN(blackhawk_tsc_reg_dump(sa__, core, lane, NULL)); 1450 } 1451 if(diag_level & SRDS_DIAG_UC_CORE) { 1452 EFUN(blackhawk_tsc_uc_core_var_dump(sa__, core, NULL)); 1453 1454 { 1455 uint8_t orig_lane, num_micros, lane; 1456 1457 ESTM(num_micros = rdc_micro_num_uc_cores()); 1458 orig_lane = blackhawk_tsc_get_physical_lane(sa__); 1459 for (lane = 0; lane < num_micros*2; lane += 2) { 1460 EFUN(blackhawk_tsc_set_physical_lane(sa__, lane)); 1461 1462 EFUN(blackhawk_tsc_uc_micro_var_dump(sa__, core, lane, NULL)); 1463 } 1464 EFUN(blackhawk_tsc_set_physical_lane(sa__, orig_lane)); 1465 } 1466 } 1467 if(diag_level & SRDS_DIAG_UC_LANE) { 1468 1469 EFUN(blackhawk_tsc_uc_lane_var_dump(sa__, core, lane, NULL)); 1470 } 1471 if(diag_level & SRDS_DIAG_LANE_DEBUG) { 1472 EFUN(blackhawk_tsc_display_lane_debug_status(sa__)); 1473 } 1474 if(diag_level & SRDS_DIAG_BER_VERT) { 1475 /* display ber projections for all channels */ 1476 uint8_t ber_mode = DIAG_BER_VERT | DIAG_BER_POS; 1477 uint8_t timer_control = 23; /* 30 seconds */ 1478 uint8_t err_threshold = 100 / 16; /* 100 errors */ 1479 EFUN(_display_ber_scan_data(sa__, ber_mode, timer_control, err_threshold)); 1480 ber_mode = DIAG_BER_VERT | DIAG_BER_NEG; 1481 EFUN(_display_ber_scan_data(sa__, ber_mode, timer_control, err_threshold)); 1482 } 1483 if(diag_level & SRDS_DIAG_BER_HORZ) { 1484 /* display ber projections for all channels */ 1485 uint8_t ber_mode = DIAG_BER_HORZ | DIAG_BER_POS; 1486 uint8_t timer_control = 23; /* 30 seconds */ 1487 uint8_t err_threshold = 100 / 16; /* 100 errors */ 1488 EFUN(_display_ber_scan_data(sa__, ber_mode, timer_control, err_threshold)); 1489 ber_mode = DIAG_BER_HORZ | DIAG_BER_NEG; 1490 EFUN(_display_ber_scan_data(sa__, ber_mode, timer_control, err_threshold)); 1491 } 1492 1493 /* re enable micro */ 1494 if (!micro_stop) { 1495 EFUN(blackhawk_tsc_stop_rx_adaptation(sa__, 0)); 1496 } 1497 1498 EFUN_PRINTF(("\n\n")); 1499 return (ERR_CODE_NONE); 1500 1501 } 1502 1503 typedef struct { 1504 uint16_t addr; 1505 uint8_t line_byte_counter; 1506 } blackhawk_tsc_diag_access_callback_state_t; 1507 1508 static err_code_t blackhawk_tsc_diag_access_read_byte_callback(void *arg, uint8_t byte_count, uint16_t data) { 1509 blackhawk_tsc_diag_access_callback_state_t * const state_ptr = (blackhawk_tsc_diag_access_callback_state_t *)arg; 1510 while (byte_count > 0) { 1511 if (state_ptr->line_byte_counter == 0) { 1512 USR_PRINTF(("\n%04x ", state_ptr->addr)); 1513 } 1514 USR_PRINTF(("%02x ", data & 0xFF)); 1515 ++state_ptr->addr; 1516 state_ptr->line_byte_counter = (state_ptr->line_byte_counter+1) % 16; 1517 data >>= 8; 1518 --byte_count; 1519 } 1520 return (ERR_CODE_NONE); 1521 } 1522 1523 static err_code_t blackhawk_tsc_diag_access_read_word_callback(void *arg, uint8_t byte_count, uint16_t data) { 1524 blackhawk_tsc_diag_access_callback_state_t * const state_ptr = (blackhawk_tsc_diag_access_callback_state_t *)arg; 1525 UNUSED(byte_count); 1526 1527 if (state_ptr->line_byte_counter == 0) { 1528 USR_PRINTF(("\n%04x ", state_ptr->addr)); 1529 } 1530 USR_PRINTF(("%04x ", data)); 1531 state_ptr->addr += 2; 1532 state_ptr->line_byte_counter = (state_ptr->line_byte_counter+2) % 16; 1533 return (ERR_CODE_NONE); 1534 } 1535 1536 /* Required Diagnostic Functions */ 1537 err_code_t blackhawk_tsc_diag_access(srds_access_t *sa__, enum srds_diag_access_enum type, uint16_t addr, uint16_t data, uint16_t param) { 1538 srds_info_t *blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(sa__); 1539 blackhawk_tsc_diag_access_callback_state_t state; 1540 1541 #ifdef PHYMOD_SUPPORT 1542 if ( blackhawk_tsc_info_ptr == NULL ) { 1543 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 1544 } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) { 1545 blackhawk_tsc_init_blackhawk_tsc_info(sa__); 1546 } 1547 #endif /* PHYMOD_SUPPORT */ 1548 EFUN(blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(blackhawk_tsc_info_ptr, sa__)); 1549 state.addr = addr; 1550 state.line_byte_counter = 0; 1551 1552 1553 switch(type) { 1554 case SRDS_REG_READ: { 1555 uint16_t tmp = 0; 1556 if(data > 1) { 1557 uint16_t i; 1558 EFUN_PRINTF(("\n**** SERDES BLK REGISTER READ ****")); 1559 for (i = 0; i < data; i++) { 1560 if (!(i % 16)) { 1561 ESTM_PRINTF(("\n%04x ",i+addr)); 1562 } 1563 EFUN(blackhawk_tsc_pmd_rdt_reg(sa__, i+addr,&tmp)); 1564 ESTM_PRINTF(("%04x ", tmp)); 1565 } 1566 EFUN_PRINTF(("\n")); 1567 } else { 1568 EFUN(blackhawk_tsc_pmd_rdt_reg(sa__, addr,&tmp)); 1569 EFUN_PRINTF(("Register Read: x%04x = x%04x\n",addr,tmp)); 1570 } 1571 } break; 1572 case SRDS_REG_RMW: { 1573 uint16_t tmp = 0, tmp2; 1574 EFUN(blackhawk_tsc_pmd_rdt_reg(sa__, addr,&tmp)); 1575 tmp2 = (tmp & ~param) | (param & data); 1576 EFUN(blackhawk_tsc_pmd_wr_reg(sa__, addr,tmp2)); 1577 EFUN_PRINTF(("Register RMW: x%04x = x%04x -> x%04x\n",addr,tmp,tmp2)); 1578 } break; 1579 case SRDS_CORE_RAM_READ_BYTE: { 1580 if(data > 1) { 1581 EFUN_PRINTF(("\n**** SERDES BLK CORE RAM READ BYTE ****")); 1582 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1583 addr + blackhawk_tsc_info_ptr->core_var_ram_base, 1584 data, 1585 0, 1586 data, 1587 &state, 1588 blackhawk_tsc_diag_access_read_byte_callback)); 1589 EFUN_PRINTF(("\n")); 1590 } else { 1591 ESTM_PRINTF(("Core RAM Read byte: x%04x = x%02x\n",(uint8_t)addr,blackhawk_tsc_rdbc_uc_var(sa__, __ERR, (uint8_t)addr))); 1592 } 1593 } break; 1594 case SRDS_LANE_RAM_READ_BYTE: { 1595 if(data > 1) { 1596 EFUN_PRINTF(("\n**** SERDES BLK LANE RAM READ BYTE ****")); 1597 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, (addr + blackhawk_tsc_info_ptr->lane_var_ram_base + (blackhawk_tsc_get_physical_lane(sa__) * blackhawk_tsc_info_ptr->lane_var_ram_size)), 1598 data, 1599 0, 1600 data, 1601 &state, 1602 blackhawk_tsc_diag_access_read_byte_callback)); 1603 EFUN_PRINTF(("\n")); 1604 } else { 1605 ESTM_PRINTF(("Lane RAM Read byte: x%04x = x%02x\n",addr,blackhawk_tsc_rdbl_uc_var(sa__, __ERR,addr))); 1606 } 1607 } break; 1608 case SRDS_CORE_RAM_READ_WORD: { 1609 if(data > 1) { 1610 EFUN_PRINTF(("\n**** SERDES BLK CORE RAM READ WORD ****")); 1611 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1612 addr + blackhawk_tsc_info_ptr->core_var_ram_base, 1613 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1614 0, 1615 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1616 &state, 1617 blackhawk_tsc_diag_access_read_word_callback)); 1618 EFUN_PRINTF(("\n")); 1619 } else { 1620 ESTM_PRINTF(("Core RAM Read word: x%04x = x%04x\n",addr,blackhawk_tsc_rdwc_uc_var(sa__, __ERR, (uint8_t)addr))); 1621 } 1622 } break; 1623 case SRDS_LANE_RAM_READ_WORD: { 1624 if(data > 1) { 1625 EFUN_PRINTF(("\n**** SERDES BLK LANE RAM READ WORD ****")); 1626 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, (addr + blackhawk_tsc_info_ptr->lane_var_ram_base + (blackhawk_tsc_get_physical_lane(sa__) * blackhawk_tsc_info_ptr->lane_var_ram_size)), 1627 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1628 0, 1629 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1630 &state, 1631 blackhawk_tsc_diag_access_read_word_callback)); 1632 EFUN_PRINTF(("\n")); 1633 } else { 1634 ESTM_PRINTF(("Lane RAM Read word: x%04x = x%04x\n",addr,blackhawk_tsc_rdwl_uc_var(sa__, __ERR, addr))); 1635 } 1636 } break; 1637 case SRDS_CORE_RAM_RMW_BYTE: { 1638 uint8_t tmp, tmp2; 1639 ESTM(tmp = blackhawk_tsc_rdbc_uc_var(sa__, __ERR, (uint8_t)addr)); 1640 tmp2 = (tmp & (uint8_t)~param) | ((uint8_t)param & data); 1641 EFUN(blackhawk_tsc_wrbc_uc_var(sa__, (uint8_t)addr,tmp2)); 1642 EFUN_PRINTF(("Core RAM RMW byte: x%04x = x%02x -> x%02x\n",addr,tmp,tmp2)); 1643 } break; 1644 case SRDS_LANE_RAM_RMW_BYTE: { 1645 uint8_t tmp, tmp2; 1646 ESTM(tmp = blackhawk_tsc_rdbl_uc_var(sa__, __ERR,addr)); 1647 tmp2 = (tmp & (uint8_t)~param) | ((uint8_t)param & data); 1648 EFUN(blackhawk_tsc_wrbl_uc_var(sa__, addr,tmp2)); 1649 EFUN_PRINTF(("Lane RAM RMW byte: x%04x = x%02x -> x%02x\n",addr,tmp,tmp2)); 1650 } break; 1651 case SRDS_CORE_RAM_RMW_WORD: { 1652 uint16_t tmp, tmp2; 1653 ESTM(tmp = blackhawk_tsc_rdwc_uc_var(sa__, __ERR, (uint8_t)addr)); 1654 tmp2 = (tmp & ~param) | (param & data); 1655 EFUN(blackhawk_tsc_wrwc_uc_var(sa__, (uint8_t)addr,tmp2)); 1656 EFUN_PRINTF(("Core RAM RMW word: x%04x = x%04x -> x%04x\n",addr,tmp,tmp2)); 1657 } break; 1658 case SRDS_LANE_RAM_RMW_WORD: { 1659 uint16_t tmp, tmp2; 1660 ESTM(tmp = blackhawk_tsc_rdwl_uc_var(sa__, __ERR,addr)); 1661 tmp2 = (tmp & ~param) | (param & data); 1662 EFUN(blackhawk_tsc_wrwl_uc_var(sa__, addr,tmp2)); 1663 EFUN_PRINTF(("Lane RAM RMW word: x%04x = x%04x -> x%04x\n",addr,tmp,tmp2)); 1664 } break; 1665 case SRDS_GLOB_RAM_READ_BYTE: { 1666 if(data > 1) { 1667 EFUN_PRINTF(("\n**** SERDES BLK GLOB RAM READ BYTE ****")); 1668 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1669 0x20000000 | (uint32_t)addr, 1670 data, 1671 0, 1672 data, 1673 &state, 1674 blackhawk_tsc_diag_access_read_byte_callback)); 1675 EFUN_PRINTF(("\n")); 1676 } else { 1677 ESTM_PRINTF(("Glob RAM Read byte: x%04x = x%02x\n",addr,blackhawk_tsc_INTERNAL_rdb_uc_var(sa__, __ERR,addr))); 1678 } 1679 } break; 1680 case SRDS_GLOB_RAM_RMW_BYTE: { 1681 uint8_t tmp, tmp2; 1682 ESTM(tmp = blackhawk_tsc_INTERNAL_rdb_uc_var(sa__, __ERR,addr)); 1683 tmp2 = (tmp & (uint8_t)~param) | ((uint8_t)param & data); 1684 EFUN(blackhawk_tsc_INTERNAL_wrb_uc_var(sa__, addr,tmp2)); 1685 EFUN_PRINTF(("Glob RAM RMW byte: x%04x = x%02x -> x%02x\n",addr,tmp,tmp2)); 1686 } break; 1687 case SRDS_GLOB_RAM_READ_WORD: { 1688 if(data > 1) { 1689 EFUN_PRINTF(("\n**** SERDES BLK GLOB RAM READ WORD ****")); 1690 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1691 0x20000000 | (uint32_t)addr, 1692 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1693 0, 1694 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1695 &state, 1696 blackhawk_tsc_diag_access_read_word_callback)); 1697 EFUN_PRINTF(("\n")); 1698 } else { 1699 ESTM_PRINTF(("Glob RAM Read word: x%04x = x%04x\n",addr,blackhawk_tsc_INTERNAL_rdw_uc_var(sa__, __ERR,addr))); 1700 } 1701 } break; 1702 case SRDS_GLOB_RAM_RMW_WORD: { 1703 uint16_t tmp, tmp2; 1704 ESTM(tmp = blackhawk_tsc_INTERNAL_rdw_uc_var(sa__, __ERR,addr)); 1705 tmp2 = (tmp & ~param) | (param & data); 1706 EFUN(blackhawk_tsc_INTERNAL_wrw_uc_var(sa__, addr,tmp2)); 1707 EFUN_PRINTF(("Glob RAM RMW word: x%04x = x%04x -> x%04x\n",addr,tmp,tmp2)); 1708 } break; 1709 case SRDS_UC_CMD: { 1710 uint16_t tmp; 1711 EFUN(blackhawk_tsc_pmd_uc_cmd_with_data(sa__, (enum srds_pmd_uc_cmd_enum)addr, (uint8_t)param, data, GRACEFUL_STOP_TIME)); 1712 ESTM(tmp = rd_uc_dsc_data()); 1713 EFUN_PRINTF(("uC Command: cmd=x%02x supp=x%02x data=x%04x returned=x%04x\n",addr,param,data,tmp)); 1714 } break; 1715 case SRDS_PROG_RAM_READ_BYTE: { 1716 if(data > 1) { 1717 EFUN_PRINTF(("\n**** SERDES BLK PROG RAM READ BYTE ****")); 1718 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1719 addr, 1720 data, 1721 0, 1722 data, 1723 &state, 1724 blackhawk_tsc_diag_access_read_byte_callback)); 1725 EFUN_PRINTF(("\n")); 1726 } else { 1727 ESTM_PRINTF(("Prog RAM Read byte: x%04x = x%02x\n",addr,blackhawk_tsc_INTERNAL_rdb_uc_var(sa__, __ERR,addr))); 1728 } 1729 } break; 1730 case SRDS_PROG_RAM_READ_WORD: { 1731 if(data > 1) { 1732 EFUN_PRINTF(("\n**** SERDES BLK PROG RAM READ WORD ****")); 1733 EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__, 1734 addr, 1735 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1736 0, 1737 ((data+1)>>1)<<1, /* Round up to nearest word count */ 1738 &state, 1739 blackhawk_tsc_diag_access_read_word_callback)); 1740 EFUN_PRINTF(("\n")); 1741 } else { 1742 ESTM_PRINTF(("Prog RAM Read word: x%04x = x%04x\n",addr,blackhawk_tsc_INTERNAL_rdw_uc_var(sa__, __ERR,addr))); 1743 } 1744 } break; 1745 case SRDS_BER_PROJ_DATA: { 1746 /* display ber projections for all channels */ 1747 EFUN(_display_ber_scan_data(sa__, (uint8_t)addr, (uint8_t)data, (uint8_t)(param>>4))); 1748 } break; 1749 case SRDS_EN_BREAKPOINT: 1750 case SRDS_GOTO_BREAKPOINT: 1751 case SRDS_RD_BREAKPOINT: 1752 case SRDS_DIS_BREAKPOINT: 1753 default: EFUN_PRINTF(("Invalid request type blackhawk_tsc_diag_access\n")); 1754 } 1755 1756 return(ERR_CODE_NONE); 1757 } 1758 1759 err_code_t blackhawk_tsc_display_state (srds_access_t *sa__) { 1760 EFUN(blackhawk_tsc_display_core_state(sa__)); 1761 EFUN(blackhawk_tsc_display_lane_state_hdr()); 1762 EFUN(blackhawk_tsc_display_lane_state(sa__)); 1763 EFUN(blackhawk_tsc_display_lane_state_legend()); 1764 return(ERR_CODE_NONE); 1765 } 1766 1767 err_code_t blackhawk_tsc_display_config (srds_access_t *sa__) { 1768 EFUN(blackhawk_tsc_display_core_config(sa__)); 1769 EFUN(blackhawk_tsc_display_lane_config(sa__)); 1770 return(ERR_CODE_NONE); 1771 } 1772 1773 /*************************/ 1774 /* Temperature forcing */ 1775 /*************************/ 1776 1777 err_code_t blackhawk_tsc_force_die_temperature (srds_access_t *sa__, int16_t die_temp) { 1778 /* disable force */ 1779 if(die_temp == -255) { 1780 EFUN(wrc_micro_pvt_tempdata_frc(0)); 1781 return(ERR_CODE_NONE); 1782 } 1783 1784 /* enable force */ 1785 if (die_temp>130) 1786 die_temp = 130; 1787 if (die_temp<-45) 1788 die_temp = -45; 1789 1790 EFUN(wrc_micro_pvt_tempdata_frcval(_degC_to_bin(die_temp))); 1791 EFUN(wrc_micro_pvt_tempdata_frc(1)); 1792 1793 return(ERR_CODE_NONE); 1794 } 1795 1796 /**********************/ 1797 /* CL72/CL93 Status */ 1798 /**********************/ 1799 1800 1801 1802 err_code_t blackhawk_tsc_display_linktrn_status(srds_access_t *sa__) { 1803 EFUN_PRINTF(("\n\n***************************\n" )); 1804 ESTM_PRINTF(( "** LANE %d CL93n72 Status **\n" , blackhawk_tsc_get_lane(sa__) )); 1805 EFUN_PRINTF(( "***************************\n" )); 1806 ESTM_PRINTF(( "linktrn_signal_detect = %d (1 = Link training FSM in SEND_DATA state; 0 = Link in training state)" "\n", rd_linktrn_training_fsm_signal_detect())); 1807 ESTM_PRINTF(( "linktrn_ieee_training_failure = %d (1 = Training failure detected; 0 = Training failure not detected)\n", rd_linktrn_ieee_training_failure() )); 1808 ESTM_PRINTF(( "linktrn_ieee_training_status = %d (1 = Start-up protocol in progress; 0 = Start-up protocol complete)" "\n", rd_linktrn_ieee_training_status() )); 1809 ESTM_PRINTF(( "linktrn_ieee_receiver_status = %d (1 = Receiver trained and ready to receive; 0 = Receiver training)" "\n\n", rd_linktrn_ieee_receiver_status() )); 1810 return(ERR_CODE_NONE); 1811 } 1812 1813 1814 1815