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_diagnostics.c (42288B)


      1 
      2 /*
      3  *
      4  * 
      5  *
      6  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      7  * 
      8  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      9  */
     10 
     11 #include <phymod/phymod.h>
     12 #include <phymod/phymod_system.h>
     13 #include <phymod/phymod_util.h>
     14 #include <phymod/phymod_config.h>
     15 #include <phymod/phymod_diagnostics.h>
     16 #include <phymod/phymod_diag.h>
     17 #include <phymod/phymod_diagnostics_dispatch.h>
     18 #include <phymod/chip/blackhawk.h>
     19 #include <phymod/chip/blackhawk_diagnostics.h>
     20 #include "blackhawk/tier1/blackhawk_cfg_seq.h"
     21 #include "blackhawk/tier1/common/srds_api_enum.h"
     22 #include "blackhawk/tier1/blackhawk_tsc_enum.h"
     23 #include "blackhawk/tier1/blackhawk_tsc_common.h"
     24 #include "blackhawk/tier1/blackhawk_tsc_interface.h"
     25 #include "blackhawk/tier1/blackhawk_tsc_dependencies.h"
     26 #include "blackhawk/tier1/blackhawk_tsc_internal.h"
     27 #include "blackhawk/tier1/public/blackhawk_api_uc_vars_rdwr_defns_public.h"
     28 #include "blackhawk/tier1/blackhawk_tsc_access.h"
     29 #include "blackhawk/tier1/blackhawk_tsc_types.h"
     30 
     31 
     32 
     33 #define PATTERN_MAX_LENGTH 240
     34 #ifdef PHYMOD_BLACKHAWK_SUPPORT
     35 
     36 
     37 /*phymod, internal enum mappings*/
     38 STATIC
     39 int _blackhawk_prbs_poly_phymod_to_blackhawk(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *blackhawk_poly)
     40 {
     41     switch(phymod_poly){
     42     case phymodPrbsPoly7:
     43         *blackhawk_poly = PRBS_7;
     44         break;
     45     case phymodPrbsPoly9:
     46         *blackhawk_poly = PRBS_9;
     47         break;
     48     case phymodPrbsPoly11:
     49         *blackhawk_poly = PRBS_11;
     50         break;
     51     case phymodPrbsPoly15:
     52         *blackhawk_poly = PRBS_15;
     53         break;
     54     case phymodPrbsPoly23:
     55         *blackhawk_poly = PRBS_23;
     56         break;
     57     case phymodPrbsPoly31:
     58         *blackhawk_poly = PRBS_31;
     59         break;
     60     case phymodPrbsPoly58:
     61         *blackhawk_poly = PRBS_58;
     62         break;
     63     case phymodPrbsPoly49:
     64         *blackhawk_poly = PRBS_49;
     65         break;
     66     case phymodPrbsPoly10:
     67         *blackhawk_poly = PRBS_10;
     68         break;
     69     case phymodPrbsPoly20:
     70         *blackhawk_poly = PRBS_20;
     71         break;
     72     case phymodPrbsPoly13:
     73         *blackhawk_poly = PRBS_13;
     74         break;
     75     default:
     76         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for blackhawk %u"), phymod_poly));
     77     }
     78     return PHYMOD_E_NONE;
     79 }
     80 
     81 STATIC
     82 int _blackhawk_prbs_poly_blackhawk_to_phymod(enum srds_prbs_polynomial_enum  *blackhawk_poly, phymod_prbs_poly_t *phymod_poly)
     83 {
     84     switch(*blackhawk_poly){
     85     case PRBS_7:
     86         *phymod_poly = phymodPrbsPoly7;
     87         break;
     88     case PRBS_9:
     89         *phymod_poly = phymodPrbsPoly9;
     90         break;
     91     case PRBS_11:
     92         *phymod_poly = phymodPrbsPoly11;
     93         break;
     94     case PRBS_15:
     95         *phymod_poly = phymodPrbsPoly15;
     96         break;
     97     case PRBS_23:
     98         *phymod_poly = phymodPrbsPoly23;
     99         break;
    100     case PRBS_31:
    101         *phymod_poly = phymodPrbsPoly31;
    102         break;
    103     case PRBS_58:
    104         *phymod_poly = phymodPrbsPoly58;
    105         break;
    106     case PRBS_49:
    107         *phymod_poly = phymodPrbsPoly49;
    108         break;
    109     case PRBS_10:
    110         *phymod_poly = phymodPrbsPoly10;
    111         break;
    112     case PRBS_20:
    113         *phymod_poly = phymodPrbsPoly20;
    114         break;
    115     case PRBS_13:
    116         *phymod_poly = phymodPrbsPoly13;
    117         break;
    118     default:
    119         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), *blackhawk_poly));
    120     }
    121     return PHYMOD_E_NONE;
    122 }
    123 
    124 int blackhawk_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position)
    125 {
    126 
    127 
    128     /* Not supported */
    129     PHYMOD_DEBUG_ERROR(("blackhawk_phy_rx_slicer_position_set function is NOT SUPPORTED!!\n"));
    130 
    131 
    132     return PHYMOD_E_NONE;
    133 
    134 }
    135 
    136 int blackhawk_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position)
    137 {
    138 
    139 
    140     /* Not supported */
    141     PHYMOD_DEBUG_ERROR(("blackhawk_phy_rx_slicer_position_get function is NOT SUPPORTED!!\n"));
    142 
    143 
    144     return PHYMOD_E_NONE;
    145 
    146 }
    147 
    148 
    149 int blackhawk_phy_rx_slicer_position_max_get(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position_min, const phymod_slicer_position_t* position_max)
    150 {
    151 
    152 
    153     /* Not supported */
    154     PHYMOD_DEBUG_ERROR(("blackhawk_phy_rx_slicer_position_max_get function is NOT SUPPORTED!!\n"));
    155 
    156 
    157     return PHYMOD_E_NONE;
    158 
    159 }
    160 
    161 
    162 int blackhawk_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs)
    163 {
    164     enum srds_prbs_polynomial_enum blackhawk_poly;
    165     phymod_phy_access_t phy_copy;
    166     int start_lane, num_lane, i;
    167     phymod_firmware_lane_config_t fw_config;
    168 
    169     PHYMOD_IF_ERR_RETURN
    170         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    171     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    172 
    173     /* next to see if the port is PAM4 or not */
    174     PHYMOD_IF_ERR_RETURN
    175         (blackhawk_phy_firmware_lane_config_get(phy, &fw_config));
    176 
    177     PHYMOD_IF_ERR_RETURN(_blackhawk_prbs_poly_phymod_to_blackhawk(prbs->poly, &blackhawk_poly));
    178     /*first check which direction */
    179     for (i = 0; i < num_lane; i++) {
    180         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    181             continue;
    182         }
    183         phy_copy.access.lane_mask = 1 << (start_lane + i);
    184         if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    185             /* if PAM4 speed, use mode 2 */
    186             if (fw_config.ForcePAM4Mode) {
    187                 PHYMOD_IF_ERR_RETURN
    188                     (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_NO_HYSTERESIS,  prbs->invert));
    189             } else {
    190                 PHYMOD_IF_ERR_RETURN
    191                     (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    192             }
    193         } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    194             PHYMOD_IF_ERR_RETURN
    195                 (blackhawk_tsc_config_tx_prbs(&phy_copy.access, blackhawk_poly, prbs->invert));
    196         } else {
    197             /* if PAM4 speed, use mode 2 */
    198             if (fw_config.ForcePAM4Mode) {
    199                 PHYMOD_IF_ERR_RETURN
    200                     (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_NO_HYSTERESIS,  prbs->invert));
    201             } else {
    202                 PHYMOD_IF_ERR_RETURN
    203                     (blackhawk_tsc_config_rx_prbs(&phy_copy.access, blackhawk_poly,PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    204             }
    205             PHYMOD_IF_ERR_RETURN
    206                 (blackhawk_tsc_config_tx_prbs(&phy_copy.access, blackhawk_poly, prbs->invert));
    207         }
    208     }
    209     return PHYMOD_E_NONE;
    210 }
    211 
    212 int blackhawk_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs)
    213 {
    214     phymod_prbs_t config_tmp;
    215     enum srds_prbs_polynomial_enum blackhawk_poly;
    216     enum srds_prbs_checker_mode_enum prbs_checker_mode;
    217     phymod_phy_access_t phy_copy;
    218     uint8_t invert;
    219 
    220     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    221 
    222 
    223     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    224         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_config(&phy_copy.access, &blackhawk_poly, &invert));
    225         config_tmp.invert = invert;
    226         PHYMOD_IF_ERR_RETURN(_blackhawk_prbs_poly_blackhawk_to_phymod(&blackhawk_poly, &config_tmp.poly));
    227         prbs->invert = config_tmp.invert;
    228         prbs->poly = config_tmp.poly;
    229     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    230         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_config(&phy_copy.access,
    231                                                                 &blackhawk_poly,
    232                                                                 &prbs_checker_mode,
    233                                                                 &invert));
    234         config_tmp.invert = invert;
    235         PHYMOD_IF_ERR_RETURN(_blackhawk_prbs_poly_blackhawk_to_phymod(&blackhawk_poly, &config_tmp.poly));
    236         prbs->invert = config_tmp.invert;
    237         prbs->poly = config_tmp.poly;
    238     } else {
    239         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_config(&phy_copy.access, &blackhawk_poly,  &invert));
    240         config_tmp.invert = invert;
    241         PHYMOD_IF_ERR_RETURN(_blackhawk_prbs_poly_blackhawk_to_phymod(&blackhawk_poly, &config_tmp.poly));
    242         prbs->invert = config_tmp.invert;
    243         prbs->poly = config_tmp.poly;
    244     }
    245     return PHYMOD_E_NONE;
    246 }
    247 
    248 int blackhawk_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable)
    249 {
    250     phymod_phy_access_t phy_copy;
    251     int start_lane, num_lane, i;
    252 
    253     PHYMOD_IF_ERR_RETURN
    254         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    255     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    256 
    257     /*first check which direction */
    258     for (i = 0; i < num_lane; i++) {
    259         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    260             continue;
    261         }
    262         phy_copy.access.lane_mask = 1 << (start_lane + i);
    263         if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    264             PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_prbs_en(&phy_copy.access, enable));
    265         } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    266             PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rx_prbs_en(&phy_copy.access, enable));
    267         } else {
    268             PHYMOD_IF_ERR_RETURN(blackhawk_tsc_tx_prbs_en(&phy_copy.access, enable));
    269             PHYMOD_IF_ERR_RETURN(blackhawk_tsc_rx_prbs_en(&phy_copy.access, enable));
    270         }
    271     }
    272     return PHYMOD_E_NONE;
    273 }
    274 
    275 int blackhawk_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable)
    276 {
    277     uint8_t enable_tmp;
    278     phymod_phy_access_t phy_copy;
    279 
    280     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    281 
    282     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    283         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_en(&phy_copy.access, &enable_tmp));
    284         *enable = enable_tmp;
    285     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    286         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_en(&phy_copy.access, &enable_tmp));
    287         *enable = enable_tmp;
    288     } else {
    289         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_tx_prbs_en(&phy_copy.access, &enable_tmp));
    290         *enable = enable_tmp;
    291         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_rx_prbs_en(&phy_copy.access, &enable_tmp));
    292         *enable &= enable_tmp;
    293     }
    294 
    295     return PHYMOD_E_NONE;
    296 
    297 }
    298 
    299 
    300 int blackhawk_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status)
    301 {
    302     uint8_t status = 0;
    303     uint32_t prbs_err_count = 0;
    304     int i, start_lane, num_lane;
    305     phymod_phy_access_t phy_copy;
    306 
    307     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    308     /* next figure out the lane num and start_lane based on the input */
    309     PHYMOD_IF_ERR_RETURN
    310         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    311 
    312     prbs_status->prbs_lock = 0;
    313     prbs_status->error_count = 0;
    314     prbs_status->prbs_lock_loss = 0;
    315     prbs_status->prbs_lock = 1;
    316 
    317     for (i = 0; i < num_lane; i++) {
    318         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    319             continue;
    320         }
    321         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    322         PHYMOD_IF_ERR_RETURN(blackhawk_tsc_prbs_chk_lock_state(&phy_copy.access, &status));
    323     if (status) {
    324         /*next check the lost of lock and error count */
    325         status = 0;
    326         PHYMOD_IF_ERR_RETURN
    327                 (blackhawk_tsc_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status));
    328         PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count));
    329         if (status) {
    330         /*temp lost of lock */
    331             prbs_status->prbs_lock_loss = 1;
    332         } else {
    333                 prbs_status->error_count += prbs_err_count;
    334         }
    335     } else {
    336             PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i ));
    337             prbs_status->prbs_lock = 0;
    338             /* return PHYMOD_E_NONE; */
    339         }
    340     }
    341     return PHYMOD_E_NONE;
    342 
    343 }
    344 
    345 
    346 int blackhawk_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern)
    347 {
    348     int i,j = 0, bit;
    349     char patt[PATTERN_MAX_LENGTH+1];
    350     phymod_phy_access_t phy_copy;
    351 
    352     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    353 
    354     for (i=0; i< PATTERN_MAX_SIZE; i++)
    355     {
    356       for (j=0;j<32 && i*32+j <= PATTERN_MAX_LENGTH; j++)
    357       {
    358           if (i*32+j == pattern->pattern_len) {
    359               break;
    360           }
    361           bit = pattern->pattern[i] >> j & 00000001;
    362           switch (bit) {
    363           case (1):
    364               patt[i*32+j] = '1';
    365               break;
    366           default:
    367               patt[i*32+j] = '0';
    368               break;
    369           }
    370       }
    371       if (i*32+j == pattern->pattern_len && i*32+j <= PATTERN_MAX_LENGTH) {
    372           /* coverity[overrun-local] */
    373           patt[i*32+j] = '\0';
    374           break;
    375       }
    376     }
    377     /* coverity[divide_by_zero : FALSE] */
    378     PHYMOD_IF_ERR_RETURN
    379             (blackhawk_tsc_config_shared_tx_pattern (&phy_copy.access,
    380 				(uint8_t) pattern->pattern_len, (const char *) patt));
    381     return PHYMOD_E_NONE;
    382 
    383 }
    384 
    385 int blackhawk_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern)
    386 {
    387     phymod_phy_access_t phy_copy;
    388 
    389     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    390     PHYMOD_IF_ERR_RETURN
    391         (blackhawk_tsc_config_shared_tx_pattern_idx_get(&phy_copy.access,
    392                                   &pattern->pattern_len,
    393                                   pattern->pattern));
    394 
    395     return PHYMOD_E_NONE;
    396 
    397 }
    398 
    399 
    400 int blackhawk_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, const phymod_pattern_t* pattern)
    401 {
    402     phymod_phy_access_t phy_copy;
    403 
    404     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    405     PHYMOD_IF_ERR_RETURN
    406         (blackhawk_tsc_tx_shared_patt_gen_en(&phy_copy.access, (uint8_t) enable, (uint8_t)pattern->pattern_len));
    407     return PHYMOD_E_NONE;
    408 
    409 }
    410 
    411 int blackhawk_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    412 {
    413     phymod_phy_access_t phy_copy;
    414     uint8_t enable_8;
    415 
    416     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    417     PHYMOD_IF_ERR_RETURN
    418        (blackhawk_tsc_tx_shared_patt_gen_en_get(&phy_copy.access, &enable_8));
    419 
    420     *enable = enable_8;
    421     return PHYMOD_E_NONE;
    422 
    423 }
    424 
    425 
    426 int blackhawk_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag)
    427 {
    428 
    429     return PHYMOD_E_NONE;
    430 }
    431 
    432 
    433 int blackhawk_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag)
    434 {
    435 
    436     return PHYMOD_E_NONE;
    437 }
    438 
    439 int blackhawk_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type)
    440 {
    441     int start_lane, num_lane;
    442     uint32_t i, j, tmp_lane_mask;
    443     phymod_phy_access_t phy_copy;
    444 
    445     phymod_diag_type_t cmd_type;
    446     srds_info_t  *tsc_info_ptr = NULL;
    447 
    448     if (!type) {
    449         cmd_type = phymod_diag_DSC;
    450     } else if ((!PHYMOD_STRCMP(type, "ber")) ||
    451                (!PHYMOD_STRCMP(type, "Ber")) ||
    452                (!PHYMOD_STRCMP(type, "BER"))) {
    453         cmd_type = phymod_diag_BER;
    454     } else if ((!PHYMOD_STRCMP(type, "config")) ||
    455                (!PHYMOD_STRCMP(type, "Config")) ||
    456                (!PHYMOD_STRCMP(type, "CONFIG"))) {
    457         cmd_type = phymod_diag_CFG;
    458     } else if ((!PHYMOD_STRCMP(type, "cl72")) ||
    459                (!PHYMOD_STRCMP(type, "Cl72")) ||
    460                (!PHYMOD_STRCMP(type, "CL72"))) {
    461         cmd_type = phymod_diag_CL72;
    462     } else if ((!PHYMOD_STRCMP(type, "debug")) ||
    463                (!PHYMOD_STRCMP(type, "Debug")) ||
    464                (!PHYMOD_STRCMP(type, "DEBUG"))) {
    465         cmd_type = phymod_diag_DEBUG;
    466     } else if ((!PHYMOD_STRCMP(type, "state")) ||
    467                (!PHYMOD_STRCMP(type, "State")) ||
    468                (!PHYMOD_STRCMP(type, "STATE"))) {
    469         cmd_type = phymod_diag_STATE;
    470     } else if ((!PHYMOD_STRCMP(type, "verbose")) ||
    471                (!PHYMOD_STRCMP(type, "Verbose")) ||
    472                (!PHYMOD_STRCMP(type, "VERBOSE"))) {
    473         cmd_type = phymod_diag_ALL;
    474     } else if (!PHYMOD_STRCMP(type, "STD")) {
    475         cmd_type = phymod_diag_DSC_STD;
    476     } else {
    477         cmd_type = phymod_diag_STATE;
    478     }
    479 
    480     PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask  = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask));
    481 
    482     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    483 
    484     /* Make sure information table is initialized */
    485     tsc_info_ptr = blackhawk_tsc_INTERNAL_get_blackhawk_tsc_info_ptr(&phy_copy.access);
    486     if (tsc_info_ptr->signature == 0) {
    487      PHYMOD_IF_ERR_RETURN
    488             (blackhawk_tsc_init_blackhawk_tsc_info(&phy_copy.access));
    489     }
    490     /*next figure out the lane num and start_lane based on the input*/
    491     PHYMOD_IF_ERR_RETURN
    492         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    493 
    494     if (cmd_type == phymod_diag_DSC) {
    495        for (i = start_lane; i < start_lane + num_lane; i++) {
    496             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, i)) {
    497                 continue;
    498             }
    499             phy_copy.access.lane_mask = 0x1 << i ;
    500             PHYMOD_IF_ERR_RETURN
    501                 (blackhawk_tsc_display_diag_data(&phy_copy.access, SRDS_DIAG_CORE));
    502        }
    503     } else if (cmd_type == phymod_diag_DSC_STD) {
    504 
    505             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    506             PHYMOD_DIAG_OUT(("    | DSC Phy: 0x%03x lane_mask: 0x%02x                                 |\n", phy->access.addr, phy->access.lane_mask));
    507             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    508              tmp_lane_mask = phy_copy.access.lane_mask;
    509              for (j = 0; j < 8; j++) {
    510                phy_copy.access.lane_mask = 0x1 << j;
    511                PHYMOD_IF_ERR_RETURN
    512                   (blackhawk_tsc_display_diag_data(&phy_copy.access, SRDS_DIAG_CORE | SRDS_DIAG_LANE | SRDS_DIAG_EVENT));
    513              }
    514 
    515     } else {
    516         for (i = 0; i < num_lane; i++) {
    517             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    518                 continue;
    519             }
    520             phy_copy.access.lane_mask = 1 << (start_lane + i);
    521 
    522             switch (cmd_type) {
    523             case phymod_diag_CFG:
    524                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    525                 if(i==0) {
    526                     tmp_lane_mask = phy_copy.access.lane_mask;
    527                     phy_copy.access.lane_mask = 1;
    528                     PHYMOD_IF_ERR_RETURN
    529                         (blackhawk_tsc_display_core_config(&phy_copy.access));
    530                     phy_copy.access.lane_mask = tmp_lane_mask;
    531                 }
    532                 PHYMOD_IF_ERR_RETURN
    533                     (blackhawk_tsc_display_lane_config(&phy_copy.access));
    534                 break;
    535 
    536 #if 0 
    537             casephymod_diag_CL72:
    538                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    539                 PHYMOD_IF_ERR_RETURN
    540                     (blackhawk_tsc_display_cl93n72_status(&phy_copy.access));
    541                 break;
    542 #endif
    543 
    544             case phymod_diag_DEBUG:
    545                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    546                 PHYMOD_IF_ERR_RETURN
    547                     (blackhawk_tsc_display_lane_debug_status(&phy_copy.access));
    548                 break;
    549 
    550             case phymod_diag_BER:
    551                 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__));
    552                 break;
    553 
    554             /*
    555              * COVERITY
    556              *
    557              * TEFMOD_DIAG_ALL branch involve information in TEFMOD_DIAG_STATE branch
    558              */
    559             /* coverity[unterminated_case] */
    560             case phymod_diag_ALL:
    561                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    562                 if(i==0) {
    563                     tmp_lane_mask = phy_copy.access.lane_mask;
    564                     phy_copy.access.lane_mask = 1;
    565                     PHYMOD_IF_ERR_RETURN
    566                         (blackhawk_tsc_display_core_config(&phy_copy.access));
    567                     phy_copy.access.lane_mask = tmp_lane_mask;
    568                 }
    569                 PHYMOD_IF_ERR_RETURN
    570                     (blackhawk_tsc_display_lane_config(&phy_copy.access));
    571 
    572 #if 0  
    573                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    574                 PHYMOD_IF_ERR_RETURN
    575                     (blackhawk_tsc_display_cl93n72_status(&phy_copy.access));
    576 #endif
    577 
    578                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    579                 PHYMOD_IF_ERR_RETURN
    580                     (blackhawk_tsc_display_lane_debug_status(&phy_copy.access));
    581                 break;
    582 
    583             case phymod_diag_STATE:
    584             default:
    585                 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__));
    586                 for (j = 0; j < 8; j++) {
    587                      phy_copy.access.lane_mask = 0x1 << j;
    588                      if (j==0){
    589                          PHYMOD_IF_ERR_RETURN
    590                             (blackhawk_tsc_display_diag_data(&phy_copy.access, SRDS_DIAG_CORE | SRDS_DIAG_LANE | SRDS_DIAG_EVENT | SRDS_DIAG_REG_LANE | SRDS_DIAG_REG_CORE | SRDS_DIAG_UC_LANE | SRDS_DIAG_UC_CORE));
    591                      } else {
    592                          PHYMOD_IF_ERR_RETURN
    593                             (blackhawk_tsc_display_diag_data(&phy_copy.access, SRDS_DIAG_LANE | SRDS_DIAG_EVENT | SRDS_DIAG_REG_LANE | SRDS_DIAG_UC_LANE ));
    594                      }
    595                  }
    596                 break;
    597             }
    598         }
    599     }
    600     return PHYMOD_E_NONE;
    601 }
    602 
    603 static void _blackhawk_diag_uc_reg_dump(phymod_access_t *pa)
    604 {
    605     err_code_t errc;
    606 
    607     COMPILER_REFERENCE(errc);
    608 
    609     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    610     PHYMOD_DIAG_OUT(("|    MICRO CODE USR CTRL CONFIGURATION REGISTERS  |\n"));
    611     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    612     PHYMOD_DIAG_OUT(("|    config_word              [0x00]: 0x%04X      |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0x0)));
    613     PHYMOD_DIAG_OUT(("|    usr_misc_ctrl_word       [0x04]: 0x%04X      |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0x4)));
    614     PHYMOD_DIAG_OUT(("|    retune_after_restart     [0x06]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x6)));
    615     PHYMOD_DIAG_OUT(("|    clk90_offset_adjust      [0x07]: 0x%04X      |\n",    blackhawk_tsc_rdbls_uc_var(pa,&errc,0x7)));
    616     PHYMOD_DIAG_OUT(("|    clk90_offset_override    [0x08]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x8)));
    617     PHYMOD_DIAG_OUT(("|    lane_event_log_level     [0x09]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x9)));
    618     PHYMOD_DIAG_OUT(("|    pam4_chn_loss            [0x0A]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0xa)));
    619     PHYMOD_DIAG_OUT(("|    cl93n72_frc_byte         [0x0B]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0xb)));
    620     PHYMOD_DIAG_OUT(("|    disable_startup          [0x0C]: 0x%04X      |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0xc)));
    621     PHYMOD_DIAG_OUT(("|    disable_steady_state     [0x0E]: 0x%04X      |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0xe)));
    622     PHYMOD_DIAG_OUT(("|    disable_startup_dfe      [0x10]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x10)));
    623     PHYMOD_DIAG_OUT(("|    disable_steady_state_dfe [0x11]: 0x%04X      |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x11)));
    624     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    625     PHYMOD_DIAG_OUT(("|         MICRO CODE USER STATUS REGISTERS        |\n"));
    626     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    627     PHYMOD_DIAG_OUT(("|    restart_counter          [0x12]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x12)));
    628     PHYMOD_DIAG_OUT(("|    reset_counter            [0x13]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x13)));
    629     PHYMOD_DIAG_OUT(("|    pmd_lock_counter         [0x14]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x14)));
    630     PHYMOD_DIAG_OUT(("|    heye_left                [0x15]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x15)));
    631     PHYMOD_DIAG_OUT(("|    heye_right               [0x16]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x16)));
    632     PHYMOD_DIAG_OUT(("|    veye_upper               [0x17]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x17)));
    633     PHYMOD_DIAG_OUT(("|    veye_lower               [0x18]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x18)));
    634     PHYMOD_DIAG_OUT(("|    micro_stopped            [0x19]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x19)));
    635     PHYMOD_DIAG_OUT(("|    link_time                [0x1C]: 0x%04X     |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0x1c)));
    636     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    637     PHYMOD_DIAG_OUT(("|            MICRO CODE MISC REGISTERS            |\n"));
    638     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    639     PHYMOD_DIAG_OUT(("|    usr_diag_status          [0x1E]: 0x%04X     |\n",    blackhawk_tsc_rdwl_uc_var(pa,&errc,0x1e)));
    640     PHYMOD_DIAG_OUT(("|    usr_diag_rd_ptr          [0x20]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x20)));
    641     PHYMOD_DIAG_OUT(("|    usr_diag_mode            [0x21]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x21)));
    642     PHYMOD_DIAG_OUT(("|    usr_main_tap_est         [0x22]: 0x%04X     |\n",    blackhawk_tsc_rdwls_uc_var(pa,&errc,0x22)));
    643     PHYMOD_DIAG_OUT(("|    usr_sts_phase_hoffset    [0x24]: 0x%04X     |\n",    blackhawk_tsc_rdbls_uc_var(pa,&errc,0x24)));
    644     PHYMOD_DIAG_OUT(("|    usr_diag_wr_ptr          [0x25]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x25)));
    645     PHYMOD_DIAG_OUT(("|    status_byte              [0x26]: 0x%04X     |\n",    blackhawk_tsc_rdbl_uc_var(pa,&errc,0x26)));
    646     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    647 }
    648 
    649 STATIC int blackhawk_diagnostics_eyescan_run_uc(const phymod_phy_access_t* phy, uint32_t flags)
    650 {
    651     int                 rc = PHYMOD_E_NONE;
    652     int                 j ;
    653     phymod_phy_access_t phy_copy;
    654 
    655     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    656 
    657     if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    658         for(j=0; j< PHYMOD_CONFIG_MAX_LANES_PER_CORE; j++) { /* Loop for all lanes. */
    659             if ((phy->access.lane_mask & (1<<j))==0) continue;
    660 
    661             phy_copy.access.lane_mask = (phy->access.lane_mask & (1<<j));
    662 
    663             PHYMOD_DIAG_OUT(("\n\n\n"));
    664             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    665             PHYMOD_DIAG_OUT(("    | EYESCAN Phy: 0x%03x lane_mask: 0x%02x                                 |\n", phy_copy.access.addr, phy_copy.access.lane_mask));
    666             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    667 
    668             rc  = blackhawk_tsc_display_eye_scan(&(phy_copy.access));
    669             if(rc != PHYMOD_E_NONE) {
    670                 _blackhawk_diag_uc_reg_dump(&(phy_copy.access));
    671                 PHYMOD_IF_ERR_RETURN(rc);
    672             }
    673         }
    674     }
    675     return PHYMOD_E_NONE;
    676 }
    677 
    678 int blackhawk_diagnostics_eye_margin_proj( const phymod_phy_access_t* phy, uint32_t flags,
    679                                         const phymod_phy_eyescan_options_t* eyescan_options)
    680 {
    681 #ifdef SERDES_API_FLOATING_POINT
    682   int osr_mode;
    683   USR_DOUBLE data_rate, data_rate_in_Mhz;
    684   phymod_phy_access_t phy_copy;
    685   int start_lane, num_lane, i, found=0;
    686   phymod_phy_speed_config_t speed_config;
    687 
    688   struct   blackhawk_tsc_uc_core_config_st core_cfg;
    689   if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    690      PHYMOD_IF_ERR_RETURN
    691         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    692      PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    693      for (i = 0; i < num_lane; i++) {
    694          phy_copy.access.lane_mask = 1 << (start_lane + i);
    695 
    696          if (found == 0) {
    697              PHYMOD_IF_ERR_RETURN(blackhawk_tsc_get_uc_core_config(&(phy_copy.access), &core_cfg));
    698              PHYMOD_IF_ERR_RETURN(blackhawk_osr_mode_get(&phy_copy.access, &osr_mode));
    699              PHYMOD_IF_ERR_RETURN(phymod_phy_speed_config_t_init(&speed_config));
    700              PHYMOD_IF_ERR_RETURN(blackhawk_phy_speed_config_get(phy, &speed_config));
    701              data_rate = speed_config.data_rate * 1000.0 * 1000.0;
    702              data_rate_in_Mhz = speed_config.data_rate;
    703              found = 1;
    704          }
    705          if(num_lane > 1) {
    706              PHYMOD_DIAG_OUT((" l=%0d, baud rate  = %fMB/s \n", i, data_rate_in_Mhz));
    707          } else {
    708              PHYMOD_DIAG_OUT((" baud rate       = %fMB/s \n", data_rate_in_Mhz));
    709          }
    710          PHYMOD_IF_ERR_RETURN(blackhawk_tsc_eye_margin_proj(&phy_copy.access, data_rate, eyescan_options->ber_proj_scan_mode,
    711                                     eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt));
    712      }
    713   }
    714 #else
    715       PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("BER Proj is supported with SERDES_API_FLOATING_POINT only\n")));
    716 #endif
    717 
    718   return PHYMOD_E_NONE;
    719 }
    720 
    721 int blackhawk_phy_eyescan_run(const phymod_phy_access_t* phy,
    722                            uint32_t flags,
    723                            phymod_eyescan_mode_t mode,
    724                            const phymod_phy_eyescan_options_t* eyescan_options)
    725 {
    726     uint8_t  pmd_rx_lock=0;
    727     phymod_phy_access_t phy_copy;
    728 
    729     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    730 
    731     PHYMOD_IF_ERR_RETURN
    732       (blackhawk_tsc_pmd_lock_status(&phy_copy.access, &pmd_rx_lock));
    733 
    734     if(pmd_rx_lock == 0) {
    735       PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Can not get eyescan when pmd_rx is not locked\n")));
    736     }
    737 
    738     /* If stage isn't set - perform all stages*/
    739     if(!PHYMOD_EYESCAN_F_ENABLE_GET(flags)
    740        && !PHYMOD_EYESCAN_F_PROCESS_GET(flags)
    741        && !PHYMOD_EYESCAN_F_DONE_GET(flags))
    742     {
    743         PHYMOD_EYESCAN_F_ENABLE_SET(flags);
    744         PHYMOD_EYESCAN_F_PROCESS_SET(flags);
    745         PHYMOD_EYESCAN_F_DONE_SET(flags);
    746     }
    747 
    748     /* mode phymodEyescanModeBERProj gives BER projection */
    749     switch(mode) {
    750         case phymodEyescanModeFast:
    751             return blackhawk_diagnostics_eyescan_run_uc(phy, flags);
    752         case phymodEyescanModeBERProj:
    753             return blackhawk_diagnostics_eye_margin_proj(phy, flags, eyescan_options);
    754         default:
    755             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported eyescan mode %u"), mode));
    756     }
    757 
    758   return PHYMOD_E_NONE;
    759 }
    760 
    761 int blackhawk_phy_PAM4_tx_pattern_enable_set(const phymod_phy_access_t* phy, phymod_PAM4_tx_pattern_t pattern_type, uint32_t enable)
    762 {
    763     phymod_phy_access_t phy_copy;
    764 
    765     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    766 
    767     switch (pattern_type) {
    768     case phymod_PAM4TxPattern_JP03B:
    769         PHYMOD_IF_ERR_RETURN
    770             (blackhawk_tsc_config_tx_jp03b_pattern(&phy_copy.access, (uint8_t) enable));
    771         break;
    772     case phymod_PAM4TxPattern_Linear:
    773         PHYMOD_IF_ERR_RETURN
    774             (blackhawk_tsc_config_tx_linearity_pattern(&phy_copy.access, (uint8_t) enable));
    775         break;
    776     default:
    777         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported PAM4 tx pattern  %u"), pattern_type));
    778     }
    779     return PHYMOD_E_NONE;
    780 
    781 }
    782 
    783 int blackhawk_phy_PAM4_tx_pattern_enable_get(const phymod_phy_access_t* phy, phymod_PAM4_tx_pattern_t pattern_type, uint32_t* enable)
    784 {
    785     phymod_phy_access_t phy_copy;
    786 
    787     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    788 
    789     PHYMOD_IF_ERR_RETURN
    790         (blackhawk_tsc_pam4_tx_pattern_enable_get(&phy_copy.access, pattern_type, enable));
    791     return PHYMOD_E_NONE;
    792 
    793 }
    794 
    795 int _blackhawk_phy_post_fec_ber_proj(const phymod_phy_access_t* phy, const phymod_phy_ber_proj_options_t* options)
    796 {
    797     phymod_phy_access_t phy_copy;
    798     uint8_t default_hist_errcnt_thresh = 1;
    799     uint8_t default_prbs_errcnt_thresh;
    800     uint8_t hist_errcnt_thresh = 0, prbs_errcnt_thresh = 0;
    801     int timeout_s;
    802     blackhawk_tsc_prbs_err_analyzer_errcnt_st err_analyzer;
    803     int start_lane, num_lane, i;
    804 
    805     PHYMOD_IF_ERR_RETURN(phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    806     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    807 
    808     switch (options->ber_proj_phase) {
    809         case PHYMOD_BER_PROJ_PHASE_F_PRE:
    810             /* This is pre-config stage. Only needed when
    811              * options->ber_proj_hist_errcnt_thresh == 0.
    812              */
    813             if (options->ber_proj_fec_size == 0) {
    814                 /* If user use unsupported FEC type, Portmod will set fec_size to 0.
    815                  * So here we check whether fec_size equals to 0. If so, return error.
    816                  */
    817                 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM,
    818                                        (_PHYMOD_MSG("Unsupported FEC type for Post FEC BER Projection.")));
    819             }
    820 
    821             default_prbs_errcnt_thresh = default_hist_errcnt_thresh + 8;
    822             for (i = 0; i < num_lane; i++) {
    823                 phy_copy.access.lane_mask = 1 << (start_lane + i);
    824                 /* Configure PRBS Error Analyzer */
    825                 PHYMOD_IF_ERR_RETURN
    826                     (blackhawk_tsc_prbs_error_analyzer_config(&phy_copy.access,
    827                                                               options->ber_proj_fec_size,
    828                                                               default_prbs_errcnt_thresh,
    829                                                               default_hist_errcnt_thresh));
    830             }
    831             break;
    832         case PHYMOD_BER_PROJ_PHASE_F_CONFIG:
    833             if (options->ber_proj_fec_size == 0) {
    834                 /* If user use unsupported FEC type, Portmod will set fec_size to 0.
    835                  * So here we check whether fec_size equals to 0. If so, return error.
    836                  */
    837                 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("Unsupported FEC type for Post FEC BER Projection.")));
    838             }
    839             /* PLP team recommend 5% proj_timeout value as the timeout_s to get optimized thershold */
    840             /* 99 is used to generate CEIL function of 5% of timeout_s */
    841             timeout_s = (options->ber_proj_timeout_s * 5 + 99)/ 100;
    842 
    843             for (i = 0; i < num_lane; i++) {
    844                 phy_copy.access.lane_mask = 1 << (start_lane + i);
    845                 PHYMOD_DIAG_OUT(("\nConfigure PRBS Error Analyzer: Phy: 0x%03x, Lane: 0x%01x", phy->access.addr, start_lane+i));
    846                 if ((options->ber_proj_hist_errcnt_thresh == 0)) {
    847                     PHYMOD_DIAG_OUT(("\n------------------------------------------------------------------------------------------------\n"));
    848                     /* Use optimized Hist_Errcnt_Threshold */
    849                     /* Initialize err cnt */
    850                     PHYMOD_MEMSET(&err_analyzer, 0, sizeof(blackhawk_tsc_prbs_err_analyzer_errcnt_st));
    851                     /* Get the error count */
    852                     PHYMOD_IF_ERR_RETURN
    853                         (blackhawk_tsc_prbs_error_analyzer_accumulate_err_count(&phy_copy.access, &err_analyzer));
    854                     /* Get the optimized hist errcnt threshold. */
    855                     PHYMOD_IF_ERR_RETURN
    856                         (blackhawk_tsc_optimize_hist_errcnt_thresh(&phy_copy.access,
    857                                                                    &err_analyzer,
    858                                                                    timeout_s,
    859                                                                    options->ber_proj_timeout_s));
    860                     hist_errcnt_thresh = err_analyzer.hist_errcnt_thresh;
    861                     PHYMOD_DIAG_OUT(("------------------------------------------------------------------------------------------------\n"));
    862                 } else if (options->ber_proj_hist_errcnt_thresh > 7) {
    863                     PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("hist_errcnt_threshold is out of range. Valid range is [1,7].")));
    864                 } else {
    865                     hist_errcnt_thresh = options->ber_proj_hist_errcnt_thresh;
    866                 }
    867                 prbs_errcnt_thresh = hist_errcnt_thresh + 8;
    868                 PHYMOD_IF_ERR_RETURN
    869                     (blackhawk_tsc_prbs_error_analyzer_config(&phy_copy.access,
    870                                                               options->ber_proj_fec_size,
    871                                                               prbs_errcnt_thresh,
    872                                                               hist_errcnt_thresh));
    873                 PHYMOD_IF_ERR_RETURN
    874                     (blackhawk_tsc_display_prbs_error_analyzer_config(&phy_copy.access, prbs_errcnt_thresh, hist_errcnt_thresh, options->ber_proj_timeout_s));
    875             }
    876             break;
    877         case PHYMOD_BER_PROJ_PHASE_F_START:
    878             for (i = 0; i < num_lane; i++) {
    879                 phy_copy.access.lane_mask = 1 << (start_lane + i);
    880                 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_error_analyzer_status_clear(&phy_copy.access));
    881             }
    882             break;
    883         case PHYMOD_BER_PROJ_PHASE_F_COLLECT:
    884             for (i = 0; i < num_lane; i++) {
    885                 phy_copy.access.lane_mask = 1 << (start_lane + i);
    886                 PHYMOD_MEMSET(&err_analyzer, 0, sizeof(blackhawk_tsc_prbs_err_analyzer_errcnt_st));
    887                 PHYMOD_MEMCPY(err_analyzer.prbs_errcnt, options->ber_proj_prbs_errcnt[i].prbs_errcnt, sizeof(err_analyzer.prbs_errcnt));
    888                 PHYMOD_IF_ERR_RETURN(
    889                     blackhawk_tsc_prbs_error_analyzer_accumulate_err_count(&phy_copy.access, &err_analyzer));
    890                 PHYMOD_MEMCPY(options->ber_proj_prbs_errcnt[i].prbs_errcnt, err_analyzer.prbs_errcnt, sizeof(err_analyzer.prbs_errcnt));
    891             }
    892             break;
    893         case PHYMOD_BER_PROJ_PHASE_F_CAL:
    894             for (i = 0; i < num_lane; i++) {
    895                 phy_copy.access.lane_mask = 1 << (start_lane + i);
    896                 PHYMOD_MEMSET(&err_analyzer, 0, sizeof(blackhawk_tsc_prbs_err_analyzer_errcnt_st));
    897                 if ((options->ber_proj_hist_errcnt_thresh == 0)) {
    898                     PHYMOD_IF_ERR_RETURN(
    899                         blackhawk_tsc_prbs_error_analyzer_accumulate_err_count(&phy_copy.access, &err_analyzer));
    900                 } else {
    901                     err_analyzer.hist_errcnt_thresh = options->ber_proj_hist_errcnt_thresh;
    902                     err_analyzer.prbs_errcnt_thresh = options->ber_proj_hist_errcnt_thresh + 8;
    903                 }
    904                 PHYMOD_MEMCPY(err_analyzer.prbs_errcnt, options->ber_proj_prbs_errcnt[i].prbs_errcnt, sizeof(err_analyzer.prbs_errcnt));
    905                 PHYMOD_DIAG_OUT(("\nPost-FEC BER: Phy: 0x%03x, Lane: 0x%01x", phy->access.addr, start_lane+i));
    906                 PHYMOD_IF_ERR_RETURN(blackhawk_tsc_display_prbs_error_analyzer_err_count(&phy_copy.access, err_analyzer));
    907                 PHYMOD_IF_ERR_RETURN(
    908                     blackhawk_tsc_prbs_error_analyzer_compute_proj(&phy_copy.access, err_analyzer, options->ber_proj_timeout_s));
    909             }
    910             break;
    911         default:
    912             return PHYMOD_E_PARAM;
    913     }
    914     return PHYMOD_E_NONE;
    915 }
    916 
    917 /* BER Projection*/
    918 int blackhawk_phy_ber_proj(const phymod_phy_access_t* phy, phymod_ber_proj_mode_t mode, const phymod_phy_ber_proj_options_t* options)
    919 {
    920     switch (mode) {
    921         case phymodBERProjModePostFEC:
    922             PHYMOD_IF_ERR_RETURN(_blackhawk_phy_post_fec_ber_proj(phy, options));
    923             break;
    924         default:
    925             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported BER PROJECTION mode  %u"), mode));
    926     }
    927     return PHYMOD_E_NONE;
    928 }
    929 
    930 /* fast BER Projection get*/
    931 int blackhawk_phy_fast_ber_proj_get(const phymod_phy_access_t* phy, uint32_t* ber_proj_data)
    932 {
    933     struct ber_data_st ber_data_local;
    934     int start_lane, num_lane;
    935     phymod_phy_access_t phy_copy;
    936 
    937     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    938 
    939     /* next figure out the lane num and start_lane based on the input */
    940     PHYMOD_IF_ERR_RETURN
    941         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    942 
    943     phy_copy.access.lane_mask = 0x1 << start_lane;
    944 
    945     /* collect prbs in 100 ms */
    946     PHYMOD_IF_ERR_RETURN
    947         (blackhawk_tsc_INTERNAL_get_BER_data(&phy_copy.access, 100, &ber_data_local, 0));
    948 
    949     /* first check if PRBS enabled or prbs lost lock */
    950     if ((ber_data_local.prbs_chk_en == 0) || (ber_data_local.lcklost == 1)) {
    951         *ber_proj_data = 0xffffffff;
    952     } else {
    953         uint16_t x = 0,y = 0,z = 0,div;
    954 
    955         if (COMPILER_64_GE(ber_data_local.num_errs, ber_data_local.num_bits)) {
    956             x = 1;
    957             y = 0;
    958             z = 0;
    959         } else {
    960             uint64_t tmp_num_errs, tmp_num_bits, tmp_div;
    961             while (1) {
    962                 /*
    963                  * div = (uint16_t)(((ber_data_local.num_errs<<1) + ber_data_local.num_bits)/(ber_data_local.num_bits<<1));
    964                  */
    965                 COMPILER_64_COPY(tmp_num_errs, ber_data_local.num_errs);
    966                 COMPILER_64_COPY(tmp_num_bits, ber_data_local.num_bits);
    967 
    968                 /* first check if the  number of error is 0 or the error is too small */
    969                 if (COMPILER_64_IS_ZERO(tmp_num_errs) || (z > 40))  {
    970                     /* the prbs error count is too small to have a meaningful estimate, return 0 */
    971                     *ber_proj_data = 0;
    972                     return PHYMOD_E_NONE;
    973                 }
    974                 /* ber_data_local.num_errs << 1 */
    975                 COMPILER_64_SHL(tmp_num_errs, 1);
    976 
    977                 /* (ber_data_local.num_errs << 1) + ber_data_local.num_bits */
    978                 COMPILER_64_ADD_64(tmp_num_errs, ber_data_local.num_bits);
    979 
    980                 /* ber_data_local.num_bits << 1 */
    981                 COMPILER_64_SHL(tmp_num_bits, 1);
    982 
    983                 COMPILER_64_COPY(tmp_div, tmp_num_errs);
    984                 COMPILER_64_UDIV_64(tmp_div, tmp_num_bits);
    985                 div = (uint16_t)(COMPILER_64_LO(tmp_div));
    986 
    987                 if (div >= 10) break;
    988                 /*
    989                  * ber_data_local.num_errs = ber_data_local.num_errs*10;
    990                  */
    991                 COMPILER_64_UMUL_32(ber_data_local.num_errs, (uint32_t) 10);
    992                 z = z + 1;
    993             }
    994             if(div >= 100) {
    995                 div = div / 10;
    996                 z = z - 1;
    997             }
    998             x = div / 10;
    999             y = div - 10 * x;
   1000             z = z - 1;
   1001         }
   1002         *ber_proj_data = x << 24 | y << 16 | z;
   1003     }
   1004 
   1005     return PHYMOD_E_NONE;
   1006 }
   1007 
   1008 
   1009 #endif /* PHYMOD_BLACKHAWK_SUPPORT */