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

falcon_diagnostics.c (32544B)


      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_diagnostics_dispatch.h>
     17 
     18 #include "../../tscf/tier1/tefmod_enum_defines.h" 
     19 #include "../../falcon/tier1/falcon_cfg_seq.h"
     20 #include "../../falcon/tier1/falcon_tsc_enum.h"
     21 #include "../../falcon/tier1/falcon_tsc_common.h"
     22 #include "../../falcon/tier1/falcon_tsc_interface.h"
     23 #include "../../falcon/tier1/falcon_tsc_dependencies.h"
     24 #include "../../falcon/tier1/falcon_tsc_debug_functions.h"
     25 
     26 
     27 #define PATTERN_MAX_LENGTH 240
     28 #ifdef PHYMOD_FALCON_SUPPORT
     29 
     30 
     31 /*phymod, internal enum mappings*/
     32 STATIC
     33 int _falcon_prbs_poly_phymod_to_falcon(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *falcon_poly)
     34 {
     35     switch(phymod_poly){
     36     case phymodPrbsPoly7:
     37         *falcon_poly = PRBS_7;
     38         break;
     39     case phymodPrbsPoly9:
     40         *falcon_poly = PRBS_9;
     41         break;
     42     case phymodPrbsPoly11:
     43         *falcon_poly = PRBS_11;
     44         break;
     45     case phymodPrbsPoly15:
     46         *falcon_poly = PRBS_15;
     47         break;
     48     case phymodPrbsPoly23:
     49         *falcon_poly = PRBS_23;
     50         break;
     51     case phymodPrbsPoly31:
     52         *falcon_poly = PRBS_31;
     53         break;
     54     case phymodPrbsPoly58:
     55         *falcon_poly = PRBS_58;
     56         break;
     57     default:
     58         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly));
     59     }
     60     return PHYMOD_E_NONE;
     61 }
     62 
     63 STATIC
     64 int _falcon_prbs_poly_tscf_to_phymod(falcon_prbs_polynomial_type_t tscf_poly, phymod_prbs_poly_t *phymod_poly)
     65 {
     66     switch(tscf_poly){
     67     case FALCON_PRBS_POLYNOMIAL_7:
     68         *phymod_poly = phymodPrbsPoly7;
     69         break;
     70     case FALCON_PRBS_POLYNOMIAL_9:
     71         *phymod_poly = phymodPrbsPoly9;
     72         break;
     73     case FALCON_PRBS_POLYNOMIAL_11:
     74         *phymod_poly = phymodPrbsPoly11;
     75         break;
     76     case FALCON_PRBS_POLYNOMIAL_15:
     77         *phymod_poly = phymodPrbsPoly15;
     78         break;
     79     case FALCON_PRBS_POLYNOMIAL_23:
     80         *phymod_poly = phymodPrbsPoly23;
     81         break;
     82     case FALCON_PRBS_POLYNOMIAL_31:
     83         *phymod_poly = phymodPrbsPoly31;
     84         break;
     85     case FALCON_PRBS_POLYNOMIAL_58:
     86         *phymod_poly = phymodPrbsPoly58;
     87         break;
     88     default:
     89         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tscf_poly));
     90     }
     91     return PHYMOD_E_NONE;
     92 }
     93 
     94 int falcon_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position)
     95 {
     96         
     97     
     98     /* Not supported */
     99     PHYMOD_DEBUG_ERROR(("falcon_phy_rx_slicer_position_set function is NOT SUPPORTED!!\n"));
    100 
    101         
    102     return PHYMOD_E_NONE;
    103     
    104 }
    105 
    106 int falcon_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position)
    107 {
    108         
    109     
    110     /* Not supported */
    111     PHYMOD_DEBUG_ERROR(("falcon_phy_rx_slicer_position_get function is NOT SUPPORTED!!\n"));
    112 
    113         
    114     return PHYMOD_E_NONE;
    115     
    116 }
    117 
    118 
    119 int falcon_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)
    120 {
    121         
    122     
    123     /* Not supported */
    124     PHYMOD_DEBUG_ERROR(("falcon_phy_rx_slicer_position_max_get function is NOT SUPPORTED!!\n"));
    125 
    126         
    127     return PHYMOD_E_NONE;
    128     
    129 }
    130 
    131 
    132 int falcon_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs)
    133 {
    134     enum srds_prbs_polynomial_enum falcon_poly;
    135     phymod_phy_access_t phy_copy;
    136     int start_lane, num_lane, i;
    137 
    138     PHYMOD_IF_ERR_RETURN
    139         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    140     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    141 
    142     PHYMOD_IF_ERR_RETURN(_falcon_prbs_poly_phymod_to_falcon(prbs->poly, &falcon_poly));
    143     /*first check which direction */
    144     for (i = 0; i < num_lane; i++) {
    145         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    146             continue;
    147         }
    148         phy_copy.access.lane_mask = 1 << (start_lane + i);
    149         if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    150             PHYMOD_IF_ERR_RETURN
    151                 (falcon_tsc_config_rx_prbs(&phy_copy.access, falcon_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    152         } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    153             PHYMOD_IF_ERR_RETURN
    154                 (falcon_tsc_config_tx_prbs(&phy_copy.access, falcon_poly, prbs->invert));
    155         } else {
    156             PHYMOD_IF_ERR_RETURN
    157                 (falcon_tsc_config_rx_prbs(&phy_copy.access, falcon_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    158             PHYMOD_IF_ERR_RETURN
    159                 (falcon_tsc_config_tx_prbs(&phy_copy.access, falcon_poly, prbs->invert));
    160         }
    161     }
    162     return PHYMOD_E_NONE;
    163 }
    164 
    165 int falcon_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs)
    166 {
    167     phymod_prbs_t config_tmp;
    168     falcon_prbs_polynomial_type_t tscf_poly;
    169 
    170     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    171         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert));
    172         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_poly_get(&phy->access, &tscf_poly));
    173         PHYMOD_IF_ERR_RETURN(_falcon_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    174         prbs->invert = config_tmp.invert;
    175         prbs->poly = config_tmp.poly;
    176     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    177         PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert));
    178         PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_poly_get(&phy->access, &tscf_poly));
    179         PHYMOD_IF_ERR_RETURN(_falcon_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    180         prbs->invert = config_tmp.invert;
    181         prbs->poly = config_tmp.poly;
    182     } else {
    183         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert));
    184         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_poly_get(&phy->access, &tscf_poly));
    185         PHYMOD_IF_ERR_RETURN(_falcon_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    186         prbs->invert = config_tmp.invert;
    187         prbs->poly = config_tmp.poly;
    188     }
    189     return PHYMOD_E_NONE;
    190 }
    191 
    192 
    193 int falcon_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable)
    194 {
    195     phymod_phy_access_t phy_copy;
    196     int start_lane, num_lane, i;
    197 
    198     PHYMOD_IF_ERR_RETURN
    199         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    200     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    201 
    202     /*first check which direction */
    203     for (i = 0; i < num_lane; i++) {
    204         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    205             continue;
    206         }
    207         phy_copy.access.lane_mask = 1 << (start_lane + i);
    208         if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    209             PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_prbs_en(&phy_copy.access, enable));
    210         } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    211             PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_prbs_en(&phy_copy.access, enable));
    212         } else {
    213             PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_prbs_en(&phy_copy.access, enable));
    214             PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_prbs_en(&phy_copy.access, enable));
    215         }
    216     }
    217     return PHYMOD_E_NONE;
    218 }
    219 
    220 int falcon_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable)
    221 {
    222     uint32_t enable_tmp;
    223     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    224         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_enable_get(&phy->access, &enable_tmp));
    225         *enable = enable_tmp;
    226     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    227         PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_enable_get(&phy->access, &enable_tmp));
    228         *enable = enable_tmp;
    229     } else {
    230         PHYMOD_IF_ERR_RETURN(falcon_prbs_tx_enable_get(&phy->access, &enable_tmp));
    231         *enable = enable_tmp;
    232         PHYMOD_IF_ERR_RETURN(falcon_prbs_rx_enable_get(&phy->access, &enable_tmp));
    233         *enable &= enable_tmp;
    234     }
    235 
    236     return PHYMOD_E_NONE;
    237     
    238 }
    239 
    240 
    241 int falcon_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status)
    242 {
    243     uint8_t status = 0;
    244     uint32_t prbs_err_count = 0;
    245 
    246     PHYMOD_IF_ERR_RETURN(falcon_tsc_prbs_chk_lock_state(&phy->access, &status));
    247     if (status) {
    248         prbs_status->prbs_lock = 1;
    249         /*next check the lost of lock and error count */
    250         status = 0;
    251         PHYMOD_IF_ERR_RETURN
    252             (falcon_tsc_prbs_err_count_state(&phy->access, &prbs_err_count, &status));
    253         if (status) {
    254         /*temp lost of lock */
    255             prbs_status->prbs_lock_loss = 1;
    256         } else {
    257             prbs_status->prbs_lock_loss = 0;
    258             prbs_status->error_count = prbs_err_count;
    259         }
    260     } else {
    261         prbs_status->prbs_lock = 0;
    262     }
    263 
    264     return PHYMOD_E_NONE;
    265     
    266 }
    267 
    268 
    269 int falcon_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern)
    270 {
    271     int i,j = 0, bit;
    272     char patt[PATTERN_MAX_LENGTH+1];
    273     for (i=0; i< PATTERN_MAX_SIZE; i++)
    274     {
    275       for (j=0;j<32 && i*32+j <= PATTERN_MAX_LENGTH; j++)
    276       {
    277           if (i*32+j == pattern->pattern_len) {
    278               break;
    279           }
    280           bit = pattern->pattern[i] >> j & 00000001;
    281           switch (bit) {
    282           case (1):
    283               patt[i*32+j] = '1';
    284               break;
    285           default:
    286               patt[i*32+j] = '0';
    287               break;
    288           }
    289       }
    290       if (i*32+j == pattern->pattern_len && i*32+j <= PATTERN_MAX_LENGTH) {
    291           /* coverity[overrun-local] */
    292           patt[i*32+j] = '\0';
    293           break;
    294       }
    295     }
    296     PHYMOD_IF_ERR_RETURN
    297             (falcon_tsc_config_shared_tx_pattern_idx_set(&phy->access,
    298                                   &pattern->pattern_len ));
    299     PHYMOD_IF_ERR_RETURN
    300             (falcon_tsc_config_shared_tx_pattern (&phy->access,
    301                                 (uint8_t) pattern->pattern_len, (const char *) patt));
    302         
    303     return PHYMOD_E_NONE;
    304     
    305 }
    306 
    307 int falcon_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern)
    308 {
    309         
    310     PHYMOD_IF_ERR_RETURN
    311         (falcon_tsc_config_shared_tx_pattern_idx_get(&phy->access,
    312                                   &pattern->pattern_len, 
    313                                   pattern->pattern));
    314         
    315     return PHYMOD_E_NONE;
    316     
    317 }
    318 
    319 
    320 int falcon_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable, phymod_pattern_t* pattern)
    321 {
    322     PHYMOD_IF_ERR_RETURN
    323         (falcon_tsc_tx_shared_patt_gen_en(&phy->access, (uint8_t) enable, (uint8_t)pattern->pattern_len));
    324     return PHYMOD_E_NONE;
    325     
    326 }
    327 
    328 int falcon_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    329 {
    330     uint8_t enable_8;
    331     PHYMOD_IF_ERR_RETURN
    332        (falcon_tsc_tx_shared_patt_gen_en_get(&phy->access, &enable_8));
    333     *enable = (uint32_t) enable_8;
    334     return PHYMOD_E_NONE;
    335     
    336 }
    337 
    338 
    339 int falcon_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag)
    340 {
    341     int16_t temperature;
    342 
    343     falcon_tsc_read_die_temperature(&core->access, &temperature);
    344     diag->temperature = temperature;
    345 
    346     falcon_tsc_read_pll_range(&core->access, &diag->pll_range);
    347 
    348     return PHYMOD_E_NONE;
    349 }
    350 
    351 
    352 int falcon_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag)
    353 {
    354         
    355     unsigned char rx_lock;
    356     int osr_mode;
    357     phymod_diag_eyescan_t_init(&diag->eyescan);
    358     phymod_diag_slicer_offset_t_init(&diag->slicer_offset);
    359 
    360     PHYMOD_IF_ERR_RETURN(falcon_tsc_pmd_lock_status(&phy->access, &rx_lock));
    361     diag->rx_lock = (uint32_t ) rx_lock;
    362     PHYMOD_IF_ERR_RETURN(falcon_osr_mode_get(&phy->access, &osr_mode));
    363     switch(osr_mode) {
    364         case 0: diag->osr_mode = phymodOversampleMode1; break;
    365         case 1: diag->osr_mode = phymodOversampleMode2; break;
    366         case 2: diag->osr_mode = phymodOversampleMode4; break;
    367         case 5: diag->osr_mode = phymodOversampleMode8; break;
    368         case 8: diag->osr_mode = phymodOversampleMode16P5; break;
    369         case 12: diag->osr_mode = phymodOversampleMode20P625; break;
    370         default: 
    371             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode));
    372     }
    373     PHYMOD_IF_ERR_RETURN(falcon_tsc_signal_detect(&phy->access, &diag->signal_detect));
    374 
    375     return PHYMOD_E_NONE;
    376 }
    377 
    378 int falcon_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type)
    379 {
    380     int start_lane, num_lane;
    381     int tmp_lane_mask;
    382     phymod_phy_access_t phy_copy;
    383     struct falcon_tsc_detailed_lane_status_st lane_st[4];
    384     int i = 0;
    385     int j = 0;
    386 
    387     uint32_t cmd_type;
    388 
    389     uint8_t trace_mem[768];
    390 
    391     if (!type) {
    392         cmd_type = (uint32_t)TEFMOD_DIAG_DSC;
    393     } else if ((!PHYMOD_STRCMP(type, "ber")) ||
    394                (!PHYMOD_STRCMP(type, "Ber")) ||
    395                (!PHYMOD_STRCMP(type, "BER"))) {
    396         cmd_type = (uint32_t)TEFMOD_DIAG_BER;
    397     } else if ((!PHYMOD_STRCMP(type, "config")) ||
    398                (!PHYMOD_STRCMP(type, "Config")) ||
    399                (!PHYMOD_STRCMP(type, "CONFIG"))) {
    400         cmd_type = (uint32_t)TEFMOD_DIAG_CFG;
    401     } else if ((!PHYMOD_STRCMP(type, "cl72")) ||
    402                (!PHYMOD_STRCMP(type, "Cl72")) ||
    403                (!PHYMOD_STRCMP(type, "CL72"))) {
    404         cmd_type = (uint32_t)TEFMOD_DIAG_CL72;
    405     } else if ((!PHYMOD_STRCMP(type, "debug")) ||
    406                (!PHYMOD_STRCMP(type, "Debug")) ||
    407                (!PHYMOD_STRCMP(type, "DEBUG"))) {
    408         cmd_type = (uint32_t)TEFMOD_DIAG_DEBUG;
    409     } else if ((!PHYMOD_STRCMP(type, "state")) ||
    410                (!PHYMOD_STRCMP(type, "State")) ||
    411                (!PHYMOD_STRCMP(type, "STATE"))) {
    412         cmd_type = (uint32_t)TEFMOD_DIAG_STATE;
    413     } else if ((!PHYMOD_STRCMP(type, "verbose")) ||
    414                (!PHYMOD_STRCMP(type, "Verbose")) ||
    415                (!PHYMOD_STRCMP(type, "VERBOSE"))) {
    416         cmd_type = (uint32_t)TEFMOD_DIAG_ALL;
    417     } else if (!PHYMOD_STRCMP(type, "STD")) {
    418         cmd_type = (uint32_t)TEFMOD_DIAG_DSC_STD;
    419     } else {
    420         cmd_type = (uint32_t)TEFMOD_DIAG_STATE;
    421     }
    422 
    423     PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask  = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask));
    424 
    425     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    426  
    427     /*next figure out the lane num and start_lane based on the input*/
    428     PHYMOD_IF_ERR_RETURN
    429         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    430 
    431     if (cmd_type == TEFMOD_DIAG_DSC) {
    432        PHYMOD_IF_ERR_RETURN
    433            (falcon_tsc_display_core_state(&phy_copy.access));
    434        PHYMOD_IF_ERR_RETURN
    435            (falcon_tsc_display_lane_state_hdr(&phy_copy.access)); 
    436        for (i = 0; i < 4; i++) {
    437             phy_copy.access.lane_mask = 0x1 << i ;
    438             PHYMOD_IF_ERR_RETURN
    439                 (falcon_tsc_display_lane_state(&phy_copy.access));
    440        }
    441     } else if (cmd_type == TEFMOD_DIAG_DSC_STD) {
    442 
    443             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    444             PHYMOD_DIAG_OUT(("    | DSC Phy: 0x%03x lane_mask: 0x%02x                                 |\n", phy->access.addr, phy->access.lane_mask));
    445             PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    446             PHYMOD_IF_ERR_RETURN
    447                 (falcon_tsc_display_core_state(&phy_copy.access));
    448              PHYMOD_IF_ERR_RETURN
    449                 (falcon_tsc_display_lane_state_hdr(&phy_copy.access));
    450              PHYMOD_IF_ERR_RETURN
    451                 (falcon_tsc_display_lane_state(&phy_copy.access));
    452              tmp_lane_mask = phy_copy.access.lane_mask;
    453              for (j = 0; j < 4; j++) {
    454                phy_copy.access.lane_mask = 0x1 << j;
    455                PHYMOD_IF_ERR_RETURN
    456                   (falcon_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j]));
    457              }
    458              phy_copy.access.lane_mask = tmp_lane_mask;
    459              PHYMOD_IF_ERR_RETURN
    460                 (falcon_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4));
    461              PHYMOD_IF_ERR_RETURN
    462                 (falcon_tsc_read_event_log((&phy_copy.access), trace_mem, 2));
    463                  
    464     } else {
    465         for (i = 0; i < num_lane; i++) {
    466             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    467             
    468             switch (cmd_type) {
    469             case TEFMOD_DIAG_CFG:
    470                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    471                 if(i==0) {
    472                     tmp_lane_mask = phy_copy.access.lane_mask;
    473                     phy_copy.access.lane_mask = 1;
    474                     PHYMOD_IF_ERR_RETURN
    475                         (falcon_tsc_display_core_config(&phy_copy.access));
    476                     phy_copy.access.lane_mask = tmp_lane_mask;
    477                 }
    478                 PHYMOD_IF_ERR_RETURN
    479                     (falcon_tsc_display_lane_config(&phy_copy.access));
    480                 break;
    481                 
    482             case TEFMOD_DIAG_CL72:
    483                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    484                 PHYMOD_IF_ERR_RETURN
    485                     (falcon_tsc_display_cl93n72_status(&phy_copy.access));
    486                 break;
    487                 
    488             case TEFMOD_DIAG_DEBUG:
    489                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    490                 PHYMOD_IF_ERR_RETURN
    491                     (falcon_tsc_display_lane_debug_status(&phy_copy.access));
    492                 break;
    493                 
    494             case TEFMOD_DIAG_BER:
    495                 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__));
    496                 break;
    497                 
    498             /*
    499              * COVERITY
    500              *
    501              * TEFMOD_DIAG_ALL branch involve information in TEFMOD_DIAG_STATE branch
    502              */
    503             /* coverity[unterminated_case] */
    504             case TEFMOD_DIAG_ALL:
    505                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    506                 if(i==0) {
    507                     tmp_lane_mask = phy_copy.access.lane_mask;
    508                     phy_copy.access.lane_mask = 1;
    509                     PHYMOD_IF_ERR_RETURN
    510                         (falcon_tsc_display_core_config(&phy_copy.access));
    511                     phy_copy.access.lane_mask = tmp_lane_mask;
    512                 }
    513                 PHYMOD_IF_ERR_RETURN
    514                     (falcon_tsc_display_lane_config(&phy_copy.access));
    515 
    516                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    517                 PHYMOD_IF_ERR_RETURN
    518                     (falcon_tsc_display_cl93n72_status(&phy_copy.access));
    519 
    520                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    521                 PHYMOD_IF_ERR_RETURN
    522                     (falcon_tsc_display_lane_debug_status(&phy_copy.access));
    523 
    524             case TEFMOD_DIAG_STATE:
    525             default:
    526                 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__));
    527                 PHYMOD_IF_ERR_RETURN
    528                     (falcon_tsc_display_core_state(&phy_copy.access));
    529                 PHYMOD_IF_ERR_RETURN
    530                     (falcon_tsc_display_lane_state_hdr(&phy_copy.access));
    531                 PHYMOD_IF_ERR_RETURN
    532                     (falcon_tsc_display_lane_state(&phy_copy.access));
    533                 tmp_lane_mask = phy_copy.access.lane_mask;
    534                 for (j = 0; j < 4; j++) {
    535                      phy_copy.access.lane_mask = 0x1 << j;
    536                      PHYMOD_IF_ERR_RETURN
    537                          (falcon_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j]));
    538                  }
    539                 phy_copy.access.lane_mask = tmp_lane_mask;
    540                 PHYMOD_IF_ERR_RETURN
    541                     (falcon_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4));
    542                 PHYMOD_IF_ERR_RETURN
    543                     (falcon_tsc_read_event_log((&phy_copy.access), trace_mem, 2));
    544                 break;
    545             }
    546         }
    547     }
    548     return PHYMOD_E_NONE;
    549 }
    550 
    551 STATIC err_code_t falcon_phy_meas_lowber_eye (const phymod_access_t *pa, 
    552                                      const phymod_phy_eyescan_options_t* eyescan_options,
    553                                      uint32_t *buffer) 
    554 {
    555     struct falcon_tsc_eyescan_options_st e_options;
    556 
    557     e_options.linerate_in_khz = eyescan_options->linerate_in_khz;
    558     e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds;
    559     e_options.horz_max = eyescan_options->horz_max;
    560     e_options.horz_min = eyescan_options->horz_min;
    561     e_options.hstep = eyescan_options->hstep;
    562     e_options.vert_max = eyescan_options->vert_max;
    563     e_options.vert_min = eyescan_options->vert_min;
    564     e_options.vstep = eyescan_options->vstep;
    565     e_options.mode = eyescan_options->mode;
    566 
    567     return (falcon_tsc_meas_lowber_eye(pa, e_options, buffer));
    568 }
    569 
    570 STATIC err_code_t falcon_phy_display_lowber_eye (const phymod_access_t *pa, 
    571                                         const phymod_phy_eyescan_options_t* eyescan_options,
    572                                         uint32_t *buffer) 
    573 {
    574     struct falcon_tsc_eyescan_options_st e_options;
    575 
    576     e_options.linerate_in_khz = eyescan_options->linerate_in_khz;
    577     e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds;
    578     e_options.horz_max = eyescan_options->horz_max;
    579     e_options.horz_min = eyescan_options->horz_min;
    580     e_options.hstep = eyescan_options->hstep;
    581     e_options.vert_max = eyescan_options->vert_max*2;
    582     e_options.vert_min = eyescan_options->vert_min*2;
    583     e_options.vstep = eyescan_options->vstep*2;
    584     e_options.mode = eyescan_options->mode;
    585 
    586     return(falcon_tsc_display_lowber_eye (pa, e_options, buffer)); 
    587 } 
    588 
    589 static void _falcon_diag_uc_reg_dump(const phymod_access_t *pa)
    590 {
    591     err_code_t errc;
    592 
    593     COMPILER_REFERENCE(errc);
    594 
    595     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    596     PHYMOD_DIAG_OUT(("|    MICRO CODE USR CTRL CONFIGURATION REGISTERS  |\n"));
    597     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    598     PHYMOD_DIAG_OUT(("|    config_word              [0x00]: 0x%04X      |\n",    falcon_tsc_rdwl_uc_var(pa,&errc,0x0)));
    599     PHYMOD_DIAG_OUT(("|    retune_after_restart     [0x02]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x2)));
    600     PHYMOD_DIAG_OUT(("|    clk90_offset_adjust      [0x03]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x3)));
    601     PHYMOD_DIAG_OUT(("|    clk90_offset_override    [0x04]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x4)));
    602     PHYMOD_DIAG_OUT(("|    lane_event_log_level     [0x05]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x5)));
    603     PHYMOD_DIAG_OUT(("|    disable_startup          [0x06]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x6)));
    604     PHYMOD_DIAG_OUT(("|    disable_startup_dfe      [0x07]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x7)));
    605     PHYMOD_DIAG_OUT(("|    disable_steady_state     [0x08]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x8)));
    606     PHYMOD_DIAG_OUT(("|    disable_steady_state_dfe [0x09]: 0x%04X      |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x9)));
    607     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    608     PHYMOD_DIAG_OUT(("|         MICRO CODE USER STATUS REGISTERS        |\n"));
    609     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    610     PHYMOD_DIAG_OUT(("|    restart_counter           [0x0A]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xa)));
    611     PHYMOD_DIAG_OUT(("|    reset_counter             [0x0B]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xb)));
    612     PHYMOD_DIAG_OUT(("|    pmd_lock_counter          [0x0C]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xc)));
    613     PHYMOD_DIAG_OUT(("|    heye_left                 [0x0D]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xd)));
    614     PHYMOD_DIAG_OUT(("|    heye_left_lsbyte          [0x0E]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xe)));
    615     PHYMOD_DIAG_OUT(("|    heye_right                [0x0F]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0xf)));
    616     PHYMOD_DIAG_OUT(("|    heye_right_lsbyte         [0x10]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x10)));
    617     PHYMOD_DIAG_OUT(("|    veye_upper                [0x11]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x11)));
    618     PHYMOD_DIAG_OUT(("|    veye_upper_lsbyte         [0x12]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x12)));
    619     PHYMOD_DIAG_OUT(("|    veye_lower                [0x13]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x13)));
    620     PHYMOD_DIAG_OUT(("|    veye_lower_lsbyte         [0x14]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x14)));
    621     PHYMOD_DIAG_OUT(("|    micro_stopped             [0x15]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x15)));
    622     PHYMOD_DIAG_OUT(("|    link_time                 [0x16]: 0x%04X     |\n",    falcon_tsc_rdwl_uc_var(pa,&errc,0x16)));
    623     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    624     PHYMOD_DIAG_OUT(("|            MICRO CODE MISC REGISTERS            |\n"));
    625     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    626     PHYMOD_DIAG_OUT(("|    usr_diag_status           [0x18]: 0x%04X     |\n",    falcon_tsc_rdwl_uc_var(pa,&errc,0x18)));
    627     PHYMOD_DIAG_OUT(("|    usr_diag_rd_ptr           [0x1A]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x1a)));
    628     PHYMOD_DIAG_OUT(("|    usr_diag_mode             [0x1B]: 0x%04X     |\n",    falcon_tsc_rdbl_uc_var(pa,&errc,0x1b)));
    629     PHYMOD_DIAG_OUT(("|    usr_var_msb               [0x1C]: 0x%04X     |\n",    falcon_tsc_rdwl_uc_var(pa,&errc,0x1c)));
    630     PHYMOD_DIAG_OUT(("|    usr_var_lsb               [0x1E]: 0x%04X     |\n",    falcon_tsc_rdwl_uc_var(pa,&errc,0x1e)));
    631     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    632 }
    633 
    634 STATIC int falcon_diagnostics_eyescan_run_uc(const phymod_phy_access_t* phy, uint32_t flags)   
    635 {
    636     int                 ii, rc = PHYMOD_E_NONE;
    637     uint32_t            stripe[64];
    638     uint16_t            status;
    639     int                 j ;
    640     phymod_phy_access_t phy_copy;
    641     
    642   PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    643 
    644   for(j=0; j< PHYMOD_CONFIG_MAX_LANES_PER_CORE; j++) { /* Loop for all lanes. */
    645     if ((phy->access.lane_mask & (1<<j))==0) continue;
    646 
    647     phy_copy.access.lane_mask = (phy->access.lane_mask & (1<<j));
    648 
    649     if(PHYMOD_EYESCAN_F_ENABLE_GET(flags)) {
    650         PHYMOD_IF_ERR_RETURN(falcon_tsc_meas_eye_scan_start(&(phy_copy.access), 0));
    651 
    652         if(!PHYMOD_EYESCAN_F_ENABLE_DONT_WAIT_GET(flags)) {
    653             PHYMOD_USLEEP(100000);
    654         }
    655     }
    656 
    657     if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    658 
    659         for (ii = 62; ii >= -62; ii=ii-2) { 
    660             if (ii == 62) {
    661                 PHYMOD_DIAG_OUT(("\n\n\n"));
    662                 PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    663                 PHYMOD_DIAG_OUT(("    | EYESCAN Phy: 0x%03x lane_mask: 0x%02x                                 |\n", phy_copy.access.addr, phy_copy.access.lane_mask));
    664                 PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    665                 /*display eyescan header*/
    666                 PHYMOD_IF_ERR_RETURN(falcon_tsc_display_eye_scan_header(&(phy_copy.access), 1));
    667             }
    668 
    669             rc  = falcon_tsc_read_eye_scan_stripe(&(phy_copy.access), stripe, &status);
    670             if(rc != PHYMOD_E_NONE) {
    671                 _falcon_diag_uc_reg_dump(&(phy_copy.access));
    672                 PHYMOD_IF_ERR_RETURN(rc);
    673             }
    674             PHYMOD_IF_ERR_RETURN(falcon_tsc_display_eye_scan_stripe(&(phy_copy.access), ii, &stripe[0]));
    675 
    676             PHYMOD_DIAG_OUT(("\n"));
    677         }
    678 
    679         if (rc == PHYMOD_E_NONE) {
    680             PHYMOD_IF_ERR_RETURN(falcon_tsc_display_eye_scan_footer(&(phy_copy.access), 1));
    681             PHYMOD_DIAG_OUT(("\n"));
    682         }
    683     }
    684     
    685     if(PHYMOD_EYESCAN_F_DONE_GET(flags)) {
    686         PHYMOD_IF_ERR_RETURN(falcon_tsc_meas_eye_scan_done(&(phy_copy.access)));
    687     }
    688   }
    689     return PHYMOD_E_NONE;
    690 }
    691 
    692 STATIC int falcon_diagnostics_eyescan_run_lowber( 
    693     const phymod_phy_access_t* phy,
    694     uint32_t flags,
    695     const phymod_phy_eyescan_options_t* eyescan_options
    696     )   
    697 {
    698     uint32_t *buffer;
    699     int buffer_size = 64*64;
    700     int rv = PHYMOD_E_NONE;
    701 
    702     buffer = PHYMOD_MALLOC(sizeof(uint32_t) * buffer_size, "buffer");
    703     if (NULL == buffer) {
    704         return PHYMOD_E_MEMORY;
    705     }
    706     PHYMOD_MEMSET(buffer, 0, sizeof(uint32_t) * buffer_size);
    707 
    708     /*enable eyescan*/
    709     if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    710 
    711         rv = falcon_phy_meas_lowber_eye (&(phy->access), eyescan_options, buffer);
    712         if (rv < 0) {
    713             goto cleanup;
    714         }
    715         rv = falcon_phy_display_lowber_eye (&(phy->access), eyescan_options, buffer);
    716         if (rv < 0) {
    717             goto cleanup;
    718         }
    719     }
    720     if (buffer != NULL) {
    721         PHYMOD_FREE(buffer);
    722     }
    723 
    724     if(PHYMOD_EYESCAN_F_DONE_GET(flags)) {
    725         PHYMOD_IF_ERR_RETURN(falcon_tsc_pmd_uc_cmd(&(phy->access), CMD_CAPTURE_BER_END, 0, 2000));
    726     }
    727 
    728     return PHYMOD_E_NONE;
    729 
    730 cleanup:
    731     if (buffer != NULL) {
    732         PHYMOD_FREE(buffer);
    733     }
    734 
    735     return rv;
    736 }
    737 
    738 int falcon_diagnostics_eye_margin_proj( const phymod_phy_access_t* phy, uint32_t flags,
    739                                         const phymod_phy_eyescan_options_t* eyescan_options) {
    740 #ifdef SERDES_API_FLOATING_POINT
    741   int osr_mode;
    742   USR_DOUBLE data_rate, data_rate_in_Mhz;
    743   phymod_phy_access_t phy_copy;
    744   int start_lane, num_lane, i, found=0;
    745 
    746   struct   falcon_tsc_uc_core_config_st core_cfg;
    747   if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    748      PHYMOD_IF_ERR_RETURN
    749         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    750      PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    751      for (i = 0; i < num_lane; i++) {
    752          phy_copy.access.lane_mask = 1 << (start_lane + i);
    753 
    754          if (found == 0) {
    755              PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_core_config (&(phy_copy.access), &core_cfg));
    756              PHYMOD_IF_ERR_RETURN(falcon_osr_mode_get(&phy_copy.access, &osr_mode));
    757              data_rate = (core_cfg.vco_rate_in_Mhz * 1000.0 * 1000.0) / (1<<osr_mode);
    758              data_rate_in_Mhz = (core_cfg.vco_rate_in_Mhz) / (1<<osr_mode);
    759              found = 1;
    760          }
    761          if(num_lane > 1) {
    762              PHYMOD_DIAG_OUT((" l=%0d, data rate  = %fMHz\n", i, data_rate_in_Mhz));
    763          } else {
    764              PHYMOD_DIAG_OUT((" data rate       = %fMHz\n", data_rate_in_Mhz));
    765          }
    766          falcon_tsc_eye_margin_proj(&phy_copy.access, data_rate, eyescan_options->ber_proj_scan_mode,
    767                                     eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt);
    768      }
    769   }
    770 #else
    771       PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("BER Proj is supported with SERDES_API_FLOATING_POINT only\n")));
    772 #endif
    773   return PHYMOD_E_NONE;
    774 }
    775 
    776 int falcon_phy_eyescan_run(const phymod_phy_access_t* phy, 
    777                            uint32_t flags, 
    778                            phymod_eyescan_mode_t mode, 
    779                            const phymod_phy_eyescan_options_t* eyescan_options)
    780 {
    781     uint8_t  pmd_rx_lock=0;
    782 
    783     PHYMOD_IF_ERR_RETURN
    784       (falcon_tsc_pmd_lock_status(&phy->access, &pmd_rx_lock));
    785     if(pmd_rx_lock == 0) {
    786       PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Can not get eyescan when pmd_rx is not locked\n")));
    787     }
    788 
    789     /* If stage isn't set - perform all stages*/
    790     if(!PHYMOD_EYESCAN_F_ENABLE_GET(flags)
    791        && !PHYMOD_EYESCAN_F_PROCESS_GET(flags)
    792        && !PHYMOD_EYESCAN_F_DONE_GET(flags)) 
    793     {
    794         PHYMOD_EYESCAN_F_ENABLE_SET(flags);
    795         PHYMOD_EYESCAN_F_PROCESS_SET(flags);
    796         PHYMOD_EYESCAN_F_DONE_SET(flags);
    797     }
    798 
    799 
    800     /* mode phymodEyescanModeBERProj gives BER projection */
    801     switch(mode) {
    802         case phymodEyescanModeFast:
    803             return falcon_diagnostics_eyescan_run_uc(phy, flags);
    804         case phymodEyescanModeLowBER:
    805             return falcon_diagnostics_eyescan_run_lowber(phy, flags, eyescan_options);
    806         case phymodEyescanModeBERProj:
    807             return falcon_diagnostics_eye_margin_proj(phy, flags, eyescan_options);
    808         default:
    809             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported eyescan mode %u"), mode));
    810     }
    811 }
    812 
    813 
    814 #endif /* PHYMOD_FALCON_SUPPORT */