openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

blackhawk_tsc_internal.c (114651B)


      1 /***********************************************************************************
      2  ***********************************************************************************
      3  *  File Name     :  blackhawk_tsc_internal.c                                         *
      4  *  Created On    :  13/02/2014                                                    *
      5  *  Created By    :  Justin Gaither                                                *
      6  *  Description   :  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_internal.c
     23  * Implementation of API functions
     24  */
     25 #include <phymod/phymod_system.h>
     26 #include "blackhawk_tsc_internal.h"
     27 #include "blackhawk_tsc_internal_error.h"
     28 #include "blackhawk_tsc_access.h"
     29 #include "blackhawk_tsc_common.h"
     30 #include "blackhawk_tsc_config.h"
     31 #include "blackhawk_tsc_functions.h"
     32 #include "blackhawk_tsc_select_defns.h"
     33 #include "blackhawk_tsc_prbs.h"
     34 #include "blackhawk_tsc_debug_functions.h"
     35 
     36 
     37 
     38 
     39 /* If SERDES_EVAL is defined, then is_ate_log_enabled() is queried to *\
     40 \* know whether to log ATE.  blackhawk_tsc_access.h provides that function.  */
     41 uint32_t blackhawk_tsc_INTERNAL_mult_with_overflow_check(uint32_t a, uint32_t b, uint8_t *of) {
     42     uint16_t c,d;
     43     uint32_t r,s;
     44     if (a > b) return blackhawk_tsc_INTERNAL_mult_with_overflow_check(b, a, of);
     45     *of = 0;
     46     c = b >> 16;
     47     d = UINT16_MAX & b;
     48     r = a * c;
     49     s = a * d;
     50     if (r > UINT16_MAX) *of = 1;
     51     r <<= 16;
     52     return (s + r);
     53 }
     54 
     55 #ifdef SERDES_MULTI_INFO_TABLE_EN 
     56 srds_info_t blackhawk_tsc_info[NUM_SERDES_INFO_TABLES];
     57 #endif
     58 
     59 
     60 srds_info_t *blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(srds_access_t *sa__) {
     61     err_code_t err_code = ERR_CODE_NONE;
     62     srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__);
     63 #ifdef PHYMOD_SUPPORT
     64     if ( blackhawk_tsc_info_ptr == NULL ) {
     65         blackhawk_tsc_init_blackhawk_tsc_info(sa__);
     66     } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) {
     67         blackhawk_tsc_init_blackhawk_tsc_info(sa__);
     68     }
     69 #endif /* PHYMOD_SUPPORT */
     70     if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) {
     71         err_code = blackhawk_tsc_init_blackhawk_tsc_info(sa__);
     72         if (err_code != ERR_CODE_NONE){
     73             EFUN_PRINTF(("ERROR:  %s Failed: 0x%04X \n", API_FUNCTION_NAME, err_code));
     74             return 0;
     75         }
     76     } 
     77     return blackhawk_tsc_info_ptr;
     78 }
     79 
     80 err_code_t blackhawk_tsc_INTERNAL_match_ucode_from_info(srds_access_t *sa__) {
     81     uint16_t ucode_version_major;
     82     uint8_t ucode_version_minor;
     83     uint32_t ucode_version;
     84 
     85     srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(sa__);
     86     CHECK_AND_RETURN_IF_NULL(blackhawk_tsc_info_ptr, ERR_CODE_INVALID_INFO_TABLE_ADDR);
     87 
     88     ESTM(ucode_version_major = rdcv_common_ucode_version());
     89     ESTM(ucode_version_minor = rdcv_common_ucode_minor_version());
     90     ucode_version = (ucode_version_major << 8) | ucode_version_minor;
     91     if (ucode_version == blackhawk_tsc_info_ptr->ucode_version) {
     92         return(ERR_CODE_NONE);
     93     } else {
     94         EFUN_PRINTF(("ERROR:  ucode version of the current thread not matching with stored blackhawk_tsc_info->ucode_version, Expected 0x%08X, but received 0x%08X.\n",
     95                     blackhawk_tsc_info_ptr->ucode_version, ucode_version));
     96         return(ERR_CODE_UCODE_VERIFY_FAIL);
     97     }
     98 }
     99 
    100 err_code_t blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(srds_info_t *blackhawk_tsc_info_ptr, srds_access_t *sa__)
    101 {
    102     err_code_t err_code = ERR_CODE_NONE;
    103 
    104     CHECK_AND_RETURN_IF_NULL(blackhawk_tsc_info_ptr, ERR_CODE_INVALID_INFO_TABLE_ADDR);
    105 
    106     if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) {
    107         EFUN_PRINTF(("ERROR:  Mismatch in blackhawk_tsc_info signature.  Expected 0x%08X, but received 0x%08X.\n",
    108                      SRDS_INFO_SIGNATURE, blackhawk_tsc_info_ptr->signature));
    109         return (blackhawk_tsc_error(sa__, ERR_CODE_INFO_TABLE_ERROR));
    110     }
    111     err_code = blackhawk_tsc_INTERNAL_match_ucode_from_info(sa__);
    112     if (err_code != ERR_CODE_NONE) {
    113         /* ucode version mismatch */
    114         return(ERR_CODE_MICRO_INIT_NOT_DONE);
    115     }
    116     return (ERR_CODE_NONE);
    117 }
    118 
    119 
    120 int blackhawk_tsc_osr_mode_enum_to_int_x1000(uint8_t osr_mode) {
    121     switch(osr_mode) {
    122     case BLACKHAWK_TSC_OSX1:      return 1000;
    123     case BLACKHAWK_TSC_OSX2:      return 2000;
    124     case BLACKHAWK_TSC_OSX4:      return 4000;
    125     case BLACKHAWK_TSC_OSX8:      return 8000;
    126     case BLACKHAWK_TSC_OSX16P5:   return 16500;
    127     case BLACKHAWK_TSC_OSX20P625: return 20625;
    128     case BLACKHAWK_TSC_OSX16:     return 16000;
    129     case BLACKHAWK_TSC_OSX32:     return 32000;
    130     case BLACKHAWK_TSC_OSX21P25:  return 21250;
    131 #ifdef wr_ams_rx_rxclk_div2p5
    132     case BLACKHAWK_TSC_OSX2P5:    return 2500;
    133 #endif
    134     default:                    return 1000;
    135     }
    136 }
    137 
    138 err_code_t blackhawk_tsc_INTERNAL_get_num_bits_per_ms(srds_access_t *sa__, uint32_t *num_bits_per_ms) {
    139     uint8_t osr_mode = 0;
    140 #if defined(rd_rx_pam4_mode)
    141     uint8_t pam4_mode = 0;
    142 #endif
    143     uint8_t pll_select = 0, prev_pll = 0;
    144     struct blackhawk_tsc_uc_core_config_st core_config = {{0}};
    145 
    146     { 
    147        blackhawk_tsc_osr_mode_st osr_mode_st;
    148        ENULL_MEMSET(&osr_mode_st, 0, sizeof(blackhawk_tsc_osr_mode_st));
    149        EFUN(blackhawk_tsc_INTERNAL_get_osr_mode(sa__, &osr_mode_st));
    150        osr_mode = osr_mode_st.rx;
    151     }
    152 
    153 #if defined(rd_rx_pam4_mode)
    154     ESTM(pam4_mode = rd_rx_pam4_mode());
    155 #endif
    156 
    157 #if defined(rd_rx_pll_select)
    158     ESTM(prev_pll = blackhawk_tsc_get_pll_idx(sa__));
    159     ESTM(pll_select = rd_rx_pll_select());
    160     EFUN(blackhawk_tsc_set_pll_idx(sa__,pll_select));
    161 #endif
    162         EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_config));
    163         *num_bits_per_ms = (((uint32_t)core_config.vco_rate_in_Mhz * 100000UL) / blackhawk_tsc_osr_mode_enum_to_int_x1000(osr_mode))*10;
    164 
    165 #if defined(rd_rx_pam4_mode)
    166     if(pam4_mode > 0) *num_bits_per_ms <<= 1; 
    167 #endif
    168     EFUN(blackhawk_tsc_set_pll_idx(sa__,prev_pll));
    169     return(ERR_CODE_NONE);
    170 }
    171 
    172 err_code_t blackhawk_tsc_INTERNAL_display_BER(srds_access_t *sa__, uint16_t time_ms) {
    173     char string[10];
    174     EFUN(blackhawk_tsc_INTERNAL_get_BER_string(sa__,time_ms,string));
    175     USR_PRINTF(("%s",string));
    176     return(ERR_CODE_NONE);
    177 }
    178 
    179 err_code_t blackhawk_tsc_INTERNAL_get_BER_string(srds_access_t *sa__, uint16_t time_ms, char *string) {
    180     char string2[3];
    181     struct ber_data_st ber_data_local;
    182 
    183     ENULL_MEMSET(&ber_data_local, 0, sizeof(ber_data_local));
    184     if(string == NULL) {
    185         return(ERR_CODE_BAD_PTR_OR_INVALID_INPUT);
    186     }
    187 
    188     EFUN(blackhawk_tsc_INTERNAL_get_BER_data(sa__, time_ms, &ber_data_local, USE_HW_TIMERS));
    189 
    190     if(ber_data_local.prbs_chk_en == 0) {
    191         USR_STRCPY(string,"");
    192         return(ERR_CODE_NONE);
    193     } else {
    194         USR_STRCPY(string2," ");
    195     }
    196 
    197     if((COMPILER_64_HI(ber_data_local.num_errs) == 0) &&
    198        (COMPILER_64_LO(ber_data_local.num_errs) < 3) &&
    199        (ber_data_local.lcklost == 0)) {   /* lcklost = 0 */
    200         USR_STRNCAT(string2,"<",1);
    201         COMPILER_64_SET(ber_data_local.num_errs, 0, 3);
    202     } else {
    203         USR_STRNCAT(string2," ",1);
    204     }
    205     if(ber_data_local.lcklost == 1) {    /* lcklost = 1 */
    206         USR_STRCPY(string,"  !Lock ");
    207     } else {                    /* lcklost = 0 */
    208         uint16_t x=0,y=0,z=0,srds_div;
    209 
    210         if(COMPILER_64_GE(ber_data_local.num_errs, ber_data_local.num_bits)) {
    211             x = 1;y=0;z=0;
    212         }else {
    213             uint64_t temp_dividend;
    214             uint64_t temp_divisor;
    215             while(1) {
    216                 COMPILER_64_COPY(temp_dividend, ber_data_local.num_errs);
    217                 COMPILER_64_SHL(temp_dividend, 1);
    218                 COMPILER_64_ADD_64(temp_dividend, ber_data_local.num_bits);
    219 
    220                 COMPILER_64_COPY(temp_divisor, ber_data_local.num_bits);
    221                 COMPILER_64_SHL(temp_divisor, 1);
    222 
    223                 COMPILER_64_UDIV_64(temp_dividend, temp_divisor);
    224 
    225                 srds_div = (uint16_t) COMPILER_64_LO( temp_dividend );
    226 
    227                 if(srds_div>=10) {
    228                     break;
    229                 }
    230 
    231                 COMPILER_64_UMUL_32(ber_data_local.num_errs, 10);
    232                 z=z+1;
    233             }
    234             if(srds_div>=100) {
    235                 srds_div = srds_div/10;
    236                 z=z-1;
    237             }
    238             x=srds_div/10;
    239             y = srds_div - 10*x;
    240             z=z-1;
    241         }
    242         USR_SPRINTF(string,"%s%d.%1de-%02d",string2,x,y,z);
    243 
    244     }
    245     return(ERR_CODE_NONE);
    246 
    247 }
    248 
    249 err_code_t blackhawk_tsc_INTERNAL_get_BER_data(srds_access_t *sa__, uint16_t time_ms, struct ber_data_st *ber_data, enum blackhawk_tsc_prbs_chk_timer_selection_enum timer_sel) {
    250     uint8_t lcklost = 0;
    251     uint32_t err_cnt= 0;
    252     const uint8_t ITER_MAX=10;
    253     uint8_t iter=0 ;
    254     
    255 
    256     if(ber_data == NULL) {
    257         return(ERR_CODE_BAD_PTR_OR_INVALID_INPUT);
    258     }
    259 
    260     ESTM(ber_data->prbs_chk_en = rd_prbs_chk_en());
    261     if(ber_data->prbs_chk_en == 0)
    262         return(ERR_CODE_NONE);
    263 
    264     /* hardware timer's limitation - 448ms Max */
    265     if((time_ms <= PRBS_MAX_HW_TIMER_TIMEOUT) && (timer_sel == USE_HW_TIMERS)) {
    266         uint8_t prbs_chk_mode_bak = 0;
    267         uint32_t num_bits_per_ms=0;
    268         uint16_t time_ms_adjusted = 0;
    269         uint8_t prbs_chk_lock = 0;
    270         struct prbs_chk_hw_timer_ctrl_st prbs_chk_hw_timer_ctrl_bak;
    271         USR_MEMSET(&prbs_chk_hw_timer_ctrl_bak, 0, sizeof(struct prbs_chk_hw_timer_ctrl_st));
    272         /* STEP 1: save prbs chk mode */
    273         ESTM(prbs_chk_mode_bak = rd_prbs_chk_mode());
    274         
    275         /* STEP 2: force prbs mode 2, initial seed without hysteresis */ /* ??????????????????? */
    276         EFUN(wr_prbs_chk_mode(PRBS_INITIAL_SEED_NO_HYSTERESIS));
    277         
    278         /* STEP 3: save prbs hardware timer config registers */
    279         EFUN(blackhawk_tsc_get_prbs_chk_hw_timer_ctrl(sa__, &prbs_chk_hw_timer_ctrl_bak));
    280         
    281         /* STEP 4: Configure hardware timer to count prbs errors */
    282         EFUN(blackhawk_tsc_config_prbs_chk_hw_timer(sa__, time_ms, &time_ms_adjusted));
    283         
    284         /* STEP 5: Clear prbs error counters and lock lost status */
    285         EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost)); /* clear error counters */
    286         
    287         /* STEP 6: toggle checker enable to start hardware timers and error counters */
    288         EFUN(blackhawk_tsc_prbs_chk_en_toggle(sa__));
    289         
    290         /* STEP 7: Confirm that prbs lock was achieved */
    291         ESTM(prbs_chk_lock = rd_prbs_chk_lock());
    292         if(!prbs_chk_lock) {
    293             /* If prbs lock was not achieved, set lcklost = 1 and skip the wait for error accumulation */
    294             ber_data->lcklost = 1;            
    295         } else {
    296             /* STEP 8: wait time_ms for hardware timeout */
    297             EFUN(USR_DELAY_MS(time_ms_adjusted));
    298             /* STEP 9: Poll prbs_chk_lock to make sure timers expired */
    299             do {
    300                 EFUN(USR_DELAY_MS(1));
    301                 ESTM(prbs_chk_lock = rd_prbs_chk_lock());
    302                 iter++;
    303             } while(prbs_chk_lock && iter<ITER_MAX);
    304             
    305             if(prbs_chk_lock) {
    306                 /* timer hasn't expired or it expired and lock didn't go away */
    307                 ber_data->lcklost = 1;
    308                 return ERR_CODE_PRBS_CHK_HW_TIMERS_NOT_EXPIRED;
    309             }
    310             
    311             /* STEP 10: Read error counters */
    312             EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost));
    313             
    314             /* STEP 11: Update the BER data structure */
    315             EFUN(blackhawk_tsc_INTERNAL_get_num_bits_per_ms(sa__,&num_bits_per_ms));
    316             COMPILER_64_SET(ber_data->num_bits, 0, num_bits_per_ms);
    317             COMPILER_64_UMUL_32(ber_data->num_bits, time_ms_adjusted);
    318             COMPILER_64_SET(ber_data->num_errs, 0, err_cnt);
    319 /*
    320             ber_data->num_bits = (uint64_t)num_bits_per_ms*(uint64_t)time_ms_adjusted;
    321             ber_data->num_errs = err_cnt;
    322 */
    323             ber_data->lcklost  = 0;
    324         }
    325         /* STEP 12: restore prbs hardware timer config registers */
    326         EFUN(blackhawk_tsc_set_prbs_chk_hw_timer_ctrl(sa__, &prbs_chk_hw_timer_ctrl_bak));
    327         /* STEP 13: Restore prbs check mode */
    328         EFUN(wr_prbs_chk_mode(prbs_chk_mode_bak));        
    329     } else
    330     {
    331         UNUSED(timer_sel);
    332         EFUN(USR_DELAY_MS(time_ms));
    333         EFUN(blackhawk_tsc_prbs_err_count_state(sa__, &err_cnt,&lcklost));
    334         ber_data->lcklost = lcklost;
    335         if(ber_data->lcklost == 0) {
    336             uint32_t num_bits_per_ms=0;
    337             EFUN(blackhawk_tsc_INTERNAL_get_num_bits_per_ms(sa__,&num_bits_per_ms));
    338             COMPILER_64_SET(ber_data->num_bits, 0, num_bits_per_ms);
    339             COMPILER_64_UMUL_32(ber_data->num_bits, time_ms);
    340             COMPILER_64_SET(ber_data->num_errs, 0, err_cnt);
    341 /*
    342             ber_data->num_bits = (uint64_t)num_bits_per_ms*(uint64_t)time_ms;
    343             ber_data->num_errs = err_cnt;
    344 */
    345             ESTM(lcklost = rd_prbs_chk_lock_lost_lh());
    346 
    347         }
    348     }
    349 
    350 
    351 
    352     return(ERR_CODE_NONE);
    353 }
    354 
    355 err_code_t blackhawk_tsc_INTERNAL_get_prbs_timeout_count_from_time(uint16_t time_ms, uint16_t * time_ms_adjusted, struct prbs_chk_hw_timer_ctrl_st * const prbs_chk_hw_timer_ctrl ) {
    356     uint8_t timeout_value;
    357     uint8_t iter = 0;
    358     if(time_ms > PRBS_HW_LUT_MAX_MINUS_1) {
    359         UNUSED(timeout_value);
    360         *time_ms_adjusted = PRBS_MAX_HW_TIMER_TIMEOUT;
    361         return ERR_CODE_NONE;
    362     }
    363 
    364     *time_ms_adjusted = time_ms;
    365 
    366     if(time_ms < 8) {   /* Linear */
    367         timeout_value = (uint8_t)time_ms;
    368     } else {
    369         for(iter=8; iter>2; iter--) {
    370             if((time_ms>>iter)&0x1)
    371                 break;
    372         }
    373 
    374         timeout_value = ((iter-1)<<2) + ((time_ms>>(iter-2))&(0x3));
    375 
    376         if((time_ms-((time_ms>>(iter-2))<<(iter-2)))>0) {   /* time_ms is not found in the map, using a possible value larger than provided */
    377             timeout_value = timeout_value + 1;
    378             *time_ms_adjusted = ((1<<(((timeout_value)>>2)+1)) + (((timeout_value)&3)*(1<<(((timeout_value)>>2)-1))));
    379         }
    380     }
    381     prbs_chk_hw_timer_ctrl->prbs_chk_en_timeout = timeout_value;
    382     prbs_chk_hw_timer_ctrl->prbs_chk_en_timer_mode = 0x3;   /* 1ms unit */    
    383     return ERR_CODE_NONE;
    384 }
    385 
    386 
    387 
    388 int16_t blackhawk_tsc_INTERNAL_ladder_setting_to_mV(srds_access_t *sa__, int8_t ctrl, uint8_t range_250) {
    389     uint16_t absv;                                    /* Absolute value of ctrl */
    390     int16_t nlmv;                                     /* Non-linear value */
    391 
    392     /* Get absolute value */
    393     absv = SRDS_ABS(ctrl);
    394 
    395     {
    396        UNUSED(range_250);
    397 
    398        nlmv = absv*263/127;
    399     }
    400     /* Add sign and return */
    401     return( (ctrl>=0) ? nlmv : -nlmv);
    402 }
    403 
    404 err_code_t blackhawk_tsc_INTERNAL_pam4_to_bin(srds_access_t *sa__, char var, char bin[]) {
    405     if(!bin) {
    406         return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    407     }
    408 
    409   switch (var) {
    410     case '0':  ENULL_STRCPY(bin,"00");
    411                break;
    412     case '1':  ENULL_STRCPY(bin,"01");
    413                break;
    414     case '2':  ENULL_STRCPY(bin,"11");  /* To account for PAM4 Gray coding */
    415                break;
    416     case '3':  ENULL_STRCPY(bin,"10");  /* To account for PAM4 Gray coding */
    417                break;
    418     case '_':  ENULL_STRCPY(bin,"");
    419                break;
    420     default :  ENULL_STRCPY(bin,"");
    421                EFUN_PRINTF(("ERROR: Invalid PAM4 format Pattern\n"));
    422                return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_PAM4));
    423   }
    424   return (ERR_CODE_NONE);
    425 }
    426 
    427 err_code_t blackhawk_tsc_INTERNAL_compute_bin(srds_access_t *sa__, char var, char bin[]) {
    428     if(!bin) {
    429         return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    430     }
    431 
    432   switch (var) {
    433     case '0':  ENULL_STRCPY(bin,"0000");
    434                break;
    435     case '1':  ENULL_STRCPY(bin,"0001");
    436                break;
    437     case '2':  ENULL_STRCPY(bin,"0010");
    438                break;
    439     case '3':  ENULL_STRCPY(bin,"0011");
    440                break;
    441     case '4':  ENULL_STRCPY(bin,"0100");
    442                break;
    443     case '5':  ENULL_STRCPY(bin,"0101");
    444                break;
    445     case '6':  ENULL_STRCPY(bin,"0110");
    446                break;
    447     case '7':  ENULL_STRCPY(bin,"0111");
    448                break;
    449     case '8':  ENULL_STRCPY(bin,"1000");
    450                break;
    451     case '9':  ENULL_STRCPY(bin,"1001");
    452                break;
    453     case 'a':
    454     case 'A':  ENULL_STRCPY(bin,"1010");
    455                break;
    456     case 'b':
    457     case 'B':  ENULL_STRCPY(bin,"1011");
    458                break;
    459     case 'c':
    460     case 'C':  ENULL_STRCPY(bin,"1100");
    461                break;
    462     case 'd':
    463     case 'D':  ENULL_STRCPY(bin,"1101");
    464                break;
    465     case 'e':
    466     case 'E':  ENULL_STRCPY(bin,"1110");
    467                break;
    468     case 'f':
    469     case 'F':  ENULL_STRCPY(bin,"1111");
    470                break;
    471     case '_':  ENULL_STRCPY(bin,"");
    472                break;
    473     default :  ENULL_STRCPY(bin,"");
    474                EFUN_PRINTF(("ERROR: Invalid Hexadecimal Pattern\n"));
    475                return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_HEX));
    476   }
    477   return (ERR_CODE_NONE);
    478 }
    479 
    480 
    481 err_code_t blackhawk_tsc_INTERNAL_compute_hex(srds_access_t *sa__, char bin[],uint8_t *hex) {
    482   if(!hex) {
    483     return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    484   }
    485  
    486   if (!USR_STRCMP(bin,"0000")) {
    487     *hex = 0x0;
    488   } 
    489   else if (!USR_STRCMP(bin,"0001")) {
    490     *hex = 0x1;
    491   } 
    492   else if (!USR_STRCMP(bin,"0010")) {
    493     *hex = 0x2;
    494   } 
    495   else if (!USR_STRCMP(bin,"0011")) {
    496     *hex = 0x3;
    497   } 
    498   else if (!USR_STRCMP(bin,"0100")) {
    499     *hex = 0x4;
    500   } 
    501   else if (!USR_STRCMP(bin,"0101")) {
    502     *hex = 0x5;
    503   } 
    504   else if (!USR_STRCMP(bin,"0110")) {
    505     *hex = 0x6;
    506   } 
    507   else if (!USR_STRCMP(bin,"0111")) {
    508     *hex = 0x7;
    509   } 
    510   else if (!USR_STRCMP(bin,"1000")) {
    511     *hex = 0x8;
    512   } 
    513   else if (!USR_STRCMP(bin,"1001")) {
    514     *hex = 0x9;
    515   } 
    516   else if (!USR_STRCMP(bin,"1010")) {
    517     *hex = 0xA;
    518   } 
    519   else if (!USR_STRCMP(bin,"1011")) {
    520     *hex = 0xB;
    521   } 
    522   else if (!USR_STRCMP(bin,"1100")) {
    523     *hex = 0xC;
    524   } 
    525   else if (!USR_STRCMP(bin,"1101")) {
    526     *hex = 0xD;
    527   } 
    528   else if (!USR_STRCMP(bin,"1110")) {
    529     *hex = 0xE;
    530   } 
    531   else if (!USR_STRCMP(bin,"1111")) {
    532     *hex = 0xF;
    533   } 
    534   else {
    535     EFUN_PRINTF(("ERROR: Invalid Binary to Hex Conversion\n"));
    536     *hex = 0x0;
    537     return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_BIN2HEX));
    538   } 
    539   return (ERR_CODE_NONE);
    540 }
    541 
    542 uint8_t blackhawk_tsc_INTERNAL_stop_micro(srds_access_t *sa__, uint8_t graceful, err_code_t *err_code_p) {
    543    uint8_t stop_state = 0;
    544 
    545    if(!err_code_p) {
    546        return(0xFF);
    547    }
    548 
    549    /* Log current micro stop status */
    550    EPSTM2((stop_state = rdv_usr_sts_micro_stopped()),0xFF);
    551 
    552    /* Stop micro only if micro is not stopped currently */
    553    if (!(stop_state & 0x7F)) {
    554        if (graceful) {
    555            EPFUN2((blackhawk_tsc_stop_rx_adaptation(sa__, 1)),0xFF);
    556        }
    557        else {
    558            EPFUN2((blackhawk_tsc_pmd_uc_control(sa__, CMD_UC_CTRL_STOP_IMMEDIATE,GRACEFUL_STOP_TIME)),0xFF);
    559        }
    560    }
    561 
    562    /* Return the previous micro stop status */
    563    return(stop_state);
    564 }
    565 
    566 
    567   
    568 
    569 /********************************************************/
    570 /*  Global RAM access through Micro Register Interface  */
    571 /********************************************************/
    572 /* Micro Global RAM Byte Read */
    573 uint8_t blackhawk_tsc_INTERNAL_rdb_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    574     uint8_t rddata;
    575 
    576     if(!err_code_p) {
    577         return(0);
    578     }
    579     EPSTM(rddata = blackhawk_tsc_rdb_uc_ram(sa__, err_code_p, addr)); /* Use Micro register interface for reading RAM */
    580     return (rddata);
    581 }
    582 
    583 /* Micro Global RAM Word Read */
    584 uint16_t blackhawk_tsc_INTERNAL_rdw_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    585   uint16_t rddata;
    586 
    587   if(!err_code_p) {
    588       return(0);
    589   }
    590   if (addr%2 != 0) {                                         /* Validate even address */
    591       *err_code_p = ERR_CODE_INVALID_RAM_ADDR;
    592       USR_PRINTF(("Error incorrect addr x%04x\n",addr));
    593       return (0);
    594   }
    595   EPSTM(rddata = blackhawk_tsc_rdw_uc_ram(sa__, err_code_p, (addr))); /* Use Micro register interface for reading RAM */
    596   return (rddata);
    597 }
    598 
    599 /* Micro Global RAM Byte Write  */
    600 err_code_t blackhawk_tsc_INTERNAL_wrb_uc_var(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) {
    601 
    602     return (blackhawk_tsc_wrb_uc_ram(sa__, addr, wr_val));          /* Use Micro register interface for writing RAM */
    603 }
    604 
    605 /* Micro Global RAM Word Write  */
    606 err_code_t blackhawk_tsc_INTERNAL_wrw_uc_var(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) {
    607     if (addr%2 != 0) {                                       /* Validate even address */
    608       USR_PRINTF(("Error incorrect addr x%04x\n",addr));
    609         return (blackhawk_tsc_error(sa__, ERR_CODE_INVALID_RAM_ADDR));
    610     }
    611     return (blackhawk_tsc_wrw_uc_ram(sa__, addr, wr_val));          /* Use Micro register interface for writing RAM */
    612 }
    613 
    614 
    615 /***********************/
    616 /*  Event Log Display  */
    617 /***********************/
    618 err_code_t blackhawk_tsc_INTERNAL_event_log_dump_callback(void *arg, uint8_t byte_count, uint16_t data) {
    619     blackhawk_tsc_INTERNAL_event_log_dump_state_t * const state_ptr = (blackhawk_tsc_INTERNAL_event_log_dump_state_t *)arg;
    620     const uint8_t bytes_per_row=16;
    621 
    622     if (byte_count == 0) {
    623         if (state_ptr->line_start_index != state_ptr->index) {
    624             EFUN_PRINTF(("%*s    %d\n", 4*(bytes_per_row - state_ptr->index + state_ptr->line_start_index), "", state_ptr->line_start_index));
    625         }
    626         return (ERR_CODE_NONE);
    627     }
    628     if (byte_count == 1) {
    629         /* There is a trailing byte in the event log.
    630          * The simplest way to handle it is to print out a whole word, but mask
    631          * the invalid upper byte.
    632          */
    633         data &= 0xFF;
    634     }
    635     EFUN_PRINTF(("  0x%04x", ((data & 0xFF) << 8) | (data >> 8)));
    636     state_ptr->index += 2;
    637     if (state_ptr->index % bytes_per_row == 0) {
    638         EFUN_PRINTF(("    %d\n", state_ptr->line_start_index));
    639         state_ptr->line_start_index = state_ptr->index;
    640     }
    641 
    642     return(ERR_CODE_NONE);
    643 }
    644 
    645 err_code_t blackhawk_tsc_INTERNAL_read_event_log_with_callback(srds_access_t *sa__,
    646                                                         uint8_t micro_num,
    647                                                         uint8_t bypass_micro,
    648                                                         void *arg,
    649                                                         err_code_t (*callback)(void *, uint8_t, uint16_t)) {
    650     uint16_t rd_idx;
    651     uint8_t current_lane;
    652     srds_info_t * blackhawk_tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr_with_check(sa__);
    653 
    654 #ifdef PHYMOD_SUPPORT
    655     if ( blackhawk_tsc_info_ptr == NULL ) {
    656         blackhawk_tsc_init_blackhawk_tsc_info(sa__);
    657     } else if (blackhawk_tsc_info_ptr->signature != SRDS_INFO_SIGNATURE) {
    658         blackhawk_tsc_init_blackhawk_tsc_info(sa__);
    659     }
    660 #endif /* PHYMOD_SUPPORT */
    661 
    662     EFUN(blackhawk_tsc_INTERNAL_verify_blackhawk_tsc_info(blackhawk_tsc_info_ptr, sa__));
    663 
    664     if (micro_num >= blackhawk_tsc_info_ptr->micro_count) {
    665         return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    666     }
    667     /* Read Current lane so that it can be restored at the end of function */
    668     current_lane = blackhawk_tsc_get_lane(sa__);
    669     /* Blackhawk has 2 lanes per micro, set lane appropriate for the desired micro */
    670     EFUN(blackhawk_tsc_set_lane(sa__,micro_num<<1));
    671     EFUN_PRINTF(("\n\n********************************************\n"));
    672     EFUN_PRINTF((    "**** SERDES UC TRACE MEMORY DUMP ***********\n"));
    673     EFUN_PRINTF((    "********************************************\n"));
    674 
    675     if (bypass_micro) {
    676         ESTM(rd_idx = rducv_trace_mem_wr_idx());
    677         if (blackhawk_tsc_info_ptr->trace_memory_descending_writes) {
    678             ++rd_idx;
    679             if (rd_idx >= blackhawk_tsc_info_ptr->trace_mem_ram_size) {
    680                 rd_idx = 0;
    681             }
    682         } else {
    683             if (rd_idx == 0) {
    684                 rd_idx = blackhawk_tsc_info_ptr->trace_mem_ram_size;
    685             }
    686             --rd_idx;
    687         }
    688     } else {
    689         /* Start Read to stop uC logging and read the word at last event written by uC */
    690         EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_EVENT_LOG_READ, CMD_EVENT_LOG_READ_START, GRACEFUL_STOP_TIME));
    691         ESTM(rd_idx = rducv_trace_mem_rd_idx());
    692     }
    693     
    694     EFUN_PRINTF(( "\n  DEBUG INFO: trace memory read index = 0x%04x\n", rd_idx));
    695     
    696     EFUN_PRINTF(("  DEBUG INFO: trace memory size = 0x%04x\n\n", blackhawk_tsc_info_ptr->trace_mem_ram_size));
    697 
    698     if (blackhawk_tsc_info_ptr->trace_memory_descending_writes) {
    699         /* Micro writes trace memory using descending addresses.
    700          * So read using ascending addresses using block read
    701          */
    702         EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(sa__,
    703                                                   blackhawk_tsc_info_ptr->trace_mem_ram_base + blackhawk_tsc_info_ptr->grp_ram_size*micro_num,
    704                                                   blackhawk_tsc_info_ptr->trace_mem_ram_size,
    705                                                   rd_idx,
    706                                                   blackhawk_tsc_info_ptr->trace_mem_ram_size,
    707                                                   arg,
    708                                                   callback));
    709     } else {
    710         /* Micro writes trace memory using descending addresses.
    711          * So read using ascending addresses using block read
    712          */
    713         EFUN(blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram_descending(sa__,
    714                                                              blackhawk_tsc_info_ptr->trace_mem_ram_base + blackhawk_tsc_info_ptr->grp_ram_size*micro_num,
    715                                                              blackhawk_tsc_info_ptr->trace_mem_ram_size,
    716                                                              rd_idx,
    717                                                              blackhawk_tsc_info_ptr->trace_mem_ram_size,
    718                                                              arg,
    719                                                              callback));
    720     }
    721 
    722     if (!bypass_micro) {
    723         /* Read Done to resume logging  */
    724         EFUN(blackhawk_tsc_pmd_uc_cmd(sa__, CMD_EVENT_LOG_READ, CMD_EVENT_LOG_READ_DONE, 50));
    725     }
    726     EFUN(blackhawk_tsc_set_lane(sa__,current_lane));
    727     return(ERR_CODE_NONE);
    728 }
    729 
    730 #ifdef TO_FLOATS
    731 /* convert uint32_t to float8 */
    732 float8_t blackhawk_tsc_INTERNAL_int32_to_float8(uint32_t input) {
    733     int8_t cnt;
    734     uint8_t output;
    735     
    736     if(input == 0) {
    737       return(0);
    738     } else if(input == 1) {
    739       return(0xe0);
    740     } else {
    741       cnt = 0;
    742       input = input & 0x7FFFFFFF; /* get rid of MSB which may be lock indicator */
    743       do {
    744         input = input << 1;
    745         cnt++;
    746       } while ((input & 0x80000000) == 0);
    747     
    748       output = (uint8_t)((input & 0x70000000)>>23)+(31 - cnt%32);
    749       return(output);
    750     }
    751 }
    752 #endif
    753 
    754 /* convert float8 to uint32_t */
    755 uint32_t blackhawk_tsc_INTERNAL_float8_to_int32(float8_t input) {
    756     uint32_t x;
    757     if(input == 0) return(0);
    758     x = (input>>5) + 8;
    759     if((input & 0x1F) < 3) {
    760       return(x>>(3-(input & 0x1f)));
    761     } 
    762     return(x<<((input & 0x1F)-3));
    763 }
    764 
    765 /* Convert uint8 to 8-bit gray code */
    766 uint8_t blackhawk_tsc_INTERNAL_uint8_to_gray(uint8_t input) {
    767     return input ^ (input >> 1);
    768 }
    769 
    770 /* Convert 8-bit gray code to uint8 */
    771 uint8_t blackhawk_tsc_INTERNAL_gray_to_uint8(uint8_t input) {
    772     input = input ^ (input >> 4);
    773     input = input ^ (input >> 2);
    774     input = input ^ (input >> 1);
    775     return input;
    776 }
    777 
    778 /* Convert seconds to hr:min:sec */
    779 uint8_t blackhawk_tsc_INTERNAL_seconds_to_displayformat(uint32_t seconds, uint8_t *hrs, uint8_t *mins, uint8_t *secs) {
    780     *hrs    = (seconds / 3600);
    781     seconds = (seconds % 3600);
    782     *mins   = (seconds / 60);
    783     *secs   = (seconds % 60);
    784     return(ERR_CODE_NONE);
    785 }
    786 
    787 /* convert float12 to uint32 */
    788 uint32_t blackhawk_tsc_INTERNAL_float12_to_uint32(uint8_t input, uint8_t multi) {
    789 
    790     return(((uint32_t)input)<<multi);
    791 }
    792 
    793 
    794 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf_main(srds_access_t *sa__, uint8_t val) {
    795     if (val > 31) 
    796     {
    797       return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID));
    798     }
    799     EFUN(WR_RX_PF_CTRL(val));
    800     return(ERR_CODE_NONE); 
    801 }
    802 
    803 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf_main(srds_access_t *sa__, uint8_t *val) {
    804     ESTM(*val = RD_RX_PF_CTRL());
    805     return (ERR_CODE_NONE);
    806 }
    807 
    808 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf2(srds_access_t *sa__, uint8_t val) {
    809     if (val > 7) {
    810       return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID));
    811     }
    812     EFUN(WR_RX_PF2_CTRL(val));
    813     return(ERR_CODE_NONE); 
    814 }
    815 
    816 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf2(srds_access_t *sa__, uint8_t *val) {
    817     ESTM(*val = RD_RX_PF2_CTRL());
    818     return (ERR_CODE_NONE);
    819 }
    820 
    821 err_code_t blackhawk_tsc_INTERNAL_set_rx_pf3(srds_access_t *sa__, uint8_t val) {
    822     if (val > 15) {
    823       return (blackhawk_tsc_error(sa__, ERR_CODE_PF_INVALID));
    824     }
    825     EFUN(wr_ams_rx_pf3_ctrl(blackhawk_tsc_INTERNAL_uint8_to_gray(val)));
    826     return(ERR_CODE_NONE); 
    827 }
    828 
    829 err_code_t blackhawk_tsc_INTERNAL_get_rx_pf3(srds_access_t *sa__, uint8_t *val) {
    830     ESTM(*val = blackhawk_tsc_INTERNAL_gray_to_uint8(rd_ams_rx_pf3_ctrl()));
    831     return (ERR_CODE_NONE);
    832 }
    833 
    834 err_code_t blackhawk_tsc_INTERNAL_set_rx_vga(srds_access_t *sa__, uint8_t val) {
    835 
    836     EFUN(blackhawk_tsc_INTERNAL_check_uc_lane_stopped(sa__));  /* make sure uC is stopped to avoid race conditions */
    837 
    838     if (val > RX_VGA_CTRL_VAL_MAX) {
    839       return (blackhawk_tsc_error(sa__, ERR_CODE_VGA_INVALID));
    840     }
    841 #if defined(RX_VGA_CTRL_VAL_MIN) && (RX_VGA_CTRL_VAL_MIN > 0)
    842     if (val < RX_VGA_CTRL_VAL_MIN) {
    843       return (blackhawk_tsc_error(sa__, ERR_CODE_VGA_INVALID));
    844     } 
    845 #endif
    846     
    847     EFUN(wr_rx_vga_val(val));
    848     return(ERR_CODE_NONE); 
    849 }
    850 
    851 err_code_t blackhawk_tsc_INTERNAL_get_rx_vga(srds_access_t *sa__, uint8_t *val) {
    852     ESTM(*val = rd_rx_vga_status());
    853     return (ERR_CODE_NONE);
    854 }
    855 
    856 
    857 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe1(srds_access_t *sa__, int8_t val) {
    858     enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
    859     EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
    860 
    861     if(pam_mode != NRZ) {
    862         EFUN_PRINTF(("ERROR: RX DFE1 is only available in NRZ mode\n"));
    863         return(ERR_CODE_INVALID_RX_PAM_MODE);
    864     }
    865     EFUN(blackhawk_tsc_INTERNAL_check_uc_lane_stopped(sa__));  /* make sure uC is stopped to avoid race conditions */
    866 
    867     EFUN(wr_rx_afe_override_sel(1));                     /* Select data23 slicer */
    868     EFUN(wr_rx_afe_override_val(val));
    869     EFUN(wr_rx_afe_override_write(1));
    870     return(ERR_CODE_NONE); 
    871 }
    872 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe1(srds_access_t *sa__, int8_t *val) {
    873     {
    874         enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
    875         EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
    876 
    877         if(pam_mode != NRZ) {
    878             EFUN_PRINTF(("ERROR: RX DFE1 is only available in NRZ mode (core %d lane %d)\n",blackhawk_tsc_get_core(sa__),blackhawk_tsc_get_lane(sa__)));
    879             return(ERR_CODE_INVALID_RX_PAM_MODE);
    880         }
    881     }
    882     ESTM(*val = (int8_t)rd_rx_data23_status());
    883     return (ERR_CODE_NONE);
    884 }
    885 
    886 
    887 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe2(srds_access_t *sa__, int8_t val) {
    888     if ((val > 15) || (val < -15)) 
    889     {
    890         USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val));
    891         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    892     }
    893     EFUN(wr_rx_afe_override_sel(6));
    894     EFUN(wr_rxa_dfe_tap2_val(val));
    895     EFUN(wr_rxa_dfe_tap2_write(1));
    896     EFUN(wr_rxb_dfe_tap2_val(val));
    897     EFUN(wr_rxb_dfe_tap2_write(1));
    898     EFUN(wr_rxc_dfe_tap2_val(val));
    899     EFUN(wr_rxc_dfe_tap2_write(1));
    900     EFUN(wr_rxd_dfe_tap2_val(val));
    901     EFUN(wr_rxd_dfe_tap2_write(1));
    902     return(ERR_CODE_NONE); 
    903 }
    904 
    905 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe2(srds_access_t *sa__, int8_t *val) {
    906     ESTM(*val = ((rd_rxa_dfe_tap2_status() + rd_rxb_dfe_tap2_status() + rd_rxc_dfe_tap2_status() + rd_rxd_dfe_tap2_status())>>2));
    907     return (ERR_CODE_NONE);
    908 }
    909 
    910 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe3(srds_access_t *sa__, int8_t val) {
    911     if ((val > 15) || (val < -15))
    912     {
    913         USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val));
    914         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    915     }
    916     EFUN(wr_rx_afe_override_sel(6));
    917     EFUN(wr_rxa_dfe_tap3_val(val));
    918     EFUN(wr_rxa_dfe_tap3_write(1));
    919     EFUN(wr_rxb_dfe_tap3_val(val));
    920     EFUN(wr_rxb_dfe_tap3_write(1));
    921     EFUN(wr_rxc_dfe_tap3_val(val));
    922     EFUN(wr_rxc_dfe_tap3_write(1));
    923     EFUN(wr_rxd_dfe_tap3_val(val));
    924     EFUN(wr_rxd_dfe_tap3_write(1));
    925     return(ERR_CODE_NONE); 
    926 }
    927 
    928 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe3(srds_access_t *sa__, int8_t *val) {
    929     ESTM(*val = (rd_rxa_dfe_tap3_status() + rd_rxb_dfe_tap3_status() + rd_rxc_dfe_tap3_status() + rd_rxd_dfe_tap3_status())>>2);
    930     return (ERR_CODE_NONE);
    931 }
    932 
    933 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe4(srds_access_t *sa__, int8_t val) {
    934     if ((val > 15) || (val < -15))
    935     {
    936         USR_PRINTF(("Exceeded range of DFE tap limit = 15, request %d\n",val));
    937         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    938     }
    939     EFUN(wr_rxa_dfe_tap4(val));
    940     EFUN(wr_rxb_dfe_tap4(val));
    941     EFUN(wr_rxc_dfe_tap4(val));
    942     EFUN(wr_rxd_dfe_tap4(val));
    943     return(ERR_CODE_NONE); 
    944 }
    945 
    946 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe4(srds_access_t *sa__, int8_t *val) {
    947     ESTM(*val = (rd_rxa_dfe_tap4() + rd_rxb_dfe_tap4() + rd_rxc_dfe_tap4() + rd_rxd_dfe_tap4())>>2);
    948     return (ERR_CODE_NONE);
    949 }
    950 
    951 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe5(srds_access_t *sa__, int8_t val) {
    952     if ((val > 7) || (val < -7))
    953     {
    954         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
    955         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    956     }
    957     EFUN(wr_rxa_dfe_tap5(val));
    958     EFUN(wr_rxb_dfe_tap5(val));
    959     EFUN(wr_rxc_dfe_tap5(val));
    960     EFUN(wr_rxd_dfe_tap5(val));
    961     return(ERR_CODE_NONE); 
    962 }
    963 
    964 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe5(srds_access_t *sa__, int8_t *val) {
    965     ESTM(*val = (rd_rxa_dfe_tap5() + rd_rxb_dfe_tap5() + rd_rxc_dfe_tap5() + rd_rxd_dfe_tap5())>>2);
    966     return (ERR_CODE_NONE);
    967 }
    968 
    969 
    970 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe6(srds_access_t *sa__, int8_t val) {
    971     if ((val > 7) || (val < -7))
    972     {
    973         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
    974         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    975     }
    976     EFUN(wr_rxa_dfe_tap6(val));
    977     EFUN(wr_rxb_dfe_tap6(val));
    978     EFUN(wr_rxc_dfe_tap6(val));
    979     EFUN(wr_rxd_dfe_tap6(val));
    980     return(ERR_CODE_NONE); 
    981 }
    982 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe6(srds_access_t *sa__, int8_t *val) {
    983     ESTM(*val = (rd_rxa_dfe_tap6() + rd_rxb_dfe_tap6() + rd_rxc_dfe_tap6() + rd_rxd_dfe_tap6())>>2);
    984     return (ERR_CODE_NONE);
    985 }
    986 
    987 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe7(srds_access_t *sa__, int8_t val) {
    988     if ((val > 7) || (val < -7))
    989     {
    990         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
    991         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
    992     }
    993     EFUN(wr_rxa_dfe_tap7(val));
    994     EFUN(wr_rxb_dfe_tap7(val));
    995     EFUN(wr_rxc_dfe_tap7(val));
    996     EFUN(wr_rxd_dfe_tap7(val));
    997     return(ERR_CODE_NONE); 
    998 }
    999 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe7(srds_access_t *sa__, int8_t *val) {
   1000     ESTM(*val = (rd_rxa_dfe_tap7() + rd_rxb_dfe_tap7() + rd_rxc_dfe_tap7() + rd_rxd_dfe_tap7())>>2);
   1001     return (ERR_CODE_NONE);
   1002 }
   1003 
   1004 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe8(srds_access_t *sa__, int8_t val) {
   1005     if ((val > 7) || (val < -7))
   1006     {
   1007         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1008         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1009     }
   1010     EFUN(wr_rxa_dfe_tap8(val));
   1011     EFUN(wr_rxb_dfe_tap8(val));
   1012     EFUN(wr_rxc_dfe_tap8(val));
   1013     EFUN(wr_rxd_dfe_tap8(val));
   1014     return(ERR_CODE_NONE); 
   1015 }
   1016 
   1017 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe8(srds_access_t *sa__, int8_t *val) {
   1018     ESTM(*val = (rd_rxa_dfe_tap8() + rd_rxb_dfe_tap8() + rd_rxc_dfe_tap8() + rd_rxd_dfe_tap8())>>2);
   1019     return (ERR_CODE_NONE);
   1020 }
   1021 
   1022 
   1023 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe9(srds_access_t *sa__, int8_t val) {
   1024     if ((val > 7) || (val < -7))
   1025     {
   1026         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1027         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1028     }
   1029     EFUN(wr_rxa_dfe_tap9(val));
   1030     EFUN(wr_rxb_dfe_tap9(val));
   1031     EFUN(wr_rxc_dfe_tap9(val));
   1032     EFUN(wr_rxd_dfe_tap9(val));
   1033     return(ERR_CODE_NONE); 
   1034 }
   1035 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe9(srds_access_t *sa__, int8_t *val) {
   1036     ESTM(*val = (rd_rxa_dfe_tap9() + rd_rxb_dfe_tap9() + rd_rxc_dfe_tap9() + rd_rxd_dfe_tap9())>>2);
   1037     return (ERR_CODE_NONE);
   1038 }
   1039 
   1040 
   1041 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe10(srds_access_t *sa__, int8_t val) {
   1042     if ((val > 7) || (val < -7))
   1043     {
   1044         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1045         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1046     }
   1047     EFUN(wr_rxa_dfe_tap10(val));
   1048     EFUN(wr_rxb_dfe_tap10(val));
   1049     EFUN(wr_rxc_dfe_tap10(val));
   1050     EFUN(wr_rxd_dfe_tap10(val));
   1051     return(ERR_CODE_NONE); 
   1052 }
   1053 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe10(srds_access_t *sa__, int8_t *val) {
   1054     ESTM(*val = (rd_rxa_dfe_tap10() + rd_rxb_dfe_tap10() + rd_rxc_dfe_tap10() + rd_rxd_dfe_tap10())>>2);
   1055     return (ERR_CODE_NONE);
   1056 }
   1057 
   1058 
   1059 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe11(srds_access_t *sa__, int8_t val) {
   1060     if ((val > 7) || (val < -7))
   1061     {
   1062         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1063         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1064     }
   1065     EFUN(wr_rxa_dfe_tap11(val));
   1066     EFUN(wr_rxb_dfe_tap11(val));
   1067     EFUN(wr_rxc_dfe_tap11(val));
   1068     EFUN(wr_rxd_dfe_tap11(val));
   1069     return(ERR_CODE_NONE); 
   1070 }
   1071 
   1072 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe11(srds_access_t *sa__, int8_t *val) {
   1073     ESTM(*val = (rd_rxa_dfe_tap11() + rd_rxb_dfe_tap11() + rd_rxc_dfe_tap11() + rd_rxd_dfe_tap11())>>2);
   1074     return (ERR_CODE_NONE);
   1075 }
   1076 
   1077 
   1078 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe12(srds_access_t *sa__, int8_t val) {
   1079     if ((val > 7) || (val < -7))
   1080     {
   1081         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1082         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1083     }
   1084     EFUN(wr_rxa_dfe_tap12(val));
   1085     EFUN(wr_rxb_dfe_tap12(val));
   1086     EFUN(wr_rxc_dfe_tap12(val));
   1087     EFUN(wr_rxd_dfe_tap12(val));
   1088     return(ERR_CODE_NONE); 
   1089 }
   1090 
   1091 
   1092 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe12(srds_access_t *sa__, int8_t *val) {
   1093     ESTM(*val = (rd_rxa_dfe_tap12() + rd_rxb_dfe_tap12() + rd_rxc_dfe_tap12() + rd_rxd_dfe_tap12())>>2);
   1094     return (ERR_CODE_NONE);
   1095 }
   1096 
   1097 
   1098 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe13(srds_access_t *sa__, int8_t val) {
   1099     if ((val > 7) || (val < -7))
   1100     {
   1101         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1102         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1103     }
   1104     EFUN(wr_rxa_dfe_tap13(val));
   1105     EFUN(wr_rxb_dfe_tap13(val));
   1106     EFUN(wr_rxc_dfe_tap13(val));
   1107     EFUN(wr_rxd_dfe_tap13(val));
   1108     return(ERR_CODE_NONE); 
   1109 }
   1110 
   1111 
   1112 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe13(srds_access_t *sa__, int8_t *val) {
   1113     ESTM(*val = (rd_rxa_dfe_tap13() + rd_rxb_dfe_tap13() + rd_rxc_dfe_tap13() + rd_rxd_dfe_tap13())>>2);
   1114     return (ERR_CODE_NONE);
   1115 }
   1116 
   1117 
   1118 err_code_t blackhawk_tsc_INTERNAL_set_rx_dfe14(srds_access_t *sa__, int8_t val) {
   1119 
   1120     if ((val > 7) || (val < -7))
   1121     {
   1122         USR_PRINTF(("Exceeded range of DFE tap limit = 7, request %d\n",val));
   1123         return (blackhawk_tsc_error(sa__, ERR_CODE_DFE_TAP));  
   1124     }
   1125     EFUN(wr_rxa_dfe_tap14(val));
   1126     EFUN(wr_rxb_dfe_tap14(val));
   1127     EFUN(wr_rxc_dfe_tap14(val));
   1128     EFUN(wr_rxd_dfe_tap14(val));
   1129     return(ERR_CODE_NONE); 
   1130 }
   1131 
   1132 
   1133 err_code_t blackhawk_tsc_INTERNAL_get_rx_dfe14(srds_access_t *sa__, int8_t *val) {
   1134     ESTM(*val = (rd_rxa_dfe_tap14() + rd_rxb_dfe_tap14() + rd_rxc_dfe_tap14() + rd_rxd_dfe_tap14())>>2);
   1135     return (ERR_CODE_NONE);
   1136 }
   1137 
   1138 err_code_t blackhawk_tsc_INTERNAL_ip_version_check(srds_access_t *sa__, uint8_t *i_am_b0) {
   1139         uint8_t ams_tx_version_id = 0;
   1140 
   1141 
   1142         ESTM(ams_tx_version_id = rd_ams_tx_version_id());
   1143         *i_am_b0 = ams_tx_version_id == 0xC0;
   1144 
   1145     return ERR_CODE_NONE;
   1146 }
   1147 
   1148 
   1149 
   1150 err_code_t blackhawk_tsc_INTERNAL_load_txfir_taps(srds_access_t *sa__){
   1151   EFUN(wr_txfir_tap_load(1));  /* Load the tap coefficients into TXFIR. */
   1152 
   1153   return(ERR_CODE_NONE); 
   1154 }
   1155 
   1156 err_code_t blackhawk_tsc_INTERNAL_set_tx_tap(srds_access_t *sa__, uint8_t tap_num, int16_t val) {
   1157 
   1158 
   1159     switch (tap_num) {
   1160     case  0: EFUN(wr_txfir_tap0_coeff (val)); break;
   1161     case  1: EFUN(wr_txfir_tap1_coeff (val)); break;
   1162     case  2: EFUN(wr_txfir_tap2_coeff (val)); break;
   1163     case  3: EFUN(wr_txfir_tap3_coeff (val)); break;
   1164     case  4: EFUN(wr_txfir_tap4_coeff (val)); break;
   1165     case  5: EFUN(wr_txfir_tap5_coeff (val)); break;
   1166     case  6: EFUN(wr_txfir_tap6_coeff ((uint8_t)val)); break;
   1167     case  7: EFUN(wr_txfir_tap7_coeff ((uint8_t)val)); break;
   1168     case  8: EFUN(wr_txfir_tap8_coeff ((uint8_t)val)); break;
   1169     case  9: EFUN(wr_txfir_tap9_coeff ((uint8_t)val)); break;
   1170     case 10: EFUN(wr_txfir_tap10_coeff((uint8_t)val)); break;
   1171     case 11: EFUN(wr_txfir_tap11_coeff((uint8_t)val)); break;
   1172     default:
   1173         return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1174     }
   1175 
   1176     return(ERR_CODE_NONE);
   1177 }
   1178 
   1179 err_code_t blackhawk_tsc_INTERNAL_get_tx_tap(srds_access_t *sa__, uint8_t tap_num, int16_t *val) {
   1180 
   1181     switch (tap_num) {
   1182     case  0: ESTM(*val = rd_txfir_tap0_coeff ()); break;
   1183     case  1: ESTM(*val = rd_txfir_tap1_coeff ()); break;
   1184     case  2: ESTM(*val = rd_txfir_tap2_coeff ()); break;
   1185     case  3: ESTM(*val = rd_txfir_tap3_coeff ()); break;
   1186     case  4: ESTM(*val = rd_txfir_tap4_coeff ()); break;
   1187     case  5: ESTM(*val = rd_txfir_tap5_coeff ()); break;
   1188     case  6: ESTM(*val = rd_txfir_tap6_coeff ()); break;
   1189     case  7: ESTM(*val = rd_txfir_tap7_coeff ()); break;
   1190     case  8: ESTM(*val = rd_txfir_tap8_coeff ()); break;
   1191     case  9: ESTM(*val = rd_txfir_tap9_coeff ()); break;
   1192     case 10: ESTM(*val = rd_txfir_tap10_coeff()); break;
   1193     case 11: ESTM(*val = rd_txfir_tap11_coeff()); break;
   1194     default:
   1195         return (blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1196     }
   1197 
   1198 
   1199     return(ERR_CODE_NONE);
   1200 }
   1201 
   1202 
   1203 
   1204 
   1205 err_code_t blackhawk_tsc_INTERNAL_core_clkgate(srds_access_t *sa__, uint8_t enable) {
   1206   UNUSED(sa__);
   1207 
   1208   if (enable) {
   1209   }
   1210   else {
   1211   }
   1212   return (ERR_CODE_NONE);
   1213 }
   1214 
   1215 err_code_t blackhawk_tsc_INTERNAL_lane_clkgate(srds_access_t *sa__, uint8_t enable) {
   1216 
   1217   if (enable) {
   1218     /* Use frc/frc_val to force all RX and TX clk_vld signals to 0 */
   1219         EFUN(wr_pmd_rx_clk_vld_frc_val(0x0));
   1220         EFUN(wr_pmd_rx_clk_vld_frc(0x1));
   1221         EFUN(wr_pmd_tx_clk_vld_frc_val(0x0));
   1222         EFUN(wr_pmd_tx_clk_vld_frc(0x1));
   1223 
   1224     /* Use frc_on to force clkgate */
   1225         EFUN(wr_ln_rx_s_clkgate_frc_on(0x1));
   1226 
   1227         EFUN(wr_ln_tx_s_clkgate_frc_on(0x1));
   1228 
   1229   }
   1230   else {
   1231         EFUN(wr_pmd_rx_clk_vld_frc_val(0x0));
   1232         EFUN(wr_pmd_rx_clk_vld_frc(0x0));
   1233         EFUN(wr_pmd_tx_clk_vld_frc_val(0x0));
   1234         EFUN(wr_pmd_tx_clk_vld_frc(0x0));
   1235 
   1236         EFUN(wr_ln_rx_s_clkgate_frc_on(0x0));
   1237 
   1238         EFUN(wr_ln_tx_s_clkgate_frc_on(0x0));
   1239   }
   1240   return (ERR_CODE_NONE);
   1241 }
   1242 
   1243 /*-----------------------------------------------*/
   1244 /*  Get dynamic eye margin estimation values     */
   1245 /*-----------------------------------------------*/
   1246 err_code_t blackhawk_tsc_INTERNAL_get_eye_margin_est(srds_access_t *sa__, uint16_t *left_eye_mUI, uint16_t *right_eye_mUI, uint16_t  *upper_eye_mV, uint16_t *lower_eye_mV) {
   1247   uint8_t ladder_range = 0;
   1248   ESTM(*left_eye_mUI  = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_heye_left()));
   1249   ESTM(*right_eye_mUI = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_heye_right()));
   1250   ESTM(*upper_eye_mV = blackhawk_tsc_INTERNAL_eye_to_mV(sa__, rdv_usr_sts_veye_upper(), ladder_range));
   1251   ESTM(*lower_eye_mV = blackhawk_tsc_INTERNAL_eye_to_mV(sa__, rdv_usr_sts_veye_lower(), ladder_range));
   1252 
   1253   return (ERR_CODE_NONE);
   1254 }
   1255 
   1256 /*----------------------------------------------------*/
   1257 /*  Get dynamic eye margin estimation values (PAM)    */
   1258 /*----------------------------------------------------*/
   1259 err_code_t blackhawk_tsc_INTERNAL_get_pam_eye_margin_est(srds_access_t *sa__, eye_margin_t *eye_margin) {
   1260   uint8_t ladder_range = 0;
   1261   uint8_t i;
   1262   for(i=0; i<NUM_PAM_EYES; i++) {
   1263       ESTM(eye_margin->left_eye_mUI [i] = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__,  rdv_usr_sts_pam_heye_left(i)));
   1264       ESTM(eye_margin->right_eye_mUI[i] = blackhawk_tsc_INTERNAL_eye_to_mUI(sa__, rdv_usr_sts_pam_heye_right(i)));
   1265       ESTM(eye_margin->upper_eye_mV [i] = blackhawk_tsc_INTERNAL_eye_to_mV (sa__, rdv_usr_sts_pam_veye_upper(i), ladder_range));
   1266       ESTM(eye_margin->lower_eye_mV [i] = blackhawk_tsc_INTERNAL_eye_to_mV (sa__, rdv_usr_sts_pam_veye_lower(i), ladder_range));
   1267   }
   1268   return (ERR_CODE_NONE);
   1269 }
   1270 
   1271 /*------------------------------------------------------*/
   1272 /*  Print dynamic eye margin estimation values (PAM)    */
   1273 /*------------------------------------------------------*/
   1274 err_code_t blackhawk_tsc_display_pam_eye_margin_est(srds_access_t *sa__) {
   1275   int8_t i;
   1276   eye_margin_t eye_margin;
   1277 
   1278   ESTM(blackhawk_tsc_INTERNAL_get_pam_eye_margin_est(sa__, &eye_margin));
   1279 
   1280   EFUN_PRINTF(("Eye margin: L(mUI),R(mUI),U(mV),D(mV)\n"));
   1281   for(i=NUM_PAM_EYES-1; i>=0; i--) {
   1282       EFUN_PRINTF(("%s eye: ", i==2?"Upper ":i==1?"Middle":"Lower "));
   1283       EFUN_PRINTF(("%6d,%6d,%5d,%5d\n", eye_margin.left_eye_mUI[i], eye_margin.right_eye_mUI[i], eye_margin.upper_eye_mV[i], eye_margin.lower_eye_mV[i]));
   1284   }
   1285   return (ERR_CODE_NONE);
   1286 }
   1287 
   1288 uint16_t blackhawk_tsc_INTERNAL_eye_to_mUI(srds_access_t *sa__, uint8_t var) 
   1289 {   
   1290     UNUSED(sa__);
   1291     /* var is in units of 1/512 th UI, so need to multiply by 1000/512 */
   1292     return ((uint16_t)var)*125/64;
   1293 }
   1294 
   1295 
   1296 uint16_t blackhawk_tsc_INTERNAL_eye_to_mV(srds_access_t *sa__, uint8_t var, uint8_t ladder_range) 
   1297 {       
   1298     /* find nearest two vertical levels */
   1299     uint16_t vl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, var, ladder_range);    
   1300     return (vl);
   1301 }
   1302 
   1303 err_code_t blackhawk_tsc_INTERNAL_get_osr_mode(srds_access_t *sa__, blackhawk_tsc_osr_mode_st *imode) {
   1304     blackhawk_tsc_osr_mode_st mode;
   1305 
   1306      ENULL_MEMSET(&mode, 0, sizeof(blackhawk_tsc_osr_mode_st));
   1307 
   1308     if(!imode) 
   1309         return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1310 
   1311   ESTM(mode.tx = rd_tx_osr_mode());
   1312   ESTM(mode.rx = rd_rx_osr_mode());
   1313   mode.tx_rx = 255;
   1314 #ifdef wr_ams_rx_rxclk_div2p5    /* Analog 2p5 OSR mode */
   1315   {
   1316       uint8_t osr_2p5, osr_2p5_pwrup;
   1317       ESTM(osr_2p5       = rd_ams_tx_txclk_div2p5());
   1318       ESTM(osr_2p5_pwrup = rd_ams_tx_txclk_div2p5_pwrup());
   1319       if ((mode.tx == BLACKHAWK_TSC_OSX1) && (osr_2p5 == 1)  && (osr_2p5_pwrup == 1)) {
   1320           mode.tx = BLACKHAWK_TSC_OSX2P5;
   1321       }
   1322       ESTM(osr_2p5       = rd_ams_rx_rxclk_div2p5());
   1323       ESTM(osr_2p5_pwrup = rd_ams_rx_rxclk_div2p5_pwrup());
   1324       if ((mode.rx == BLACKHAWK_TSC_OSX1) && (osr_2p5 == 1)  && (osr_2p5_pwrup == 1)) {
   1325           mode.rx = BLACKHAWK_TSC_OSX2P5;
   1326       }
   1327   }
   1328 #endif
   1329   *imode = mode;
   1330   return (ERR_CODE_NONE);
   1331 
   1332 }
   1333 
   1334 err_code_t blackhawk_tsc_INTERNAL_get_rx_pam_mode(srds_access_t *sa__, enum blackhawk_tsc_rx_pam_mode_enum *pmode) {
   1335     uint8_t rx_pam4_mode, rx_pam4_es_mode;
   1336 
   1337     ESTM(rx_pam4_mode    = rd_rx_pam4_mode());
   1338     ESTM(rx_pam4_es_mode = rd_rx_pam4_er_mode());
   1339     if (rx_pam4_mode == 0) {
   1340         *pmode = NRZ;
   1341     }
   1342     else if (rx_pam4_mode == 1) {
   1343         *pmode = (rx_pam4_es_mode) ? PAM4_ES : PAM4_NS;
   1344     }
   1345     else {
   1346         return(blackhawk_tsc_error(sa__, ERR_CODE_INVALID_RX_PAM_MODE));
   1347     }
   1348 
   1349   return (ERR_CODE_NONE);
   1350 }
   1351 
   1352 err_code_t blackhawk_tsc_INTERNAL_decode_br_os_mode(srds_access_t *sa__, uint8_t *br_pd_en){
   1353     enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
   1354     uint8_t os_pattern_enhanced=0, os_all_edges=0;
   1355 
   1356     ESTM(os_pattern_enhanced = rd_os_pattern_enhanced());
   1357     ESTM(os_all_edges = rd_os_all_edges());
   1358     EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
   1359     if(pam_mode == NRZ) {
   1360         ESTM(*br_pd_en = rd_br_pd_en());
   1361     } else {
   1362         *br_pd_en = (uint8_t)(!((!os_pattern_enhanced) & os_all_edges));
   1363     }
   1364     return (ERR_CODE_NONE);
   1365 }
   1366 
   1367 err_code_t blackhawk_tsc_INTERNAL_pmd_lock_status(srds_access_t *sa__, uint8_t *pmd_lock, uint8_t *pmd_lock_chg) {
   1368     uint16_t rddata;
   1369 #if defined(reg_rd_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS)
   1370     ESTM(rddata = reg_rd_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS());
   1371     ESTM(*pmd_lock = ex_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock(rddata));
   1372     ESTM(*pmd_lock_chg = ex_TLB_RX_RXDBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock_change(rddata));
   1373 #elif defined(reg_rd_TLB_RX_DBG_PMD_RX_LOCK_STATUS)
   1374     ESTM(rddata = reg_rd_TLB_RX_DBG_PMD_RX_LOCK_STATUS());
   1375     ESTM(*pmd_lock = ex_TLB_RX_DBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock(rddata));
   1376     ESTM(*pmd_lock_chg = ex_TLB_RX_DBG_PMD_RX_LOCK_STATUS__dbg_pmd_rx_lock_change(rddata));
   1377 #else
   1378 #error "Unknown core for blackhawk_tsc_INTERNAL_pmd_lock_status()"    
   1379 #endif
   1380     return(ERR_CODE_NONE);
   1381 }
   1382 
   1383 err_code_t blackhawk_tsc_INTERNAL_sigdet_status(srds_access_t *sa__, uint8_t *sig_det, uint8_t *sig_det_chg) {
   1384     uint16_t rddata;
   1385 
   1386     ESTM(rddata = reg_rd_SIGDET_SDSTATUS_0());
   1387     ESTM(*sig_det = ex_SIGDET_SDSTATUS_0__signal_detect(rddata));
   1388     ESTM(*sig_det_chg = ex_SIGDET_SDSTATUS_0__signal_detect_change(rddata));
   1389     return(ERR_CODE_NONE);
   1390 }
   1391 
   1392 err_code_t blackhawk_tsc_INTERNAL_pll_lock_status(srds_access_t *sa__, uint8_t *pll_lock, uint8_t *pll_lock_chg) {
   1393 
   1394     uint16_t rddata;
   1395     ESTM(rddata = reg_rdc_PLL_CAL_COM_CTL_STATUS_0());
   1396     ESTM(*pll_lock = exc_PLL_CAL_COM_CTL_STATUS_0__pll_lock(rddata));
   1397     ESTM(*pll_lock_chg = exc_PLL_CAL_COM_CTL_STATUS_0__pll_lock_lh_ll(rddata));
   1398     return(ERR_CODE_NONE);
   1399 }
   1400 
   1401 err_code_t blackhawk_tsc_INTERNAL_read_lane_state(srds_access_t *sa__, blackhawk_tsc_lane_state_st *istate) {
   1402        
   1403   blackhawk_tsc_lane_state_st state;
   1404 
   1405   ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_lane_state_st));
   1406 
   1407   if(!istate) 
   1408     return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1409 
   1410   EFUN(blackhawk_tsc_INTERNAL_pmd_lock_status(sa__,&state.rx_lock, &state.rx_lock_chg));
   1411   {
   1412       err_code_t err_code = 0;
   1413       state.stop_state = blackhawk_tsc_INTERNAL_stop_micro(sa__,state.rx_lock,&err_code);
   1414       if(err_code) USR_PRINTF(("WARNING: Unable to stop microcontroller,  following data is suspect\n"));
   1415   }
   1416 
   1417   {  blackhawk_tsc_osr_mode_st osr_mode;
   1418   ENULL_MEMSET(&osr_mode, 0, sizeof(blackhawk_tsc_osr_mode_st));
   1419   EFUN(blackhawk_tsc_INTERNAL_get_osr_mode(sa__, &osr_mode));
   1420   state.osr_mode = osr_mode;
   1421   }
   1422   {
   1423      enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
   1424      EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
   1425      state.rx_pam_mode = (uint8_t)pam_mode;
   1426   }
   1427   {
   1428       struct blackhawk_tsc_uc_lane_config_st lane_cfg;
   1429       EFUN(blackhawk_tsc_get_uc_lane_cfg(sa__, &lane_cfg));
   1430       state.ucv_config = lane_cfg.word;
   1431   }
   1432   ESTM(state.ucv_status = rdv_status_byte());
   1433   ESTM(state.reset_state    = rd_rx_lane_dp_reset_state());
   1434   ESTM(state.tx_reset_state = rd_tx_lane_dp_reset_state());
   1435   ESTM(state.tx_pll_select = rd_tx_pll_select());
   1436   ESTM(state.rx_pll_select = rd_rx_pll_select());
   1437   EFUN(blackhawk_tsc_INTERNAL_sigdet_status(sa__,&state.sig_det, &state.sig_det_chg));
   1438   ESTM(state.rx_ppm = rd_cdr_integ_reg()/84);
   1439   {
   1440       int8_t reg_data;
   1441       ESTM(reg_data = rdv_usr_sts_phase_hoffset());
   1442       state.clk90 = reg_data;
   1443   }
   1444   EFUN(blackhawk_tsc_INTERNAL_decode_br_os_mode(sa__, &state.br_pd_en));
   1445   /* drop the MSB, the result is actually valid modulo 128 */
   1446   /* Also flip the sign to account for d-m1, versus m1-d */
   1447   
   1448   EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF, &state.pf_main));
   1449   state.pf_hiz = 0;
   1450   EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF2, &state.pf2_ctrl));
   1451   EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_PF3, &state.pf3_ctrl));
   1452   ESTM(state.bwr_ctrl = rdv_afe_bw_adjust());
   1453   EFUN(blackhawk_tsc_read_rx_afe(sa__, RX_AFE_VGA, &state.vga));
   1454 
   1455   ESTM(state.dc_offset = rd_dc_offset_bin());
   1456   ESTM(state.p1_lvl = rdv_usr_main_tap_est()/32);
   1457   state.p1_lvl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)state.p1_lvl, 0);
   1458   if (state.rx_pam_mode == NRZ) {
   1459       ESTM(state.m1_lvl = rd_rx_phase02_status());
   1460       state.m1_lvl = blackhawk_tsc_INTERNAL_ladder_setting_to_mV(sa__, (int8_t)state.m1_lvl, 0);
   1461       state.usr_status_eq_debug1 = 0;
   1462       state.afe_bw = 0;
   1463   }
   1464   else {
   1465       ESTM(state.m1_lvl = rdv_usr_ctrl_pam4_chn_loss());
   1466 
   1467       ESTM(state.usr_status_eq_debug1 = rdv_usr_status_eq_debug1());
   1468       {
   1469           uint16_t ucode_version_major;
   1470           uint8_t ucode_version_minor;
   1471           /*Extracting the major version number*/
   1472           ESTM(ucode_version_major = rdcv_common_ucode_version() & 0xFFF);
   1473           ESTM(ucode_version_minor = rdcv_common_ucode_minor_version());
   1474           if ((ucode_version_major == 0x2) && (ucode_version_minor >= 0x3) && (ucode_version_minor < 0x8)) {
   1475               uint8_t afe_bw_dbg0, afe_bw_dbg1;
   1476               uint8_t afe_bw[4] = {1, 2, 0, 3};
   1477               ESTM(afe_bw_dbg0 = rdv_afe_bw_dbg_0());
   1478               ESTM(afe_bw_dbg1 = rdv_afe_bw_dbg_1());
   1479 
   1480               afe_bw_dbg0 &= 0x01;
   1481               afe_bw_dbg1 &= 0x01;
   1482               state.afe_bw = afe_bw[((afe_bw_dbg0 << 1) | afe_bw_dbg1)];
   1483           } else if (((ucode_version_major == 0x2) && (ucode_version_minor >= 0x8)) || (ucode_version_major > 0x2)) {
   1484               /*tag D002_08 has the changes to afe_bw calculation along with trunk before branching for tag D002_08*/
   1485               ESTM(state.afe_bw = rdv_afe_bw_dbg_0());
   1486           } else {
   1487               state.afe_bw = 0xFF; /* assign to a invalid value. */
   1488           }
   1489       }
   1490   }
   1491 
   1492   ESTM(state.blind_ctle_ctrl = rdv_usr_status_eq_debug3());
   1493   ESTM(state.blind_ctle_trnsum = rdv_usr_status_eq_debug14());
   1494   if ((state.blind_ctle_ctrl == 0) && (state.blind_ctle_trnsum < 0)) {
   1495       state.afe_bw_metric = state.blind_ctle_trnsum;
   1496   } else {
   1497       state.afe_bw_metric = state.blind_ctle_ctrl;
   1498   } 
   1499   ESTM(state.tp_metric_prec1 = rdv_usr_status_tp_metric_1());
   1500 
   1501   if (state.rx_pam_mode == NRZ) {
   1502       EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe1(sa__, &state.dfe1));
   1503   }
   1504   EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe2(sa__, &state.dfe2));  
   1505   EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe3(sa__, &state.dfe3));  
   1506   EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe4(sa__, &state.dfe4));
   1507   EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe5(sa__, &state.dfe5));
   1508 
   1509   EFUN(blackhawk_tsc_INTERNAL_get_rx_dfe6(sa__, &state.dfe6));
   1510 
   1511   /* tx_ppm = register/10.84 */
   1512   ESTM(state.tx_ppm = (int16_t)(((int32_t)(rd_tx_pi_integ2_reg()))*3125/32768));
   1513 
   1514   ESTM(state.tx_prec_en = rd_pam4_precoder_en());
   1515   ESTM(state.linktrn_en = rd_linktrn_ieee_training_enable());
   1516   ESTM(state.txfir_use_pam4_range = rd_txfir_nrz_tap_range_sel() ? 0 : 1);
   1517   {
   1518       uint8_t tap_num;
   1519       for (tap_num=0; tap_num<12; ++tap_num) {
   1520           EFUN(blackhawk_tsc_INTERNAL_get_tx_tap(sa__, tap_num, &state.txfir.tap[tap_num]));
   1521       }
   1522   }
   1523   EFUN(blackhawk_tsc_INTERNAL_get_eye_margin_est(sa__, &state.heye_left, &state.heye_right, &state.veye_upper, &state.veye_lower));
   1524  
   1525   ESTM(state.link_time = (((uint32_t)rdv_usr_sts_link_time())*8)/10);     /* convert from 80us to 0.1 ms units */
   1526   {
   1527       /* read lock status at end and combine them to handle transient cases */
   1528       uint8_t rx_lock_at_end=0, rx_lock_chg_at_end=0;
   1529       EFUN(blackhawk_tsc_INTERNAL_pmd_lock_status(sa__,&rx_lock_at_end, &rx_lock_chg_at_end));
   1530       if (state.rx_lock != rx_lock_at_end) {
   1531           USR_PRINTF(("rx_lock has changed while reading the lane state rx_lock_start=%d, rx_lock_chg_start=%d, rx_lock_at_end=%d, rx_lock_chg_at_end=%d\n",
   1532                       state.rx_lock,
   1533                       state.rx_lock_chg,
   1534                       rx_lock_at_end,
   1535                       rx_lock_chg_at_end));
   1536       }
   1537       state.rx_lock &= rx_lock_at_end;
   1538       state.rx_lock_chg |= rx_lock_chg_at_end;
   1539   }
   1540 
   1541   if (!state.stop_state || (state.stop_state == 0xFF)) {
   1542       /* manually check error code instead of EFUN*/
   1543       {
   1544           err_code_t resume_status = ERR_CODE_NONE;
   1545           resume_status = blackhawk_tsc_stop_rx_adaptation(sa__, 0);
   1546           if (resume_status) {
   1547               USR_PRINTF(("WARNING: Resuming micro after lane state capture failed \n"));
   1548           }
   1549       }
   1550   } 
   1551 
   1552   *istate = state;
   1553 
   1554 
   1555   return (ERR_CODE_NONE);
   1556 }
   1557 
   1558 err_code_t blackhawk_tsc_INTERNAL_display_lane_state_no_newline(srds_access_t *sa__) {     
   1559   uint16_t lane_idx;
   1560   blackhawk_tsc_lane_state_st state;
   1561 
   1562   const char* e2s_osr_mode_enum[14] = {
   1563     "x1   ",
   1564     "x2   ",
   1565     "x4   ",
   1566     "ERR  ",
   1567     "x21.2",
   1568     "x8   ",
   1569     "ERR  ",
   1570     "ERR  ",
   1571     "x16.5",
   1572     "x16  ",
   1573     "ERR  ",
   1574     "ERR  ",
   1575     "x20.6",
   1576     "x32  "
   1577   };
   1578 
   1579   const char* e2s_tx_osr_mode_enum[14] = {
   1580     "x1",
   1581     "x2",
   1582     "x4",
   1583     "ER",
   1584     "xL",
   1585     "x8",
   1586     "ER",
   1587     "ER",
   1588     "xH",
   1589     "xG",
   1590     "ER",
   1591     "ER",
   1592     "xK",
   1593     "xW"
   1594   }; 
   1595 
   1596   const char* e2s_rx_pam_mode_enum[3] = {
   1597     "NRZ",
   1598     "P4N",
   1599     "P4E"
   1600   };  
   1601 
   1602 
   1603   ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_lane_state_st));
   1604 
   1605   EFUN(blackhawk_tsc_INTERNAL_read_lane_state(sa__, &state));
   1606  
   1607   lane_idx = blackhawk_tsc_get_lane(sa__); 
   1608   EFUN_PRINTF(("%2d ", lane_idx));
   1609   if(state.osr_mode.tx_rx != 255) {
   1610       char *s;
   1611       s = (char *)e2s_osr_mode_enum[state.osr_mode.tx_rx];
   1612       EFUN_PRINTF(("(%2s%s, 0x%04x, 0x%02x ,", (state.br_pd_en) ? "BR" : "OS", s, state.ucv_config,state.ucv_status));
   1613   } else {
   1614       char *s;
   1615       char *r;
   1616       s = (char *)e2s_tx_osr_mode_enum[state.osr_mode.tx];
   1617       r = (char *)e2s_tx_osr_mode_enum[state.osr_mode.rx];
   1618       {
   1619           char *t;
   1620           uint8_t tx, rx;
   1621           t = (char *)e2s_rx_pam_mode_enum[state.rx_pam_mode];
   1622           ESTM(tx = rd_tx_pam4_mode()); 
   1623           ESTM(rx = rd_rx_pam4_mode());
   1624           EFUN_PRINTF(("(%3s%s,%2s%s:%s, 0x%04x, 0x%02x ,", t,(tx == rx) ? " ": "~", (state.br_pd_en) ? "BR" : "OS", s,r, state.ucv_config,state.ucv_status));
   1625       }
   1626   }
   1627   EFUN_PRINTF(("   %01x,%01x,    %01x, %1d,%1d)",state.tx_reset_state,state.reset_state,state.stop_state,state.tx_pll_select,state.rx_pll_select));
   1628   EFUN_PRINTF(("  %1d%s", state.sig_det, state.sig_det_chg ? "*" : " "));
   1629   EFUN_PRINTF(("  %1d%s", state.rx_lock, state.rx_lock_chg ? "*" : " "));
   1630   EFUN_PRINTF(("%4d ", state.rx_ppm));
   1631   EFUN_PRINTF(("  %3d ", state.clk90));
   1632   EFUN_PRINTF((" %2d,%1d,%2d,%2d", state.pf_main, state.pf2_ctrl, state.pf3_ctrl, state.bwr_ctrl));
   1633   EFUN_PRINTF(("  %2d ", state.vga));
   1634   EFUN_PRINTF(("%3d  ", state.dc_offset));
   1635   EFUN_PRINTF(("%3d ", state.p1_lvl));
   1636   if (state.afe_bw == 0xFF) {
   1637       /* afe_bw calculation is not supported in this microcode version and so invalid value 0xFF*/
   1638       EFUN_PRINTF(("(%4d,%+5d, x,%3d,%3d)", 
   1639                 state.m1_lvl, /* pam4 _chn_loss */
   1640                 state.afe_bw_metric,
   1641                 state.usr_status_eq_debug1,
   1642                 state.tp_metric_prec1));
   1643   } else {
   1644       EFUN_PRINTF(("(%4d,%+5d,%2d,%3d,%3d)", 
   1645                 state.m1_lvl, /* pam4 _chn_loss */
   1646                 state.afe_bw_metric,
   1647                 state.afe_bw,
   1648                 state.usr_status_eq_debug1,
   1649                 state.tp_metric_prec1));
   1650   }
   1651   if (state.rx_pam_mode == NRZ) {
   1652       EFUN_PRINTF(("%3d,%3d,%3d,%3d,%3d,%3d", state.dfe1, state.dfe2, state.dfe3, state.dfe4, state.dfe5, state.dfe6));
   1653   }
   1654   else {
   1655       EFUN_PRINTF((" x ,%3d,%3d,%3d,%3d,%3d", state.dfe2, state.dfe3, state.dfe4, state.dfe5, state.dfe6));
   1656   }
   1657   EFUN_PRINTF(("  %4d ", state.tx_ppm));
   1658   {
   1659       uint8_t enable_6taps;
   1660       if (state.tx_prec_en) {
   1661           EFUN_PRINTF((" P"));
   1662       }
   1663       else {
   1664           EFUN_PRINTF(("  "));
   1665       }
   1666       if(state.linktrn_en) {
   1667           EFUN_PRINTF(("T"));
   1668       }
   1669       else {
   1670           EFUN_PRINTF((" "));
   1671       }
   1672       ESTM(enable_6taps = rd_txfir_tap_en());
   1673       if (!enable_6taps) {
   1674           EFUN_PRINTF((" x ,%3d,%3d,%3d, x , x  ", state.txfir.tap[0], state.txfir.tap[1], state.txfir.tap[2]));
   1675       }
   1676       else {
   1677           EFUN_PRINTF(("%3d,%3d,%3d,%3d,%3d,%3d ",
   1678                        state.txfir.tap[0], state.txfir.tap[1], state.txfir.tap[2],
   1679                        state.txfir.tap[3], state.txfir.tap[4], state.txfir.tap[5]));
   1680       }
   1681   }
   1682   EFUN_PRINTF((" %3d,%3d,%3d,%3d ", state.heye_left, state.heye_right, state.veye_upper, state.veye_lower));
   1683   /* Check to see if link_time is max value after 80us to 0.1msec unit conversion */
   1684   if (state.link_time == 0xCCCC) {
   1685       EFUN_PRINTF((" >%4d.%01d", state.link_time/10, state.link_time%10));
   1686       EFUN_PRINTF(("  "));  
   1687   } else {
   1688       EFUN_PRINTF((" %4d.%01d", state.link_time/10, state.link_time%10));
   1689       EFUN_PRINTF(("   "));  
   1690   }
   1691   EFUN(blackhawk_tsc_INTERNAL_display_BER(sa__,100));
   1692 
   1693   
   1694   return (ERR_CODE_NONE);
   1695 }
   1696 
   1697 err_code_t blackhawk_tsc_INTERNAL_read_core_state(srds_access_t *sa__, blackhawk_tsc_core_state_st *istate) {  
   1698   blackhawk_tsc_core_state_st state;
   1699   struct blackhawk_tsc_uc_core_config_st core_cfg;
   1700 
   1701   ENULL_MEMSET(&state, 0, sizeof(blackhawk_tsc_core_state_st));
   1702   ENULL_MEMSET(&core_cfg, 0, sizeof(struct blackhawk_tsc_uc_core_config_st));
   1703 
   1704   if(!istate) 
   1705     return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1706   EFUN(blackhawk_tsc_get_uc_core_config(sa__, &core_cfg));
   1707   
   1708   {
   1709       uint8_t rescal_frc;
   1710       ESTM(rescal_frc = rdc_rescal_frc());
   1711       if (1 == rescal_frc) {
   1712           /* rescal_frc_val is read, since the rescal value is overriden. */
   1713           ESTM(state.rescal = rdc_rescal_frc_val());
   1714       } else {
   1715           ESTM(state.rescal = rd_ams_tx_ana_rescal());
   1716       }
   1717   }
   1718   ESTM(state.core_reset           = rdc_core_dp_reset_state());
   1719   ESTM(state.uc_active            = rdc_uc_active());
   1720   ESTM(state.comclk_mhz           = rdc_heartbeat_count_1us());   
   1721   ESTM(state.pll_pwrdn            = rdc_pll_pwrdn_or());
   1722   ESTM(state.ucode_version        = rdcv_common_ucode_version()); 
   1723   EFUN(blackhawk_tsc_version(sa__, &state.api_version));
   1724   ESTM(state.ucode_minor_version  = rdcv_common_ucode_minor_version());
   1725   ESTM(state.afe_hardware_version = rdcv_afe_hardware_version());
   1726   ESTM(state.temp_idx             = rdcv_temp_idx());
   1727   {  int16_t                           die_temp = 0;
   1728      EFUN(blackhawk_tsc_read_die_temperature(sa__, &die_temp));
   1729      state.die_temp               =    die_temp;
   1730   }
   1731   ESTM(state.avg_tmon             = _bin_to_degC(rdcv_avg_tmon_reg13bit()>>3));
   1732   state.vco_rate_mhz            = (uint16_t)core_cfg.vco_rate_in_Mhz;
   1733   ESTM(state.analog_vco_range     = rdc_ams_pll_range());
   1734   EFUN(blackhawk_tsc_INTERNAL_measure_pll_comp_thresh(sa__, &state.pll_comp_thresh));
   1735   EFUN(blackhawk_tsc_INTERNAL_read_pll_div(sa__, &state.pll_div));
   1736   EFUN(blackhawk_tsc_INTERNAL_pll_lock_status(sa__, &state.pll_lock, &state.pll_lock_chg));
   1737   ESTM(state.core_status          = rdcv_status_byte());
   1738   ESTM(state.refclk_doubler       = rdc_ams_pll_refclk_doubler());
   1739 
   1740   *istate = state;
   1741   return (ERR_CODE_NONE);
   1742 }
   1743 
   1744 err_code_t blackhawk_tsc_INTERNAL_measure_pll_comp_thresh(srds_access_t *sa__, int16_t *thresh) {
   1745     uint8_t pll_comp_thresh=0;
   1746     uint8_t pll_low=0;
   1747     uint8_t pll_comp_thresh_bak;
   1748 
   1749     if(!thresh) 
   1750         return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1751 
   1752     ESTM(pll_comp_thresh_bak = rdc_ams_pll_comp_thresh());
   1753     
   1754     for(pll_comp_thresh = 0; pll_comp_thresh < 8; pll_comp_thresh++) {
   1755         EFUN(wrc_ams_pll_comp_thresh(pll_comp_thresh));
   1756         ESTM(pll_low = rdc_ams_pll_low());
   1757         if(pll_low == 1) break;
   1758     }
   1759     
   1760     EFUN(wrc_ams_pll_comp_thresh(pll_comp_thresh_bak));
   1761 
   1762     *thresh = ((pll_comp_thresh==0) ? 0 : (-50*pll_comp_thresh - 50));
   1763 
   1764     return(ERR_CODE_NONE);
   1765 }
   1766 
   1767 err_code_t blackhawk_tsc_INTERNAL_display_core_state_no_newline(srds_access_t *sa__) {
   1768   blackhawk_tsc_core_state_st state;
   1769     blackhawk_tsc_core_state_st state_pll1;
   1770 
   1771     ENULL_MEMSET(&state_pll1, 0, sizeof(state_pll1));
   1772     ENULL_MEMSET(&state     , 0, sizeof(state     ));
   1773     {
   1774         uint8_t pll_orig;
   1775         ESTM(pll_orig = blackhawk_tsc_get_pll_idx(sa__));
   1776         EFUN(blackhawk_tsc_set_pll_idx(sa__, 0));
   1777   EFUN(blackhawk_tsc_INTERNAL_read_core_state(sa__, &state));
   1778         EFUN(blackhawk_tsc_set_pll_idx(sa__, 1));
   1779         EFUN(blackhawk_tsc_INTERNAL_read_core_state(sa__, &state_pll1));
   1780         EFUN(blackhawk_tsc_set_pll_idx(sa__, pll_orig));
   1781     }
   1782 
   1783     if ((state.avg_tmon<-50)||(state.avg_tmon>135)) {
   1784       EFUN_PRINTF(("\n*** WARNING: Core die temperature (LIVE_TEMP) out of bounds -50C to 130C\n"));
   1785     }
   1786     if ((state.rescal < 6) || (state.rescal > 13)) {
   1787       EFUN_PRINTF(("\n*** WARNING: RESCAL value is out of bounds 6 to 13\n"));
   1788     }
   1789     if ((state_pll1.rescal < 6) || (state_pll1.rescal > 13)) {
   1790       EFUN_PRINTF(("\n*** WARNING: RESCAL PLL1 value is out of bounds 6 to 13\n"));
   1791     }
   1792 
   1793     EFUN_PRINTF((" %02d "              ,  blackhawk_tsc_get_core(sa__)));
   1794     EFUN_PRINTF((" %x,%x,%02x "        ,  state.core_reset, state_pll1.core_reset, state.core_status));
   1795     EFUN_PRINTF(("   %1d,%1d    "      ,  state.pll_pwrdn,state_pll1.pll_pwrdn));
   1796     EFUN_PRINTF(("   %1d    "          ,  state.uc_active));
   1797     EFUN_PRINTF((" %3d.%2dMHz"         , (state.comclk_mhz/4),((state.comclk_mhz%4)*25)));    /* comclk in Mhz = heartbeat_count_1us / 4 */
   1798     EFUN_PRINTF(("   %4X_%02X "        ,  state.ucode_version, state.ucode_minor_version));
   1799     EFUN_PRINTF(("  %06X "             , state.api_version));
   1800     EFUN_PRINTF(("    0x%02x   "       ,  state.afe_hardware_version));
   1801     EFUN_PRINTF(("   %3dC   "          ,  state.die_temp));
   1802     EFUN_PRINTF(("   (%02d)%3dC "      ,  state.temp_idx, state.avg_tmon));
   1803     EFUN_PRINTF(("   0x%02x  "         ,  state.rescal));
   1804     EFUN_PRINTF((" %2d.%03d,%2d.%03dGHz ", (state     .vco_rate_mhz / 1000),
   1805                                            (state     .vco_rate_mhz % 1000),
   1806                                            (state_pll1.vco_rate_mhz / 1000),
   1807                                            (state_pll1.vco_rate_mhz % 1000)));
   1808     EFUN_PRINTF(("  %03d,%03d     "    ,  state     .analog_vco_range,
   1809                                           state_pll1.analog_vco_range));
   1810     EFUN(blackhawk_tsc_INTERNAL_display_pll_to_divider(sa__, state .pll_div));
   1811     EFUN_PRINTF((","));
   1812     EFUN(blackhawk_tsc_INTERNAL_display_pll_to_divider(sa__, state_pll1.pll_div));
   1813     EFUN_PRINTF(("   %01d%s,"         ,  state.pll_lock, state.pll_lock_chg ? "*" : " "));
   1814     EFUN_PRINTF((" %01d%s"             ,  state_pll1.pll_lock, state_pll1.pll_lock_chg ? "*" : " "));
   1815     EFUN_PRINTF(("  %+4dmV,%+4dmV "       ,  state.pll_comp_thresh,state_pll1.pll_comp_thresh));
   1816 
   1817 
   1818     return (ERR_CODE_NONE);
   1819   }
   1820 
   1821 
   1822 
   1823 /* returns 000111 (7 = 8-1), for n = 3  */
   1824 #define BFMASK(n) ((1<<((n)))-1)
   1825 
   1826 err_code_t blackhawk_tsc_INTERNAL_update_uc_lane_config_st(struct  blackhawk_tsc_uc_lane_config_st *st) {
   1827   uint16_t in = st->word;
   1828   st->field.lane_cfg_from_pcs = in & BFMASK(1); in >>= 1;
   1829   st->field.an_enabled = in & BFMASK(1); in >>= 1;
   1830   st->field.dfe_on = in & BFMASK(1); in >>= 1;
   1831   st->field.dfe_lp_mode = in & BFMASK(1); in >>= 1;
   1832   st->field.force_brdfe_on = in & BFMASK(1); in >>= 1;
   1833   st->field.media_type = in & BFMASK(2); in >>= 2;
   1834   st->field.unreliable_los = in & BFMASK(1); in >>= 1;
   1835   st->field.scrambling_dis = in & BFMASK(1); in >>= 1;  
   1836   st->field.cl72_auto_polarity_en = in & BFMASK(1); in >>= 1;
   1837   st->field.cl72_restart_timeout_en = in & BFMASK(1); in >>= 1;
   1838   st->field.force_es = in & BFMASK(1); in >>= 1;
   1839   st->field.force_ns = in & BFMASK(1); in >>= 1;
   1840   st->field.lp_has_prec_en = in & BFMASK(1); in >>= 1;
   1841   st->field.force_pam4_mode = in & BFMASK(1); in >>= 1;
   1842   st->field.force_nrz_mode = in & BFMASK(1); in >>= 1;
   1843   return(ERR_CODE_NONE);
   1844 }
   1845 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_functions_st(struct blackhawk_tsc_usr_ctrl_disable_functions_st *st) {
   1846   uint16_t in = st->word;
   1847   st->field.pf_adaptation = in & BFMASK(1); in >>= 1;
   1848   st->field.pf2_adaptation = in & BFMASK(1); in >>= 1;
   1849   st->field.pf3_adaptation = in & BFMASK(1); in >>= 1;
   1850   st->field.dc_adaptation = in & BFMASK(1); in >>= 1;
   1851   st->field.vga_adaptation = in & BFMASK(1); in >>= 1;
   1852   st->field.slicer_voffset_tuning = in & BFMASK(1); in >>= 1;
   1853   st->field.slicer_hoffset_tuning = in & BFMASK(1); in >>= 1;
   1854   st->field.phase_offset_adaptation = in & BFMASK(1); in >>= 1;
   1855   st->field.eye_adaptation = in & BFMASK(1); in >>= 1;
   1856   st->field.all_adaptation = in & BFMASK(1); in >>= 1;
   1857   st->field.deq_adaptation = in & BFMASK(1); in >>= 1;
   1858   st->field.pam_eye_margin_estimation = in & BFMASK(1); in >>= 1;
   1859   st->field.reserved = in & BFMASK(4);
   1860   return ERR_CODE_NONE;
   1861 }
   1862 
   1863 
   1864 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_dfe_functions_st(struct blackhawk_tsc_usr_ctrl_disable_dfe_functions_st *st) {
   1865   uint8_t in = st->byte;
   1866   st->field.dfe_tap1_adaptation = in & BFMASK(1); in >>= 1;
   1867   st->field.dfe_fx_taps_adaptation = in & BFMASK(1); in >>= 1;
   1868   st->field.dfe_fl_taps_adaptation = in & BFMASK(1); in >>= 1;
   1869   st->field.dfe_dcd_adaptation = in & BFMASK(1); in >>= 1;
   1870   return ERR_CODE_NONE;
   1871 }
   1872 /* word to fields, for display */
   1873 err_code_t blackhawk_tsc_INTERNAL_update_uc_core_config_st(struct blackhawk_tsc_uc_core_config_st *st) {
   1874   uint16_t in = st->word;
   1875   st->field.vco_rate = in & BFMASK(8); in >>= 8;
   1876   st->field.core_cfg_from_pcs = in & BFMASK(1); in >>= 1;
   1877   st->field.reserved = in & BFMASK(7);
   1878   st->vco_rate_in_Mhz = VCO_RATE_TO_MHZ(st->field.vco_rate);
   1879   return ERR_CODE_NONE;
   1880 }
   1881 
   1882 /* fields to word, to write into uC RAM */
   1883 err_code_t blackhawk_tsc_INTERNAL_update_uc_core_config_word(struct blackhawk_tsc_uc_core_config_st *st) {
   1884   uint16_t in = 0;
   1885   in <<= 7; in |= 0/*st->field.reserved*/ & BFMASK(7);
   1886   in <<= 1; in |= st->field.core_cfg_from_pcs & BFMASK(1);
   1887   in <<= 8; in |= st->field.vco_rate & BFMASK(8);
   1888   st->word = in;
   1889   return ERR_CODE_NONE;
   1890 }
   1891 
   1892 err_code_t blackhawk_tsc_INTERNAL_update_uc_lane_config_word(struct blackhawk_tsc_uc_lane_config_st *st) {
   1893   uint16_t in = 0;
   1894   in <<= 1; in |= st->field.force_nrz_mode & BFMASK(1);
   1895   in <<= 1; in |= st->field.force_pam4_mode & BFMASK(1);
   1896   in <<= 1; in |= st->field.lp_has_prec_en & BFMASK(1);
   1897   in <<= 1; in |= st->field.force_ns & BFMASK(1);
   1898   in <<= 1; in |= st->field.force_es & BFMASK(1);
   1899   in <<= 1; in |= st->field.cl72_restart_timeout_en & BFMASK(1);
   1900   in <<= 1; in |= st->field.cl72_auto_polarity_en & BFMASK(1);
   1901   in <<= 1; in |= st->field.scrambling_dis & BFMASK(1);
   1902   in <<= 1; in |= st->field.unreliable_los & BFMASK(1);
   1903   in <<= 2; in |= st->field.media_type & BFMASK(2);
   1904   in <<= 1; in |= st->field.force_brdfe_on & BFMASK(1);
   1905   in <<= 1; in |= st->field.dfe_lp_mode & BFMASK(1);
   1906   in <<= 1; in |= st->field.dfe_on & BFMASK(1);
   1907   in <<= 1; in |= st->field.an_enabled & BFMASK(1);
   1908   in <<= 1; in |= st->field.lane_cfg_from_pcs & BFMASK(1);
   1909   st->word = in;
   1910   return ERR_CODE_NONE;
   1911 }
   1912 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_functions_byte(struct blackhawk_tsc_usr_ctrl_disable_functions_st *st) {
   1913   uint16_t in = 0;
   1914   in <<= 5; in |= 0/*st->field.reserved*/ & BFMASK(4);
   1915   in <<= 1; in |= st->field.pam_eye_margin_estimation & BFMASK(1);
   1916   in <<= 1; in |= st->field.deq_adaptation & BFMASK(1);
   1917   in <<= 1; in |= st->field.all_adaptation & BFMASK(1);
   1918   in <<= 1; in |= st->field.eye_adaptation & BFMASK(1);
   1919   in <<= 1; in |= st->field.phase_offset_adaptation & BFMASK(1);
   1920   in <<= 1; in |= st->field.slicer_hoffset_tuning & BFMASK(1);
   1921   in <<= 1; in |= st->field.slicer_voffset_tuning & BFMASK(1);
   1922   in <<= 1; in |= st->field.vga_adaptation & BFMASK(1);
   1923   in <<= 1; in |= st->field.dc_adaptation & BFMASK(1);
   1924   in <<= 1; in |= st->field.pf3_adaptation & BFMASK(1);
   1925   in <<= 1; in |= st->field.pf2_adaptation & BFMASK(1);
   1926   in <<= 1; in |= st->field.pf_adaptation & BFMASK(1);
   1927   st->word = in;
   1928   return ERR_CODE_NONE;
   1929 }
   1930 
   1931 err_code_t blackhawk_tsc_INTERNAL_update_usr_ctrl_disable_dfe_functions_byte(struct  blackhawk_tsc_usr_ctrl_disable_dfe_functions_st *st) {
   1932   uint8_t in = 0;
   1933   in <<= 1; in |= st->field.dfe_dcd_adaptation & BFMASK(1);
   1934   in <<= 1; in |= st->field.dfe_fl_taps_adaptation & BFMASK(1);
   1935   in <<= 1; in |= st->field.dfe_fx_taps_adaptation & BFMASK(1);
   1936   in <<= 1; in |= st->field.dfe_tap1_adaptation & BFMASK(1);
   1937   st->byte = in;
   1938   return ERR_CODE_NONE;
   1939 }
   1940 
   1941 #undef BFMASK
   1942 
   1943 err_code_t blackhawk_tsc_INTERNAL_check_uc_lane_stopped(srds_access_t *sa__) {
   1944 
   1945   uint8_t is_micro_stopped;
   1946   ESTM(is_micro_stopped = rdv_usr_sts_micro_stopped() || (rd_rx_lane_dp_reset_state() > 0));
   1947   if (!is_micro_stopped) {
   1948       return(blackhawk_tsc_error(sa__, ERR_CODE_UC_NOT_STOPPED));
   1949   } else {
   1950       return(ERR_CODE_NONE);
   1951   }
   1952 }
   1953 
   1954 err_code_t blackhawk_tsc_INTERNAL_calc_patt_gen_mode_sel(srds_access_t *sa__, uint8_t *mode_sel, uint8_t *zero_pad_len, uint8_t patt_length) {
   1955 
   1956   if(!mode_sel) {
   1957     return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1958   }
   1959   if(!zero_pad_len) {
   1960     return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   1961   }
   1962 
   1963   /* Select the correct Pattern generator Mode depending on Pattern length */
   1964   if (!(140 % patt_length)) {
   1965     *mode_sel = 6;
   1966     *zero_pad_len = 100;
   1967   }
   1968   else if (!(160 % patt_length)) {
   1969     *mode_sel = 5;
   1970     *zero_pad_len = 80;
   1971   }
   1972   else if (!(180 % patt_length)) {
   1973     *mode_sel = 4;
   1974     *zero_pad_len = 60;
   1975   }
   1976   else if (!(200 % patt_length)) {
   1977     *mode_sel = 3;
   1978     *zero_pad_len = 40;
   1979   }
   1980   else if (!(220 % patt_length)) {
   1981     *mode_sel = 2;
   1982     *zero_pad_len = 20;
   1983   }
   1984   else if (!(240 % patt_length)) {
   1985     *mode_sel = 1;
   1986     *zero_pad_len = 0;
   1987   } else {
   1988     EFUN_PRINTF(("ERROR: Unsupported Pattern Length\n"));
   1989     return (blackhawk_tsc_error(sa__, ERR_CODE_CFG_PATT_INVALID_PATT_LENGTH));
   1990   }
   1991   return(ERR_CODE_NONE);
   1992 }
   1993 
   1994 /*-----------------------------------------*/
   1995 /*  Write Core Config variables to uC RAM  */
   1996 /*-----------------------------------------*/
   1997 
   1998 err_code_t blackhawk_tsc_INTERNAL_set_uc_core_config(srds_access_t *sa__, struct blackhawk_tsc_uc_core_config_st struct_val) {
   1999     {   uint8_t reset_state;
   2000         ESTM(reset_state = rdc_core_dp_reset_state());
   2001         if(reset_state < 7) {
   2002             EFUN_PRINTF(("ERROR: blackhawk_tsc_INTERNAL_set_uc_core_config(..) called without core_dp_s_rstb=0\n"));
   2003             return (blackhawk_tsc_error(sa__, ERR_CODE_CORE_DP_NOT_RESET));
   2004         }
   2005     }
   2006     if(struct_val.vco_rate_in_Mhz > 0) {
   2007         struct_val.field.vco_rate = MHZ_TO_VCO_RATE(struct_val.vco_rate_in_Mhz);
   2008     }
   2009     EFUN(blackhawk_tsc_INTERNAL_update_uc_core_config_word(&struct_val));
   2010     switch (blackhawk_tsc_get_pll_idx(sa__)) {
   2011     case 0:
   2012         EFUN(reg_wrc_CORE_PLL_COM_PLL_UC_CORE_CONFIG(struct_val.word));
   2013         break;
   2014     case 1:
   2015         EFUN(reg_wrc_CORE_PLL_COM_PLL_UC_CORE_CONFIG(struct_val.word));
   2016         break;
   2017     default:
   2018         EFUN(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   2019         break;
   2020     }
   2021     return (ERR_CODE_NONE);
   2022 }
   2023 
   2024 /*---------------------*/
   2025 /*  PLL Configuration  */
   2026 /*---------------------*/
   2027 /** Extract the refclk frequency in Hz, based on a blackhawk_tsc_pll_refclk_enum value. */
   2028 err_code_t _blackhawk_tsc_get_refclk_in_hz(srds_access_t *sa__, enum blackhawk_tsc_pll_refclk_enum refclk, uint32_t *refclk_in_hz) {
   2029     switch (refclk) {
   2030         case BLACKHAWK_TSC_PLL_REFCLK_100MHZ:          *refclk_in_hz = 100000000; break;
   2031         case BLACKHAWK_TSC_PLL_REFCLK_106P25MHZ:       *refclk_in_hz = 106250000; break;
   2032         case BLACKHAWK_TSC_PLL_REFCLK_122P88MHZ:       *refclk_in_hz = 122880000; break;
   2033         case BLACKHAWK_TSC_PLL_REFCLK_125MHZ:          *refclk_in_hz = 125000000; break;
   2034         case BLACKHAWK_TSC_PLL_REFCLK_145P947802MHZ:   *refclk_in_hz = 145947802; break;
   2035         case BLACKHAWK_TSC_PLL_REFCLK_155P52MHZ:       *refclk_in_hz = 155520000; break;
   2036         case BLACKHAWK_TSC_PLL_REFCLK_156P25MHZ:       *refclk_in_hz = 156250000; break;
   2037         case BLACKHAWK_TSC_PLL_REFCLK_159P375MHZ:      *refclk_in_hz = 159375000; break;
   2038         case BLACKHAWK_TSC_PLL_REFCLK_161P1328125MHZ:  *refclk_in_hz = 161132813; break;
   2039         case BLACKHAWK_TSC_PLL_REFCLK_166P67MHZ:       *refclk_in_hz = 166670000; break;
   2040         case BLACKHAWK_TSC_PLL_REFCLK_166P7974882MHZ:  *refclk_in_hz = 166797488; break;
   2041         case BLACKHAWK_TSC_PLL_REFCLK_167P38MHZ:       *refclk_in_hz = 167380000; break;
   2042         case BLACKHAWK_TSC_PLL_REFCLK_167P4107143MHZ:  *refclk_in_hz = 167410714; break;
   2043         case BLACKHAWK_TSC_PLL_REFCLK_174P703125MHZ:   *refclk_in_hz = 174703125; break;
   2044         case BLACKHAWK_TSC_PLL_REFCLK_212P5MHZ:        *refclk_in_hz = 212500000; break;
   2045         case BLACKHAWK_TSC_PLL_REFCLK_311p04:          *refclk_in_hz = 311040000; break;
   2046         case BLACKHAWK_TSC_PLL_REFCLK_312P5MHZ:        *refclk_in_hz = 312500000; break;
   2047         case BLACKHAWK_TSC_PLL_REFCLK_425MHZ:          *refclk_in_hz = 425000000; break;
   2048         case BLACKHAWK_TSC_PLL_REFCLK_534MHZ:          *refclk_in_hz = 534000000; break;
   2049         case BLACKHAWK_TSC_PLL_REFCLK_705MHZ:          *refclk_in_hz = 705000000; break;
   2050         case BLACKHAWK_TSC_PLL_REFCLK_175MHZ:          *refclk_in_hz = 175000000; break;
   2051         case BLACKHAWK_TSC_PLL_REFCLK_400MHZ:          *refclk_in_hz = 400000000; break;
   2052         case BLACKHAWK_TSC_PLL_REFCLK_266P67MHZ:       *refclk_in_hz = 266670000; break;
   2053         case BLACKHAWK_TSC_PLL_REFCLK_156P637MHZ:      *refclk_in_hz = 156637000; break;
   2054         case BLACKHAWK_TSC_PLL_REFCLK_157P844MHZ:      *refclk_in_hz = 157844000; break;
   2055         case BLACKHAWK_TSC_PLL_REFCLK_158P51MHZ:       *refclk_in_hz = 158510000; break;
   2056         case BLACKHAWK_TSC_PLL_REFCLK_162P9485MHZ:     *refclk_in_hz = 162948500; break;
   2057         case BLACKHAWK_TSC_PLL_REFCLK_167P331MHZ:      *refclk_in_hz = 167331000; break;
   2058         case BLACKHAWK_TSC_PLL_REFCLK_168P04MHZ:       *refclk_in_hz = 168040000; break;
   2059         case BLACKHAWK_TSC_PLL_REFCLK_169P40905086MHZ: *refclk_in_hz = 169409051; break;
   2060         case BLACKHAWK_TSC_PLL_REFCLK_173P37MHZ:       *refclk_in_hz = 173370000; break;
   2061         default:
   2062             EFUN_PRINTF(("ERROR: Unknown refclk frequency:  0x%08X\n", (uint32_t)refclk));
   2063             *refclk_in_hz = 0xFFFFFFFF;
   2064             return (blackhawk_tsc_error(sa__, ERR_CODE_REFCLK_FREQUENCY_INVALID));
   2065     }
   2066     return (ERR_CODE_NONE);
   2067 }
   2068 
   2069 /** Identify the ratio:
   2070  *
   2071  *     (numerator / denominator) = (1000 / divisor)
   2072  *
   2073  * such that this has as little rounding error as possible:
   2074  *
   2075  *     refclk_freq_hz = numerator * round(vco_freq_khz / denominator)
   2076  *
   2077  * This will yield the most accurate refclk_freq_hz.
   2078  * Common values of vco_freq_khz are considered in this.
   2079  */
   2080 static err_code_t _blackhawk_tsc_get_divisor_ratio(srds_access_t *sa__, enum blackhawk_tsc_pll_div_enum srds_div, uint16_t *numerator, uint16_t *denominator)
   2081 {
   2082     switch (srds_div) {
   2083         case BLACKHAWK_TSC_PLL_DIV_66:         *denominator =  33;  *numerator =  500; break;
   2084         case BLACKHAWK_TSC_PLL_DIV_67:         *denominator =  67;  *numerator = 1000; break;
   2085         case BLACKHAWK_TSC_PLL_DIV_70:         *denominator =   7;  *numerator =  100; break;
   2086         case BLACKHAWK_TSC_PLL_DIV_72:         *denominator =   9;  *numerator =  125; break;
   2087         case BLACKHAWK_TSC_PLL_DIV_76:         *denominator =  19;  *numerator =  250; break;
   2088         case BLACKHAWK_TSC_PLL_DIV_73P6:       *denominator =  46;  *numerator =  625; break;
   2089         case BLACKHAWK_TSC_PLL_DIV_79P2:       *denominator =  99;  *numerator = 1250; break;
   2090         case BLACKHAWK_TSC_PLL_DIV_80:         *denominator =   2;  *numerator =   25; break;
   2091         case BLACKHAWK_TSC_PLL_DIV_82P5:       *denominator =  33;  *numerator =  400; break;
   2092         case BLACKHAWK_TSC_PLL_DIV_84:         *denominator =  21;  *numerator =  250; break;
   2093         case BLACKHAWK_TSC_PLL_DIV_85:         *denominator =  17;  *numerator =  200; break;
   2094         case BLACKHAWK_TSC_PLL_DIV_87P5:       *denominator =   7;  *numerator =   80; break;
   2095         case BLACKHAWK_TSC_PLL_DIV_89P6:       *denominator =  56;  *numerator =  625; break;
   2096         case BLACKHAWK_TSC_PLL_DIV_90:         *denominator =   9;  *numerator =  100; break;
   2097         case BLACKHAWK_TSC_PLL_DIV_96:         *denominator =  12;  *numerator =  125; break;
   2098         case BLACKHAWK_TSC_PLL_DIV_100:        *denominator =   1;  *numerator =   10; break;
   2099         case BLACKHAWK_TSC_PLL_DIV_120:        *denominator =   3;  *numerator =   25; break;
   2100         case BLACKHAWK_TSC_PLL_DIV_127P401984: *denominator = 179;  *numerator = 1405; break;
   2101         case BLACKHAWK_TSC_PLL_DIV_128:        *denominator =  16;  *numerator =  125; break;
   2102         case BLACKHAWK_TSC_PLL_DIV_132:        *denominator =  33;  *numerator =  250; break;
   2103         case BLACKHAWK_TSC_PLL_DIV_134:        *denominator =  67;  *numerator =  500; break;
   2104         case BLACKHAWK_TSC_PLL_DIV_140:        *denominator =   7;  *numerator =   50; break;
   2105         case BLACKHAWK_TSC_PLL_DIV_144:        *denominator =  18;  *numerator =  125; break;
   2106         case BLACKHAWK_TSC_PLL_DIV_147P2:      *denominator =  92;  *numerator =  625; break;
   2107         case BLACKHAWK_TSC_PLL_DIV_148:        *denominator =  37;  *numerator =  250; break;
   2108         case BLACKHAWK_TSC_PLL_DIV_152:        *denominator =  19;  *numerator =  125; break;
   2109         case BLACKHAWK_TSC_PLL_DIV_158P4:      *denominator =  99;  *numerator =  625; break;
   2110         case BLACKHAWK_TSC_PLL_DIV_160:        *denominator =   4;  *numerator =   25; break;
   2111         case BLACKHAWK_TSC_PLL_DIV_165:        *denominator =  33;  *numerator =  200; break;
   2112         case BLACKHAWK_TSC_PLL_DIV_168:        *denominator =  21;  *numerator =  125; break;
   2113         case BLACKHAWK_TSC_PLL_DIV_170:        *denominator =  17;  *numerator =  100; break;
   2114         case BLACKHAWK_TSC_PLL_DIV_175:        *denominator =   7;  *numerator =   40; break;
   2115         case BLACKHAWK_TSC_PLL_DIV_180:        *denominator =   9;  *numerator =   50; break;
   2116         case BLACKHAWK_TSC_PLL_DIV_184:        *denominator =  23;  *numerator =  125; break;
   2117         case BLACKHAWK_TSC_PLL_DIV_192:        *denominator =  24;  *numerator =  125; break;
   2118         case BLACKHAWK_TSC_PLL_DIV_198:        *denominator =  99;  *numerator =  500; break;
   2119         case BLACKHAWK_TSC_PLL_DIV_200:        *denominator =   1;  *numerator =    5; break;
   2120         case BLACKHAWK_TSC_PLL_DIV_224:        *denominator =  28;  *numerator =  125; break;
   2121         case BLACKHAWK_TSC_PLL_DIV_240:        *denominator =   6;  *numerator =   25; break;
   2122         case BLACKHAWK_TSC_PLL_DIV_264:        *denominator =  33;  *numerator =  125; break;
   2123         case BLACKHAWK_TSC_PLL_DIV_280:        *denominator =   7;  *numerator =   25; break;
   2124         case BLACKHAWK_TSC_PLL_DIV_330:        *denominator =  33;  *numerator =  100; break;
   2125         case BLACKHAWK_TSC_PLL_DIV_350:        *denominator =   7;  *numerator =   20; break;
   2126         default:
   2127             EFUN_PRINTF(("ERROR: Unknown divider value:  0x%08X\n", (uint32_t)srds_div));
   2128             *numerator = 0;
   2129             *denominator = 0;
   2130             return (blackhawk_tsc_error(sa__, ERR_CODE_PLL_DIV_INVALID));
   2131     }
   2132     return (ERR_CODE_NONE);
   2133 }
   2134 
   2135 /** Get the Refclk frequency in Hz, based on the blackhawk_tsc_pll_div_enum value and VCO frequency. */
   2136 static err_code_t _blackhawk_tsc_get_refclk_from_div_vco(srds_access_t *sa__, uint32_t *refclk_freq_hz, enum blackhawk_tsc_pll_div_enum srds_div, uint32_t vco_freq_khz, enum blackhawk_tsc_pll_option_enum pll_option) {
   2137     uint16_t numerator, denominator;
   2138     EFUN(_blackhawk_tsc_get_divisor_ratio(sa__, srds_div, &numerator, &denominator));
   2139     *refclk_freq_hz = ((vco_freq_khz+(denominator>>1)) / denominator) * numerator;
   2140     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN) *refclk_freq_hz /= 2;
   2141     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN)    *refclk_freq_hz *= 2;
   2142     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN)    *refclk_freq_hz *= 4;
   2143     return (ERR_CODE_NONE);
   2144 }
   2145 
   2146 /** Get the VCO frequency in kHz, based on the reference clock frequency and blackhawk_tsc_pll_div_enum value. */
   2147 err_code_t blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(srds_access_t *sa__, uint32_t refclk_freq_hz, enum blackhawk_tsc_pll_div_enum srds_div, uint32_t *vco_freq_khz, enum blackhawk_tsc_pll_option_enum pll_option) {
   2148     uint16_t numerator, denominator;
   2149     EFUN(_blackhawk_tsc_get_divisor_ratio(sa__, srds_div, &numerator, &denominator));
   2150     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DOUBLER_EN) refclk_freq_hz *= 2;
   2151     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV2_EN)    refclk_freq_hz /= 2;
   2152     if (pll_option == BLACKHAWK_TSC_PLL_OPTION_REFCLK_DIV4_EN)    refclk_freq_hz /= 4;
   2153     *vco_freq_khz = ((refclk_freq_hz + (numerator>>1)) / numerator) * denominator;
   2154     return (ERR_CODE_NONE);
   2155 }
   2156 
   2157 /* Boundaries for allowed VCO frequency */
   2158 #    define SERDES_VCO_FREQ_KHZ_MIN (15000000)
   2159 #    define SERDES_VCO_FREQ_KHZ_MAX (30000000)
   2160 
   2161 /* Allowed tolerance in resultant VCO frequency when auto-determining divider value */
   2162 #    define SERDES_VCO_FREQ_KHZ_TOLERANCE (2000)
   2163 
   2164 /* The allowed PLL divider values */
   2165 static const enum blackhawk_tsc_pll_div_enum _blackhawk_tsc_div_candidates[] = {
   2166     BLACKHAWK_TSC_PLL_DIV_66,
   2167     BLACKHAWK_TSC_PLL_DIV_67,
   2168     BLACKHAWK_TSC_PLL_DIV_70,
   2169     BLACKHAWK_TSC_PLL_DIV_72,
   2170     BLACKHAWK_TSC_PLL_DIV_76,
   2171     BLACKHAWK_TSC_PLL_DIV_73P6,
   2172     BLACKHAWK_TSC_PLL_DIV_79P2,
   2173     BLACKHAWK_TSC_PLL_DIV_80,
   2174     BLACKHAWK_TSC_PLL_DIV_82P5,
   2175     BLACKHAWK_TSC_PLL_DIV_84,
   2176     BLACKHAWK_TSC_PLL_DIV_85,
   2177     BLACKHAWK_TSC_PLL_DIV_87P5,
   2178     BLACKHAWK_TSC_PLL_DIV_89P6,
   2179     BLACKHAWK_TSC_PLL_DIV_90,
   2180     BLACKHAWK_TSC_PLL_DIV_96,
   2181     BLACKHAWK_TSC_PLL_DIV_100,
   2182     BLACKHAWK_TSC_PLL_DIV_120,
   2183     BLACKHAWK_TSC_PLL_DIV_127P401984,
   2184     BLACKHAWK_TSC_PLL_DIV_128,
   2185     BLACKHAWK_TSC_PLL_DIV_132,
   2186     BLACKHAWK_TSC_PLL_DIV_134,
   2187     BLACKHAWK_TSC_PLL_DIV_140,
   2188     BLACKHAWK_TSC_PLL_DIV_144,
   2189     BLACKHAWK_TSC_PLL_DIV_147P2,
   2190     BLACKHAWK_TSC_PLL_DIV_148,
   2191     BLACKHAWK_TSC_PLL_DIV_152,
   2192     BLACKHAWK_TSC_PLL_DIV_158P4,
   2193     BLACKHAWK_TSC_PLL_DIV_160,
   2194     BLACKHAWK_TSC_PLL_DIV_165,
   2195     BLACKHAWK_TSC_PLL_DIV_168,
   2196     BLACKHAWK_TSC_PLL_DIV_170,
   2197     BLACKHAWK_TSC_PLL_DIV_175,
   2198     BLACKHAWK_TSC_PLL_DIV_180,
   2199     BLACKHAWK_TSC_PLL_DIV_184,
   2200     BLACKHAWK_TSC_PLL_DIV_192,
   2201     BLACKHAWK_TSC_PLL_DIV_198,
   2202     BLACKHAWK_TSC_PLL_DIV_200,
   2203     BLACKHAWK_TSC_PLL_DIV_224,
   2204     BLACKHAWK_TSC_PLL_DIV_240,
   2205     BLACKHAWK_TSC_PLL_DIV_264,
   2206     BLACKHAWK_TSC_PLL_DIV_280,
   2207     BLACKHAWK_TSC_PLL_DIV_330,
   2208     BLACKHAWK_TSC_PLL_DIV_350
   2209 };
   2210 
   2211 static const uint8_t _blackhawk_tsc_div_candidates_count = sizeof(_blackhawk_tsc_div_candidates) / sizeof(_blackhawk_tsc_div_candidates[0]);
   2212 
   2213 static err_code_t _blackhawk_tsc_check_div(srds_access_t *sa__, enum blackhawk_tsc_pll_div_enum srds_div) {
   2214     uint8_t i, found = 0;
   2215     for (i=0; i<_blackhawk_tsc_div_candidates_count; i++) {
   2216         found |= srds_div == _blackhawk_tsc_div_candidates[i];
   2217     }
   2218     if (!found) {
   2219         EFUN_PRINTF(("ERROR: Invalid divider value:  0x%08X\n", (uint32_t)srds_div));
   2220         return (blackhawk_tsc_error(sa__, ERR_CODE_PLL_DIV_INVALID));
   2221     }
   2222     return (ERR_CODE_NONE);
   2223 }
   2224     
   2225 static err_code_t _blackhawk_tsc_check_vco_freq_khz(srds_access_t *sa__, uint32_t vco_freq_khz) {
   2226     if (vco_freq_khz < SERDES_VCO_FREQ_KHZ_MIN - SERDES_VCO_FREQ_KHZ_TOLERANCE) {
   2227         EFUN_PRINTF(("ERROR: VCO frequency too low:  %d kHz is lower than minimum (%d kHz)\n", vco_freq_khz, SERDES_VCO_FREQ_KHZ_MIN));
   2228         return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID));
   2229     }
   2230     if (vco_freq_khz > SERDES_VCO_FREQ_KHZ_MAX + SERDES_VCO_FREQ_KHZ_TOLERANCE) {
   2231         EFUN_PRINTF(("ERROR: VCO frequency too high:  %d kHz is higher than maximum (%d kHz)\n", vco_freq_khz, SERDES_VCO_FREQ_KHZ_MAX));
   2232         return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID));
   2233     }
   2234     return (ERR_CODE_NONE);
   2235 }
   2236     
   2237 /** Find the entry out of _blackhawk_tsc_div_candidates that is closest to matching refclk_freq_hz and vco_freq_khz. */
   2238 static err_code_t _blackhawk_tsc_get_div(srds_access_t *sa__, uint32_t refclk_freq_hz, uint32_t vco_freq_khz, enum blackhawk_tsc_pll_div_enum *srds_div, enum blackhawk_tsc_pll_option_enum pll_option) {
   2239     int32_t vco_freq_khz_min_error = 0x7FFFFFFF;
   2240     uint8_t i;
   2241     for (i=0; i<_blackhawk_tsc_div_candidates_count; i++) {
   2242         uint32_t actual_vco_freq_khz = 0;
   2243         int32_t  vco_freq_khz_error;
   2244         EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, refclk_freq_hz, _blackhawk_tsc_div_candidates[i], &actual_vco_freq_khz, pll_option));
   2245         vco_freq_khz_error = vco_freq_khz - actual_vco_freq_khz;
   2246         vco_freq_khz_error = SRDS_ABS(vco_freq_khz_error);
   2247         if (vco_freq_khz_min_error > vco_freq_khz_error) {
   2248             vco_freq_khz_min_error = vco_freq_khz_error;
   2249             *srds_div = _blackhawk_tsc_div_candidates[i];
   2250         }
   2251     }
   2252     if (vco_freq_khz_min_error == 0xFFFFFFFF) {
   2253       return (blackhawk_tsc_error(sa__, ERR_CODE_CONFLICTING_PARAMETERS));
   2254     }
   2255     return (ERR_CODE_NONE);
   2256 }
   2257 
   2258 err_code_t blackhawk_tsc_INTERNAL_resolve_pll_parameters(srds_access_t *sa__,
   2259                                                   enum blackhawk_tsc_pll_refclk_enum refclk,
   2260                                                   uint32_t *refclk_freq_hz,
   2261                                                   enum blackhawk_tsc_pll_div_enum *srds_div,
   2262                                                   uint32_t *vco_freq_khz,
   2263                                                   enum blackhawk_tsc_pll_option_enum pll_option) {
   2264 
   2265     /* Parameter value and consistency checks */
   2266     const uint8_t given_param_count = (((refclk == BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN) ? 0 : 1)
   2267                                        + ((*srds_div == BLACKHAWK_TSC_PLL_DIV_UNKNOWN) ? 0 : 1)
   2268                                        + ((*vco_freq_khz == 0) ? 0 : 1));
   2269     const uint32_t original_vco_freq_khz = *vco_freq_khz;
   2270     enum blackhawk_tsc_pll_div_enum auto_div = BLACKHAWK_TSC_PLL_DIV_UNKNOWN;
   2271     char*pll_option_e2s[] = {"no", "refclk_x2", "refclk_div2", "refclk_div4"};
   2272     COMPILER_REFERENCE(pll_option_e2s);
   2273 
   2274     /* Verify that at least two of the three parameters is given. */
   2275     if (given_param_count < 2) {
   2276         return (blackhawk_tsc_error(sa__, ERR_CODE_INSUFFICIENT_PARAMETERS));
   2277     }
   2278 
   2279     /* Skip verification if option is selected. Error if all parameters not given. */
   2280     if ((pll_option & BLACKHAWK_TSC_PLL_OPTION_DISABLE_VERIFY) == BLACKHAWK_TSC_PLL_OPTION_DISABLE_VERIFY) {
   2281         if (given_param_count < 3) {
   2282             return (blackhawk_tsc_error(sa__, ERR_CODE_INSUFFICIENT_PARAMETERS));
   2283         } else {
   2284             EFUN(_blackhawk_tsc_get_refclk_in_hz(sa__, refclk, refclk_freq_hz));
   2285             return(ERR_CODE_NONE);
   2286         }
   2287     }
   2288     pll_option = (enum blackhawk_tsc_pll_option_enum)(pll_option & BLACKHAWK_TSC_PLL_OPTION_REFCLK_MASK);
   2289 
   2290     /* The refclk value is checked in various functions below. */
   2291 
   2292     /* Verify that the requested div value is allowed. */
   2293     if (*srds_div != BLACKHAWK_TSC_PLL_DIV_UNKNOWN) {
   2294         EFUN(_blackhawk_tsc_check_div(sa__, *srds_div));
   2295     }
   2296 
   2297     /* Verify that the requested VCO frequency is allowed. */
   2298     if (*vco_freq_khz != 0) {
   2299         EFUN(_blackhawk_tsc_check_vco_freq_khz(sa__, *vco_freq_khz));
   2300     }
   2301 
   2302     if (refclk == BLACKHAWK_TSC_PLL_REFCLK_UNKNOWN) {
   2303         /* Determine refclk from vco frequency and div */
   2304         EFUN(_blackhawk_tsc_get_refclk_from_div_vco(sa__, refclk_freq_hz, *srds_div, *vco_freq_khz, pll_option));
   2305     } else {
   2306         EFUN(_blackhawk_tsc_get_refclk_in_hz(sa__, refclk, refclk_freq_hz));
   2307     }
   2308 
   2309     if (*vco_freq_khz == 0) {
   2310         /* Determine VCO frequency from refclk and divider */
   2311         EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, *refclk_freq_hz, *srds_div, vco_freq_khz, pll_option));
   2312     }
   2313 
   2314     /* Determine divider from vco frequency and refclk.
   2315      * This is done even if the div was provided, because if it is,
   2316      * we still want to check whether the parameters are conflicting.
   2317      */
   2318     EFUN(_blackhawk_tsc_get_div(sa__, *refclk_freq_hz, *vco_freq_khz, &auto_div, pll_option));
   2319     if (*srds_div == BLACKHAWK_TSC_PLL_DIV_UNKNOWN) {
   2320         /* Use the auto-determined divider value, since the divider was not supplied. */
   2321         *srds_div = auto_div;
   2322 
   2323         /* Determine resultant VCO frequency from refclk and divider */
   2324         EFUN(blackhawk_tsc_INTERNAL_get_vco_from_refclk_div(sa__, *refclk_freq_hz, *srds_div, vco_freq_khz, pll_option));
   2325     }
   2326 
   2327     /* Verify the resultant VCO frequency */
   2328     EFUN(_blackhawk_tsc_check_vco_freq_khz(sa__, *vco_freq_khz));
   2329 
   2330     /* Verify that the requested VCO frequency is delivered. */
   2331     if ((original_vco_freq_khz != 0)
   2332         && ((*vco_freq_khz < original_vco_freq_khz - SERDES_VCO_FREQ_KHZ_TOLERANCE)
   2333             || (*vco_freq_khz > original_vco_freq_khz + SERDES_VCO_FREQ_KHZ_TOLERANCE))) {
   2334         EFUN_PRINTF(("ERROR: Could not achieve requested VCO frequency of %d kHz.\n       Refclk is %d Hz, %s option enabled, and auto-determined divider is 0x%08X, yielding a VCO frequency of %d kHz.\n",
   2335                      original_vco_freq_khz, *refclk_freq_hz, pll_option_e2s[pll_option], *srds_div, *vco_freq_khz));
   2336         return (blackhawk_tsc_error(sa__, ERR_CODE_VCO_FREQUENCY_INVALID));
   2337     }
   2338     
   2339     /* Verify the auto-determined divider value. */
   2340     if (auto_div != *srds_div) {
   2341         EFUN_PRINTF(("ERROR: Conflicting PLL parameters:  refclk is %d Hz, %s option enabled, divider is 0x%08X, and VCO frequency is %d kHz.\n       Expected divider is 0x%08X\n",
   2342                      *refclk_freq_hz, pll_option_e2s[pll_option], *srds_div, *vco_freq_khz, auto_div));
   2343         return (blackhawk_tsc_error(sa__, ERR_CODE_CONFLICTING_PARAMETERS));
   2344     }
   2345 
   2346     return (ERR_CODE_NONE);
   2347 }
   2348 
   2349 err_code_t blackhawk_tsc_INTERNAL_display_pll_to_divider(srds_access_t *sa__, uint32_t srds_div) {
   2350     /* Adjust these to increase or decrease the number of digits to the right
   2351      * of the decimal point.
   2352      */
   2353     const uint8_t decimal_digits = 4;
   2354     const uint32_t ten_to_the_decimal_digits = 10000; /* 10**decimal_digits */
   2355 
   2356     /* Not a const, because of carry logic below. */
   2357     uint16_t div_integer = SRDS_INTERNAL_GET_PLL_DIV_INTEGER(srds_div);
   2358 
   2359     if (SRDS_INTERNAL_IS_PLL_DIV_FRACTIONAL(srds_div)) {
   2360         /* fraction_num will have this many bits (ending at bit 0). */
   2361         const uint8_t  fraction_num_width = 28;
   2362         const uint32_t fraction_num = SRDS_INTERNAL_GET_PLL_DIV_FRACTION_NUM(srds_div, fraction_num_width);
   2363 
   2364         /* Identify the number that, when printed with left-padded zeros,
   2365          * becomes the digits to the right of the decimal point.
   2366          *
   2367          * This value can be obtained by dividing fraction_num by:
   2368          *
   2369          *     (2^fraction_num_width)/(10^decimal_digits)
   2370          */
   2371         const uint32_t divisor = (((1 << fraction_num_width) + (ten_to_the_decimal_digits>>1))
   2372                                   / ten_to_the_decimal_digits);
   2373         uint32_t fraction_as_int = (fraction_num + (divisor>>1)) / divisor;
   2374 
   2375         /* In case the rounding above caused the fractional portion to overflow
   2376          * (e.g. 4.9999999999 becomes 5.0000), implement the carry into the
   2377          * integer portion.
   2378          */
   2379         if (fraction_as_int >= ten_to_the_decimal_digits) {
   2380             fraction_as_int -= ten_to_the_decimal_digits;
   2381             ++div_integer;
   2382         }
   2383 
   2384         EFUN_PRINTF(("%3d.%0*d", div_integer, decimal_digits, fraction_as_int));
   2385     } else {
   2386         const uint8_t left_spaces = (decimal_digits + 1) >> 1;
   2387         COMPILER_REFERENCE(left_spaces);
   2388         EFUN_PRINTF(("%*s%3d%*s", left_spaces, "", div_integer, decimal_digits - left_spaces + 1, ""));
   2389     }
   2390     return(ERR_CODE_NONE);
   2391 }
   2392 
   2393 
   2394 err_code_t blackhawk_tsc_INTERNAL_print_uc_dsc_error(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd) {
   2395     uint32_t supp_info;
   2396 
   2397     ESTM(supp_info = (rd_uc_dsc_supp_info()) & 0xFF);
   2398     switch (SUPP_INFO_TO_ERROR_CODE(supp_info)) {
   2399       case UC_CMD_ERROR_INVALID_COMMAND:
   2400         ESTM_PRINTF(("ERROR : UC reported invalid command %d.  (other_info = 0x%X)\n",
   2401                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2402         break;
   2403       case UC_CMD_ERROR_BUSY:
   2404         ESTM_PRINTF(("ERROR : UC reported busy for command %d.  (other_info = 0x%X)\n",
   2405                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2406         break;
   2407       case UC_CMD_ERROR_GET_EYE_SAMPLE_ERROR:
   2408         ESTM_PRINTF(("ERROR : UC reported error in getting eye sample.  (command %d, other_info = 0x%X)\n",
   2409                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2410         break;
   2411       case UC_CMD_ERROR_PRBS_NOT_LOCKED:
   2412         ESTM_PRINTF(("ERROR : UC reported PRBS not locked.  (command %d, other_info = 0x%X)\n",
   2413                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2414         break;
   2415       case UC_CMD_ERROR_COMMAND_IN_PROGRESS:
   2416         ESTM_PRINTF(("ERROR : UC reported command already in progress.  (command %d, other_info = 0x%X)\n",
   2417                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2418         break;
   2419       case UC_CMD_ERROR_INVALID_MODE:
   2420         ESTM_PRINTF(("ERROR : UC reported invalid mode for command %d.  (other_info = 0x%X)\n",
   2421                      cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2422         break;
   2423       default:
   2424         ESTM_PRINTF(("ERROR : UC reported unknown error 0x%X for command %d.  (other_info = 0x%X)\n",
   2425                      SUPP_INFO_TO_ERROR_CODE(supp_info), cmd, SUPP_INFO_TO_OTHER_INFO(supp_info)));
   2426     }
   2427     /* Cleanup cmd register */
   2428     EFUN(reg_wr_DSC_A_DSC_UC_CTRL(0x80));
   2429     EFUN(wr_uc_dsc_data(0));
   2430 
   2431     return(ERR_CODE_NONE);
   2432 }
   2433  
   2434 /******************************************/
   2435 /*  Serdes Register field Poll functions  */
   2436 /******************************************/
   2437 
   2438 #ifndef CUSTOM_REG_POLLING
   2439 /* poll for microcontroller to populate the dsc_data register */
   2440 err_code_t blackhawk_tsc_INTERNAL_poll_diag_done(srds_access_t *sa__, uint16_t *status, uint32_t timeout_ms) {
   2441  uint8_t loop;
   2442 
   2443  if(!status) {
   2444      return(blackhawk_tsc_error(sa__, ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
   2445   }
   2446 
   2447  for(loop=0;loop < 100; loop++) {
   2448      ESTM(*status=rdv_usr_diag_status());
   2449 
   2450      if((*status & 0x8000) > 0) {
   2451          return(ERR_CODE_NONE);
   2452      }
   2453      if(loop>10) {
   2454          EFUN(USR_DELAY_US(10*timeout_ms));
   2455      }
   2456  }
   2457  return(blackhawk_tsc_error(sa__, ERR_CODE_DIAG_TIMEOUT));
   2458 }
   2459 /** Poll for field "uc_dsc_ready_for_cmd" = 1 [Return Val => Error_code (0 = Polling Pass)] */
   2460 err_code_t blackhawk_tsc_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(srds_access_t *sa__, uint32_t timeout_ms, enum srds_pmd_uc_cmd_enum cmd) {
   2461     /* read quickly for 10 tries */
   2462     uint16_t loop;
   2463     uint16_t reset_state;
   2464 
   2465     for (loop = 0; loop < 100; loop++) {
   2466         uint16_t rddata;
   2467         ESTM(rddata = reg_rd_DSC_A_DSC_UC_CTRL());
   2468         if (rddata & 0x0080) {    /* bit 7 is uc_dsc_ready_for_cmd */
   2469             if (rddata & 0x0040) {  /* bit 6 is uc_dsc_error_found   */
   2470                 EFUN(blackhawk_tsc_INTERNAL_print_uc_dsc_error(sa__, cmd));
   2471                 return(blackhawk_tsc_error(sa__, ERR_CODE_UC_CMD_RETURN_ERROR));
   2472             }
   2473             return (ERR_CODE_NONE);
   2474         }
   2475         if(loop>10) {
   2476             EFUN(USR_DELAY_US(10*timeout_ms));
   2477         }
   2478     }
   2479     /* Check if ln_s_rstb is asserted by looking at the reset state, the give a warning and display the commands*/
   2480     ESTM(reset_state = rd_lane_dp_reset_state());
   2481     if (reset_state & 0x0007) {
   2482         EFUN_PRINTF(("DSC ready for command is not working; SerDes is probably reset!\n"));
   2483         return (ERR_CODE_NONE);
   2484     }
   2485     {
   2486         EFUN_PRINTF(("%s ERROR : DSC ready for command is not working, applying workaround and getting debug info !\n", API_FUNCTION_NAME));
   2487         /* print the triage info and reset the cmd interface */
   2488         blackhawk_tsc_INTERNAL_print_triage_info(sa__, ERR_CODE_UC_CMD_POLLING_TIMEOUT, 1, 1, __LINE__);
   2489         /* artifically terminate the command to re-enable the command interface */
   2490         EFUN(wr_uc_dsc_ready_for_cmd(0x1));
   2491     }
   2492     return (ERR_CODE_UC_CMD_POLLING_TIMEOUT);
   2493 }
   2494 
   2495 /* Poll for field "dsc_state" = DSC_STATE_UC_TUNE [Return Val => Error_code (0 = Polling Pass)] */
   2496 err_code_t blackhawk_tsc_INTERNAL_poll_dsc_state_equals_uc_tune(srds_access_t *sa__, uint32_t timeout_ms) {
   2497   uint16_t loop;
   2498   uint16_t dsc_state;
   2499   /* poll 10 times to avoid longer delays later */
   2500   for (loop = 0; loop < 100; loop++) {
   2501     ESTM(dsc_state = rd_dsc_state());
   2502     if (dsc_state == DSC_STATE_UC_TUNE) {
   2503       return (ERR_CODE_NONE);
   2504     }
   2505     if(loop>10) {
   2506         EFUN(USR_DELAY_US(10*timeout_ms));
   2507     }
   2508   }
   2509   ESTM_PRINTF(("DSC_STATE = %d\n", rd_dsc_state()));
   2510   return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT));          /* Error Code for polling timeout */
   2511 }
   2512 
   2513 
   2514 /* Poll for field "micro_ra_initdone" = 1 [Return Val => Error_code (0 = Polling Pass)] */
   2515 err_code_t blackhawk_tsc_INTERNAL_poll_micro_ra_initdone(srds_access_t *sa__, uint32_t timeout_ms) {
   2516   uint16_t loop;
   2517 
   2518   uint8_t result;
   2519   for (loop = 0; loop <= 100; loop++) {
   2520     ESTM(result = rdc_micro_ra_initdone());
   2521     if (result) {
   2522       return (ERR_CODE_NONE);
   2523     }
   2524     EFUN(USR_DELAY_US(10*timeout_ms));
   2525   }
   2526   return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT));          /* Error Code for polling timeout */
   2527 }
   2528 
   2529 #endif /* CUSTOM_REG_POLLING */
   2530 
   2531 int8_t blackhawk_tsc_INTERNAL_afe_slicer_offset_mapping(int8_t x) {
   2532     if (x>=0)
   2533         return(x^((x&2)>>1));   /* XOR bit 0 with bit 1 */
   2534     else
   2535         return(-blackhawk_tsc_INTERNAL_afe_slicer_offset_mapping(-x));
   2536 }
   2537 
   2538 uint8_t blackhawk_tsc_INTERNAL_is_big_endian(void)
   2539 {
   2540     uint32_t one_u32 = 0x01000000;
   2541     char * ptr = (char *)(&one_u32);
   2542     const uint8_t big_endian = (ptr[0] == 1);
   2543     return big_endian;
   2544 }
   2545 
   2546 
   2547 int blackhawk_tsc_INTERNAL_get_endian_offset(uint8_t *addr) {
   2548     const int endian_const = 1;
   2549     return ((*(char*)&endian_const) == 0) ?
   2550         (
   2551         (((USR_UINTPTR)(addr))%4 == 0) ?  3 :
   2552         (((USR_UINTPTR)(addr))%4 == 1) ?  1 :
   2553         (((USR_UINTPTR)(addr))%4 == 2) ? -1 :
   2554         (((USR_UINTPTR)(addr))%4 == 3) ? -3 :
   2555         0)
   2556         : 0;
   2557 }
   2558 
   2559 err_code_t blackhawk_tsc_INTERNAL_rdblk_callback(void *arg, uint8_t byte_count, uint16_t data) {
   2560     srds_access_t *sa__;
   2561     blackhawk_tsc_INTERNAL_rdblk_callback_arg_t * const cast_arg = (blackhawk_tsc_INTERNAL_rdblk_callback_arg_t *)arg;
   2562     int endian_offset = 0;
   2563     sa__ = cast_arg->sa;
   2564 
   2565     ESTM(endian_offset = blackhawk_tsc_INTERNAL_get_endian_offset(cast_arg->mem_ptr));
   2566     *(cast_arg->mem_ptr + endian_offset) = data & 0xFF;
   2567     cast_arg->mem_ptr++;
   2568     if (byte_count == 2) {
   2569         ESTM(endian_offset = blackhawk_tsc_INTERNAL_get_endian_offset(cast_arg->mem_ptr));
   2570         *(cast_arg->mem_ptr + endian_offset) = data >> 8;
   2571         cast_arg->mem_ptr++;
   2572     }
   2573     return (ERR_CODE_NONE);
   2574 }
   2575 
   2576 err_code_t blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram(srds_access_t *sa__,
   2577                                                 uint32_t block_addr,
   2578                                                 uint16_t block_size,
   2579                                                 uint16_t start_offset,
   2580                                                 uint16_t cnt,
   2581                                                 void *arg,
   2582                                                 err_code_t (*callback)(void *, uint8_t, uint16_t)) {
   2583     uint32_t read_val = 0;
   2584     uint8_t defecit = 0;
   2585     uint32_t addr = block_addr + start_offset;
   2586     
   2587     if (cnt == 0) {
   2588         return (ERR_CODE_NONE);
   2589     }
   2590 
   2591     /* Check for bad start offset and block size. */
   2592     if (start_offset >= block_size) {
   2593         return (ERR_CODE_BAD_PTR_OR_INVALID_INPUT);
   2594     }
   2595 
   2596     while (cnt > 0) {
   2597         /* Determine how many bytes to read before wrapping back to start of block. */
   2598         uint16_t block_cnt = SRDS_MIN(cnt, block_addr + block_size - addr);
   2599         cnt -= block_cnt;
   2600 
   2601             /* Set up the word reads. */
   2602             EFUN(wrc_micro_autoinc_rdaddr_en(1));
   2603             EFUN(wrc_micro_ra_rddatasize(0x1));                     /* Select 16bit read datasize */
   2604             EFUN(wrc_micro_ra_rdaddr_msw(addr >> 16));              /* Upper 16bits of RAM address to be read */
   2605             EFUN(wrc_micro_ra_rdaddr_lsw(addr & 0xFFFE));           /* Lower 16bits of RAM address to be read */
   2606 
   2607             /* Read the leading byte, if starting at an odd address. */
   2608             if ((addr & 1) == 1) {
   2609                 ESTM(read_val |= ((rdc_micro_ra_rddata_lsw() >> 8) << defecit));
   2610                 if (defecit == 8) {
   2611                     EFUN(callback(arg, 2, (uint16_t)read_val));
   2612                     read_val = 0;
   2613                 }
   2614                 /* We just read a byte.  This toggles the defecit from 0 to 8 or from 8 to 0. */
   2615                 defecit ^= 8;
   2616                 --block_cnt;
   2617             }
   2618 
   2619             /* Read the whole words, and call the callback with two bytes at a time. */
   2620             while (block_cnt >= 2) {
   2621                 ESTM(read_val |= (rdc_micro_ra_rddata_lsw() << defecit));
   2622                 EFUN(callback(arg, 2, (uint16_t)read_val));
   2623                 read_val >>= 16;
   2624                 /* We just read two bytes.  This preserves whatever defecit (8 or 0) is there. */
   2625                 block_cnt -= 2;
   2626             }
   2627 
   2628             /* Read the trailing byte, if leftover after reading whole words. */
   2629             if (block_cnt > 0) {
   2630                 ESTM(read_val |= ((rdc_micro_ra_rddata_lsw() & 0xFF) << defecit));
   2631                 if (defecit == 8) {
   2632                     EFUN(callback(arg, 2, (uint16_t)read_val));
   2633                     read_val = 0;
   2634                 }
   2635                 /* We just read a byte.  This toggles the defecit from 0 to 8 or from 8 to 0. */
   2636                 defecit ^= 8;
   2637             }
   2638         addr = block_addr;
   2639     }
   2640 
   2641     /* If a final byte is left behind, then call the callback with it. */
   2642     if (defecit > 0) {
   2643         EFUN(callback(arg, 1, (uint16_t)read_val));
   2644     }
   2645 
   2646     return(ERR_CODE_NONE);
   2647 }
   2648 err_code_t blackhawk_tsc_INTERNAL_rdblk_uc_generic_ram_descending(srds_access_t *sa__,
   2649                                                            uint32_t block_addr,
   2650                                                            uint16_t block_size,
   2651                                                            uint16_t start_offset,
   2652                                                            uint16_t cnt,
   2653                                                            void *arg,
   2654                                                            err_code_t (*callback)(void *, uint8_t, uint16_t)) {
   2655     uint32_t read_val = 0;
   2656     uint8_t defecit = 0;
   2657     uint32_t addr = block_addr + start_offset;
   2658     uint16_t configured_addr_msw = (addr >> 16) + 1;
   2659     
   2660     if (cnt == 0) {
   2661         return (ERR_CODE_NONE);
   2662     }
   2663 
   2664     /* Check for bad start offset and block size. */
   2665     if (start_offset >= block_size) {
   2666         return (ERR_CODE_BAD_PTR_OR_INVALID_INPUT);
   2667     }
   2668 
   2669     EFUN(wrc_micro_autoinc_rdaddr_en(0));
   2670     EFUN(wrc_micro_ra_rddatasize(0x1));                         /* Select 16bit read datasize */
   2671     
   2672     while (cnt > 0) {
   2673         /* Determine how many bytes to read before wrapping back to end of block. */
   2674         uint16_t block_cnt = SRDS_MIN(cnt, start_offset+1);
   2675         cnt -= block_cnt;
   2676 
   2677         while (block_cnt > 0) {
   2678             const uint16_t addr_msw = addr >> 16;
   2679             uint16_t read_val2;
   2680             if (addr_msw != configured_addr_msw) {
   2681                 EFUN(wrc_micro_ra_rdaddr_msw(addr_msw));        /* Upper 16bits of RAM address to be read */
   2682                 configured_addr_msw = addr_msw;
   2683             }
   2684             
   2685             EFUN(wrc_micro_ra_rdaddr_lsw(addr & 0xFFFE));       /* Lower 16bits of RAM address to be read */
   2686             ESTM(read_val2 = rdc_micro_ra_rddata_lsw());
   2687 
   2688             if (((addr & 1) == 1) && (block_cnt >= 2)) {
   2689                 /* Reading two bytes.  Since we're reading in descending address order, they
   2690                  * will be reversed before they are sent out. */
   2691                 read_val |= ((((read_val2 & 0xFF) << 8) | (read_val2 >> 8)) << defecit);
   2692                 EFUN(callback(arg, 2, (uint16_t)read_val));
   2693                 read_val >>= 16;
   2694                 /* We just read two bytes.  This preserves whatever defecit (8 or 0) is there. */
   2695                 block_cnt -= 2;
   2696                 addr -= 2;
   2697             } else {
   2698                 if ((addr & 1) == 1) {
   2699                     /* Reading upper byte of word. */
   2700                     read_val |= ((read_val2 >> 8) << defecit);
   2701                 } else {
   2702                     /* Reading lower byte of word. */
   2703                     read_val |= ((read_val2 & 0xFF) << defecit);
   2704                 }
   2705                 if (defecit == 8) {
   2706                     EFUN(callback(arg, 2, (uint16_t)read_val));
   2707                     read_val = 0;
   2708                 }
   2709                 /* We just read a byte.  This toggles the defecit from 0 to 8 or from 8 to 0. */
   2710                 defecit ^= 8;
   2711                 --block_cnt;
   2712                 --addr;
   2713             }
   2714         }
   2715         
   2716         addr = block_addr + block_size - 1;
   2717         start_offset = block_size - 1;
   2718     }
   2719 
   2720     /* If a final byte is left behind, then call the callback with it. */
   2721     if (defecit > 0) {
   2722         EFUN(callback(arg, 1, (uint16_t)read_val));
   2723     }
   2724 
   2725     return(ERR_CODE_NONE);
   2726 }
   2727 
   2728 uint8_t blackhawk_tsc_INTERNAL_grp_idx_from_lane(uint8_t lane) {
   2729     return(lane>>1);
   2730 }
   2731 
   2732 err_code_t blackhawk_tsc_INTERNAL_get_lms_thresh_bin(srds_access_t *sa__, int8_t *lms_thresh_bin) {
   2733     ESTM(*lms_thresh_bin = (int8_t)rd_afe_lms_thresh_bin());
   2734     return(ERR_CODE_NONE);
   2735 }
   2736 
   2737 err_code_t blackhawk_tsc_INTERNAL_poll_dbgfb_idx_lock(srds_access_t *sa__, uint8_t timeout_ms) {
   2738   uint32_t loop, max_loop = 10;
   2739   uint8_t idx_lock = 0;
   2740 
   2741   /* poll for first 10 times and then wait for timeout_ms before polling */
   2742   for (loop = 0; loop < max_loop; loop++) {
   2743       ESTM(idx_lock = rd_dbg_fdbk_idx_lock());
   2744       if (idx_lock) {
   2745           return (ERR_CODE_NONE);
   2746       }
   2747   }
   2748   /* polled for 10 times, wait for timeout_ms right here before polling the register */
   2749   EFUN(blackhawk_tsc_delay_us(timeout_ms * 1000));
   2750   ESTM(idx_lock = rd_dbg_fdbk_idx_lock());
   2751   if (idx_lock) {
   2752       return (ERR_CODE_NONE);
   2753   } else {
   2754       ESTM_PRINTF(("!!!!ERROR!!!! polling for dbgfb idx lock timedout after %d ms \n", timeout_ms));
   2755       /* Error Code for polling timeout */
   2756       return (blackhawk_tsc_error(sa__, ERR_CODE_POLLING_TIMEOUT));
   2757   }
   2758 }
   2759 
   2760 err_code_t blackhawk_tsc_get_dbgfb_summary(srds_access_t *sa__, dbgfb_cfg_st *dbgfb_cfg) {
   2761     uint32_t d_0_n1, d_0_0, d_0_p1, d_1_n1, d_1_0, d_1_p1;
   2762     uint32_t pdet, ndet;
   2763     int32_t tdet;
   2764     enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
   2765 
   2766     EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
   2767     if (pam_mode == NRZ) {
   2768         EFUN_PRINTF(("!!!!ERROR!!!! rx_pam_mode is set to NRZ , blackhawk_tsc_get_dbgfb_summary cannot continue\n"));
   2769         return(ERR_CODE_INVALID_RX_PAM_MODE);
   2770     }
   2771 
   2772     EFUN(wr_dbg_fdbk_en(1));
   2773     EFUN(wr_fdbk_counting_mode(0));
   2774     EFUN(wr_dbg_fdbk_data_threshold(dbgfb_cfg->y));
   2775     EFUN(wr_dbg_fdbk_data_sel(1));
   2776     if (dbgfb_cfg->x) {
   2777         EFUN(wr_inlv_idx(78));
   2778         EFUN(wr_dbg_fdbk_idx(dbgfb_cfg->x -1));
   2779         EFUN(wr_frc_index_diffprec(1));
   2780         EFUN(blackhawk_tsc_INTERNAL_poll_dbgfb_idx_lock(sa__, 100));
   2781         EFUN(wr_frc_index_diffprec(0));
   2782         EFUN(wr_dbg_fdbk_idx_monitor_en(0));
   2783         EFUN(wr_dbg_fdbk_idx_monitor_en(1));
   2784     } else {
   2785         EFUN(wr_dbg_fdbk_idx(1));
   2786         EFUN(wr_dbg_fdbk_idx(0));
   2787         EFUN(wr_dbg_fdbk_idx_monitor_en(0));
   2788     }
   2789     
   2790     EFUN(USR_DELAY_US(dbgfb_cfg->time_in_us));
   2791 
   2792     EFUN(wr_dbg_fdbk_en(0));
   2793     ESTM(d_1_n1 = rd_dbg_fdbk_counter_0());
   2794 
   2795     ESTM(d_1_0  = rd_dbg_fdbk_counter_1());
   2796     ESTM(d_1_p1 = rd_dbg_fdbk_counter_2());
   2797     ESTM(d_0_n1 = rd_dbg_fdbk_counter_3());
   2798     ESTM(d_0_0  = rd_dbg_fdbk_counter_4()); 
   2799     ESTM(d_0_p1 = rd_dbg_fdbk_counter_5()); 
   2800 
   2801     tdet  = d_1_n1 + d_0_p1-d_0_n1 - d_1_p1;
   2802     pdet  = d_1_n1 + d_1_0 + d_1_p1;
   2803     ndet  = d_0_n1 + d_0_0 + d_0_p1; 
   2804     dbgfb_cfg->data2 = pdet;
   2805     dbgfb_cfg->data3 = ndet;
   2806     dbgfb_cfg->data1 = tdet;
   2807     return ERR_CODE_NONE;
   2808 }
   2809 
   2810 err_code_t blackhawk_tsc_collect_dbgfb_stats(srds_access_t *sa__, uint32_t time_in_us, dbgfb_stats_st *dbgfb_stats) {
   2811     uint8_t y, x;
   2812     uint8_t max_y;
   2813     enum blackhawk_tsc_rx_pam_mode_enum pam_mode = NRZ;
   2814     uint8_t pam4es_en = 0;
   2815     dbgfb_cfg_st dbgfb_cfg = {0};
   2816 
   2817     EFUN(blackhawk_tsc_INTERNAL_get_rx_pam_mode(sa__, &pam_mode));
   2818     if (pam_mode == NRZ) {
   2819         EFUN_PRINTF(("!!!!ERROR!!!! rx_pam_mode is set to NRZ , blackhawk_tsc_collect_dbgfb_stats cannot continue\n"));
   2820         return(ERR_CODE_INVALID_RX_PAM_MODE);
   2821     }
   2822     pam4es_en = (pam_mode==PAM4_ES);
   2823     max_y = pam4es_en ? 6 : 3;
   2824     /* backup the measure time and pam4es_en info */
   2825     dbgfb_stats->time_in_us = time_in_us;
   2826     dbgfb_stats->pam4es_en  = pam4es_en; 
   2827 
   2828 
   2829     for (y=0; y < max_y; y++){
   2830         for (x = 0; x < _X_; x++){
   2831             dbgfb_cfg.y = y;
   2832             dbgfb_cfg.x = x;
   2833             dbgfb_cfg.time_in_us = time_in_us;
   2834             dbgfb_cfg.data1 = 0;
   2835             dbgfb_cfg.data2 = 0;
   2836             dbgfb_cfg.data3 = 0;
   2837             EFUN(blackhawk_tsc_get_dbgfb_summary(sa__, &dbgfb_cfg));
   2838             dbgfb_stats->time_in_us = time_in_us;
   2839             dbgfb_stats->data.data1[x][y] = dbgfb_cfg.data1;
   2840             dbgfb_stats->data.data2[x][y] = dbgfb_cfg.data2;
   2841             dbgfb_stats->data.data3[x][y] = dbgfb_cfg.data3;
   2842             dbgfb_stats->data.data4[x][y] = dbgfb_stats->data.data2[x][y] - dbgfb_stats->data.data3[x][y];
   2843 
   2844         }
   2845     }
   2846     return ERR_CODE_NONE;
   2847 }
   2848