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

phy8806x_diagnostics.c (24669B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <phymod/phymod.h>
     11 #include <phymod/phymod_system.h>
     12 #include <phymod/phymod_util.h>
     13 #include <phymod/phymod_config.h>
     14 #include <phymod/phymod_diagnostics.h>
     15 #include <phymod/phymod_diagnostics_dispatch.h>
     16 
     17 #if defined(INCLUDE_PHY_8806X)
     18 
     19 #ifdef INCLUDE_FCMAP
     20 #include <soc/phy/phymod_ctrl.h>
     21 #include <soc/phy/phyctrl.h>
     22 #include <soc/phyctrl.h>
     23 #endif
     24 
     25 #endif
     26 
     27 #include "../../tscf/tier1/tefmod_enum_defines.h" 
     28 #include "../../phy8806x/tier1/phy8806x_cfg_seq.h"
     29 #include "../../phy8806x/tier1/phy8806x_tsc_enum.h"
     30 #include "../../phy8806x/tier1/phy8806x_tsc_common.h"
     31 #include "../../phy8806x/tier1/phy8806x_tsc_interface.h"
     32 #include "../../phy8806x/tier1/phy8806x_tsc_dependencies.h"
     33 #include "../../phy8806x/tier1/phy8806x_tsc_debug_functions.h"
     34 
     35 #ifdef PHYMOD_PHY8806X_SUPPORT
     36 
     37 
     38 /*phymod, internal enum mappings*/
     39 STATIC
     40 int _phy8806x_prbs_poly_phymod_to_phy8806x(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *phy8806x_poly)
     41 {
     42     switch(phymod_poly){
     43     case phymodPrbsPoly7:
     44         *phy8806x_poly = PRBS_7;
     45         break;
     46     case phymodPrbsPoly9:
     47         *phy8806x_poly = PRBS_9;
     48         break;
     49     case phymodPrbsPoly11:
     50         *phy8806x_poly = PRBS_11;
     51         break;
     52     case phymodPrbsPoly15:
     53         *phy8806x_poly = PRBS_15;
     54         break;
     55     case phymodPrbsPoly23:
     56         *phy8806x_poly = PRBS_23;
     57         break;
     58     case phymodPrbsPoly31:
     59         *phy8806x_poly = PRBS_31;
     60         break;
     61     case phymodPrbsPoly58:
     62         *phy8806x_poly = PRBS_58;
     63         break;
     64     default:
     65         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tscf %u"), phymod_poly));
     66     }
     67     return PHYMOD_E_NONE;
     68 }
     69 
     70 STATIC
     71 int _phy8806x_prbs_poly_tscf_to_phymod(phy8806x_prbs_polynomial_type_t tscf_poly, phymod_prbs_poly_t *phymod_poly)
     72 {
     73     switch(tscf_poly){
     74     case PHY8806X_PRBS_POLYNOMIAL_7:
     75         *phymod_poly = phymodPrbsPoly7;
     76         break;
     77     case PHY8806X_PRBS_POLYNOMIAL_9:
     78         *phymod_poly = phymodPrbsPoly9;
     79         break;
     80     case PHY8806X_PRBS_POLYNOMIAL_11:
     81         *phymod_poly = phymodPrbsPoly11;
     82         break;
     83     case PHY8806X_PRBS_POLYNOMIAL_15:
     84         *phymod_poly = phymodPrbsPoly15;
     85         break;
     86     case PHY8806X_PRBS_POLYNOMIAL_23:
     87         *phymod_poly = phymodPrbsPoly23;
     88         break;
     89     case PHY8806X_PRBS_POLYNOMIAL_31:
     90         *phymod_poly = phymodPrbsPoly31;
     91         break;
     92     case PHY8806X_PRBS_POLYNOMIAL_58:
     93         *phymod_poly = phymodPrbsPoly58;
     94         break;
     95     default:
     96         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), tscf_poly));
     97     }
     98     return PHYMOD_E_NONE;
     99 }
    100 
    101 int phy8806x_phy_rx_slicer_position_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_slicer_position_t* position)
    102 {
    103     /* Not supported */
    104     PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_set function is NOT SUPPORTED!!\n"));
    105     return PHYMOD_E_NONE;
    106 }
    107 
    108 int phy8806x_phy_rx_slicer_position_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_slicer_position_t* position)
    109 {
    110     /* Not supported */
    111     PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_get function is NOT SUPPORTED!!\n"));
    112     return PHYMOD_E_NONE;
    113 }
    114 
    115 
    116 int phy8806x_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)
    117 {
    118     /* Not supported */
    119     PHYMOD_DEBUG_ERROR(("phy8806x_phy_rx_slicer_position_max_get function is NOT SUPPORTED!!\n"));
    120     return PHYMOD_E_NONE;
    121 }
    122 
    123 
    124 int phy8806x_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs)
    125 {
    126     enum srds_prbs_polynomial_enum phy8806x_poly;
    127 
    128     PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_phymod_to_phy8806x(prbs->poly, &phy8806x_poly));
    129     /*first check which direction */
    130     if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    131         PHYMOD_IF_ERR_RETURN
    132             (phy8806x_tsc_config_rx_prbs(&phy->access, phy8806x_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    133     } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    134         PHYMOD_IF_ERR_RETURN
    135             (phy8806x_tsc_config_tx_prbs(&phy->access, phy8806x_poly, prbs->invert));
    136     } else {
    137         PHYMOD_IF_ERR_RETURN
    138             (phy8806x_tsc_config_rx_prbs(&phy->access, phy8806x_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    139         PHYMOD_IF_ERR_RETURN
    140             (phy8806x_tsc_config_tx_prbs(&phy->access, phy8806x_poly, prbs->invert));
    141     }
    142     return PHYMOD_E_NONE;
    143 }
    144 
    145 int phy8806x_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs)
    146 {
    147     phymod_prbs_t config_tmp;
    148     phy8806x_prbs_polynomial_type_t tscf_poly;
    149 
    150     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    151         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert));
    152         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_poly_get(&phy->access, &tscf_poly));
    153         PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    154         prbs->invert = config_tmp.invert;
    155         prbs->poly = config_tmp.poly;
    156     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    157         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_inv_data_get(&phy->access, &config_tmp.invert));
    158         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_poly_get(&phy->access, &tscf_poly));
    159         PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    160         prbs->invert = config_tmp.invert;
    161         prbs->poly = config_tmp.poly;
    162     } else {
    163         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_inv_data_get(&phy->access, &config_tmp.invert));
    164         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_poly_get(&phy->access, &tscf_poly));
    165         PHYMOD_IF_ERR_RETURN(_phy8806x_prbs_poly_tscf_to_phymod(tscf_poly, &config_tmp.poly));
    166         prbs->invert = config_tmp.invert;
    167         prbs->poly = config_tmp.poly;
    168     }
    169     return PHYMOD_E_NONE;
    170 }
    171 
    172 int phy8806x_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable)
    173 {
    174     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    175         PHYMOD_IF_ERR_RETURN(phy8806x_tsc_tx_prbs_en(&phy->access, enable));
    176     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    177         PHYMOD_IF_ERR_RETURN(phy8806x_tsc_rx_prbs_en(&phy->access, enable));
    178     } else {
    179         PHYMOD_IF_ERR_RETURN(phy8806x_tsc_tx_prbs_en(&phy->access, enable));
    180         PHYMOD_IF_ERR_RETURN(phy8806x_tsc_rx_prbs_en(&phy->access, enable));
    181     }
    182     return PHYMOD_E_NONE;
    183 }
    184 
    185 int phy8806x_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable)
    186 {
    187     uint32_t enable_tmp;
    188     
    189     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    190         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_enable_get(&phy->access, &enable_tmp));
    191         *enable = enable_tmp;
    192     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    193         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_enable_get(&phy->access, &enable_tmp));
    194         *enable = enable_tmp;
    195     } else {
    196         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_tx_enable_get(&phy->access, &enable_tmp));
    197         *enable = enable_tmp;
    198         PHYMOD_IF_ERR_RETURN(phy8806x_prbs_rx_enable_get(&phy->access, &enable_tmp));
    199         *enable &= enable_tmp;
    200     }
    201     return PHYMOD_E_NONE;
    202 }
    203 
    204 int phy8806x_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status)
    205 {
    206     uint8_t status = 0;
    207     uint32_t prbs_err_count = 0;
    208 
    209     PHYMOD_IF_ERR_RETURN(phy8806x_tsc_prbs_chk_lock_state(&phy->access, &status));
    210     if (status) {
    211         prbs_status->prbs_lock = 1;
    212         /*next check the lost of lock and error count */
    213         status = 0;
    214         PHYMOD_IF_ERR_RETURN
    215             (phy8806x_tsc_prbs_err_count_state(&phy->access, &prbs_err_count, &status));
    216         if (status) {
    217         /*temp lost of lock */
    218             prbs_status->prbs_lock_loss = 1;
    219         } else {
    220             prbs_status->prbs_lock_loss = 0;
    221             prbs_status->error_count = prbs_err_count;
    222         }
    223     } else {
    224         prbs_status->prbs_lock = 0;
    225     }
    226     return PHYMOD_E_NONE;
    227 }
    228 
    229 int phy8806x_phy_pattern_config_set(const phymod_phy_access_t* phy, const phymod_pattern_t* pattern)
    230 {
    231     /* Not supported */
    232     PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_config_set function is NOT SUPPORTED!!\n"));
    233     return PHYMOD_E_NONE;
    234 }
    235 
    236 int phy8806x_phy_pattern_config_get(const phymod_phy_access_t* phy, phymod_pattern_t* pattern)
    237 {
    238     /* Not supported */
    239     PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_config_get function is NOT SUPPORTED!!\n"));
    240     return PHYMOD_E_NONE;
    241 }
    242 
    243 int phy8806x_phy_pattern_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    244 {
    245     /* Not supported */
    246     PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_enable_set function is NOT SUPPORTED!!\n"));
    247     return PHYMOD_E_NONE;
    248 }
    249 
    250 int phy8806x_phy_pattern_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    251 {
    252     /* Not supported */
    253     PHYMOD_DEBUG_ERROR(("phy8806x_phy_pattern_enable_get function is NOT SUPPORTED!!\n"));
    254     return PHYMOD_E_NONE;
    255 }
    256 
    257 int phy8806x_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag)
    258 {
    259     int16_t temperature;
    260 
    261     phy8806x_tsc_read_die_temperature(&core->access, &temperature);
    262     diag->temperature = temperature;
    263     phy8806x_tsc_read_pll_range(&core->access, &diag->pll_range);
    264 
    265     return PHYMOD_E_NONE;
    266 }
    267 
    268 int phy8806x_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag)
    269 {
    270     unsigned char rx_lock;
    271     int osr_mode;
    272     phymod_diag_eyescan_t_init(&diag->eyescan);
    273     phymod_diag_slicer_offset_t_init(&diag->slicer_offset);
    274 
    275     PHYMOD_IF_ERR_RETURN(phy8806x_tsc_pmd_lock_status(&phy->access, &rx_lock));
    276     diag->rx_lock = (uint32_t ) rx_lock;
    277     PHYMOD_IF_ERR_RETURN(phy8806x_osr_mode_get(&phy->access, &osr_mode));
    278     switch(osr_mode) {
    279         case 0: diag->osr_mode = phymodOversampleMode1; break;
    280         case 1: diag->osr_mode = phymodOversampleMode2; break;
    281         case 2: diag->osr_mode = phymodOversampleMode4; break;
    282         case 8: diag->osr_mode = phymodOversampleMode16P5; break;
    283         case 12: diag->osr_mode = phymodOversampleMode20P625; break;
    284         default: 
    285             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode));
    286     }
    287     PHYMOD_IF_ERR_RETURN(phy8806x_tsc_signal_detect(&phy->access, &diag->signal_detect));
    288     return PHYMOD_E_NONE;
    289 }
    290 
    291 int phy8806x_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char *type)
    292 {
    293     int start_lane, num_lane;
    294     phymod_phy_access_t phy_copy;
    295     struct phy8806x_tsc_detailed_lane_status_st lane_st[4];
    296     int i = 0;
    297     int j = 0;
    298     uint32_t cmd_type;
    299     uint8_t trace_mem[768];
    300 
    301 #if defined(INCLUDE_PHY_8806X)
    302 #ifdef INCLUDE_FCMAP
    303     soc_phymod_core_t *soc_core;
    304     phy_ctrl_t *pc;
    305 #endif
    306 #endif
    307 
    308     if (!type) {
    309         cmd_type = (uint32_t)TEFMOD_DIAG_STATE;
    310     } else if (!PHYMOD_STRCMP(type, "ber")) {
    311         cmd_type = (uint32_t)TEFMOD_DIAG_BER;
    312     } else if (!PHYMOD_STRCMP(type, "config")) {
    313         cmd_type = (uint32_t)TEFMOD_DIAG_CFG;
    314     } else if (!PHYMOD_STRCMP(type, "CL72")) {
    315         cmd_type = (uint32_t)TEFMOD_DIAG_CL72;
    316     } else if (!PHYMOD_STRCMP(type, "debug")) {
    317         cmd_type = (uint32_t)TEFMOD_DIAG_DEBUG;
    318     } else {
    319         cmd_type = (uint32_t)TEFMOD_DIAG_STATE;
    320     }
    321 
    322     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    323 
    324     /*next figure out the lane num and start_lane based on the input*/
    325     PHYMOD_IF_ERR_RETURN
    326         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    327 
    328 #if defined(INCLUDE_PHY_8806X)
    329 #ifdef INCLUDE_FCMAP
    330     soc_core = PHYMOD_ACC_USER_ACC(&phy->access);
    331     pc = EXT_PHY_SW_STATE(soc_core->unit, soc_core->port);
    332     if (pc->fcmap_enable && (!(pc->flags & PHYCTRL_SYS_SIDE_CTRL))) {
    333         num_lane = 1;
    334     }
    335 #endif
    336 #endif
    337 
    338     for (i = 0; i < num_lane; i++) {
    339         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    340 
    341         switch (cmd_type) {
    342             case TEFMOD_DIAG_CFG:
    343                  PHYMOD_IF_ERR_RETURN
    344                     (phy8806x_tsc_display_core_config(&phy_copy.access));
    345                  PHYMOD_IF_ERR_RETURN
    346                     (phy8806x_tsc_display_lane_config(&phy_copy.access));
    347                  break;
    348 
    349             case TEFMOD_DIAG_CL72:
    350                  PHYMOD_IF_ERR_RETURN
    351                     (phy8806x_tsc_display_cl93n72_status(&phy_copy.access));
    352                  break;
    353 
    354             case TEFMOD_DIAG_DEBUG:
    355                  PHYMOD_IF_ERR_RETURN
    356                     (phy8806x_tsc_display_lane_debug_status(&phy_copy.access));
    357                  break;
    358 
    359             case TEFMOD_DIAG_BER:
    360                  break;
    361 
    362             case TEFMOD_DIAG_STATE:
    363             default:
    364                  PHYMOD_IF_ERR_RETURN
    365                     (phy8806x_tsc_display_core_state_hdr(&phy_copy.access));
    366                  PHYMOD_IF_ERR_RETURN
    367                     (phy8806x_tsc_display_core_state_line(&phy_copy.access));
    368                  PHYMOD_IF_ERR_RETURN
    369                     (phy8806x_tsc_display_core_state(&phy_copy.access));
    370                  PHYMOD_IF_ERR_RETURN
    371                     (phy8806x_tsc_display_lane_state_hdr(&phy_copy.access));
    372                  PHYMOD_IF_ERR_RETURN
    373                     (phy8806x_tsc_display_lane_state(&phy_copy.access));
    374                  for (j = 0; j < 4; j++) {
    375                    PHYMOD_IF_ERR_RETURN
    376                       (phy8806x_tsc_log_full_pmd_state(&phy_copy.access, &lane_st[j]));
    377                  }
    378                  PHYMOD_IF_ERR_RETURN
    379                     (phy8806x_tsc_disp_full_pmd_state(&phy_copy.access, lane_st, 4));
    380                  PHYMOD_IF_ERR_RETURN
    381                     (phy8806x_tsc_read_event_log((&phy_copy.access), trace_mem, 2));
    382                  break;
    383         }
    384     }
    385 
    386     return PHYMOD_E_NONE;
    387 }
    388 
    389 STATIC err_code_t phy8806x_phy_meas_lowber_eye (const phymod_access_t *pa, 
    390                                      const phymod_phy_eyescan_options_t* eyescan_options,
    391                                      uint32_t *buffer) 
    392 {
    393     struct phy8806x_tsc_eyescan_options_st e_options;
    394 
    395     e_options.linerate_in_khz = eyescan_options->linerate_in_khz;
    396     e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds;
    397     e_options.horz_max = eyescan_options->horz_max;
    398     e_options.horz_min = eyescan_options->horz_min;
    399     e_options.hstep = eyescan_options->hstep;
    400     e_options.vert_max = eyescan_options->vert_max;
    401     e_options.vert_min = eyescan_options->vert_min;
    402     e_options.vstep = eyescan_options->vstep;
    403     e_options.mode = eyescan_options->mode;
    404 
    405     return (phy8806x_tsc_meas_lowber_eye(pa, e_options, buffer));
    406 }
    407 
    408 STATIC err_code_t phy8806x_phy_display_lowber_eye (const phymod_access_t *pa, 
    409                                         const phymod_phy_eyescan_options_t* eyescan_options,
    410                                         uint32_t *buffer) 
    411 {
    412     struct phy8806x_tsc_eyescan_options_st e_options;
    413 
    414     e_options.linerate_in_khz = eyescan_options->linerate_in_khz;
    415     e_options.timeout_in_milliseconds = eyescan_options->timeout_in_milliseconds;
    416     e_options.horz_max = eyescan_options->horz_max;
    417     e_options.horz_min = eyescan_options->horz_min;
    418     e_options.hstep = eyescan_options->hstep;
    419     e_options.vert_max = eyescan_options->vert_max*2;
    420     e_options.vert_min = eyescan_options->vert_min*2;
    421     e_options.vstep = eyescan_options->vstep*2;
    422     e_options.mode = eyescan_options->mode;
    423 
    424     return(phy8806x_tsc_display_lowber_eye (pa, e_options, buffer)); 
    425 } 
    426 
    427 static void _phy8806x_diag_uc_reg_dump(const phymod_access_t *pa)
    428 {
    429     err_code_t errc;
    430 
    431     COMPILER_REFERENCE(errc);
    432 
    433     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    434     PHYMOD_DIAG_OUT(("|    MICRO CODE USR CTRL CONFIGURATION REGISTERS  |\n"));
    435     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    436     PHYMOD_DIAG_OUT(("|    config_word              [0x00]: 0x%04X      |\n",    phy8806x_tsc_rdwl_uc_var(pa,&errc,0x0)));
    437     PHYMOD_DIAG_OUT(("|    retune_after_restart     [0x02]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x2)));
    438     PHYMOD_DIAG_OUT(("|    clk90_offset_adjust      [0x03]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x3)));
    439     PHYMOD_DIAG_OUT(("|    clk90_offset_override    [0x04]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x4)));
    440     PHYMOD_DIAG_OUT(("|    lane_event_log_level     [0x05]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x5)));
    441     PHYMOD_DIAG_OUT(("|    disable_startup          [0x06]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x6)));
    442     PHYMOD_DIAG_OUT(("|    disable_startup_dfe      [0x07]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x7)));
    443     PHYMOD_DIAG_OUT(("|    disable_steady_state     [0x08]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x8)));
    444     PHYMOD_DIAG_OUT(("|    disable_steady_state_dfe [0x09]: 0x%04X      |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x9)));
    445     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    446     PHYMOD_DIAG_OUT(("|         MICRO CODE USER STATUS REGISTERS        |\n"));
    447     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    448     PHYMOD_DIAG_OUT(("|    restart_counter           [0x0A]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xa)));
    449     PHYMOD_DIAG_OUT(("|    reset_counter             [0x0B]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xb)));
    450     PHYMOD_DIAG_OUT(("|    pmd_lock_counter          [0x0C]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xc)));
    451     PHYMOD_DIAG_OUT(("|    heye_left                 [0x0D]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xd)));
    452     PHYMOD_DIAG_OUT(("|    heye_left_lsbyte          [0x0E]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xe)));
    453     PHYMOD_DIAG_OUT(("|    heye_right                [0x0F]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0xf)));
    454     PHYMOD_DIAG_OUT(("|    heye_right_lsbyte         [0x10]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x10)));
    455     PHYMOD_DIAG_OUT(("|    veye_upper                [0x11]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x11)));
    456     PHYMOD_DIAG_OUT(("|    veye_upper_lsbyte         [0x12]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x12)));
    457     PHYMOD_DIAG_OUT(("|    veye_lower                [0x13]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x13)));
    458     PHYMOD_DIAG_OUT(("|    veye_lower_lsbyte         [0x14]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x14)));
    459     PHYMOD_DIAG_OUT(("|    micro_stopped             [0x15]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x15)));
    460     PHYMOD_DIAG_OUT(("|    link_time                 [0x16]: 0x%04X     |\n",    phy8806x_tsc_rdwl_uc_var(pa,&errc,0x16)));
    461     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    462     PHYMOD_DIAG_OUT(("|            MICRO CODE MISC REGISTERS            |\n"));
    463     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    464     PHYMOD_DIAG_OUT(("|    usr_diag_status           [0x18]: 0x%04X     |\n",    phy8806x_tsc_rdwl_uc_var(pa,&errc,0x18)));
    465     PHYMOD_DIAG_OUT(("|    usr_diag_rd_ptr           [0x1A]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x1a)));
    466     PHYMOD_DIAG_OUT(("|    usr_diag_mode             [0x1B]: 0x%04X     |\n",    phy8806x_tsc_rdbl_uc_var(pa,&errc,0x1b)));
    467     PHYMOD_DIAG_OUT(("|    usr_var_msb               [0x1C]: 0x%04X     |\n",    phy8806x_tsc_rdwl_uc_var(pa,&errc,0x1c)));
    468     PHYMOD_DIAG_OUT(("|    usr_var_lsb               [0x1E]: 0x%04X     |\n",    phy8806x_tsc_rdwl_uc_var(pa,&errc,0x1e)));
    469     PHYMOD_DIAG_OUT(("+-------------------------------------------------+\n"));
    470 }
    471 
    472 STATIC int phy8806x_diagnostics_eyescan_run_uc(const phymod_phy_access_t* phy, uint32_t flags)   
    473 {
    474     int                 ii, rc = PHYMOD_E_NONE;
    475     uint32_t            stripe[64];
    476     uint16_t            status;
    477     int                 j ;
    478     phymod_phy_access_t phy_copy;
    479 
    480     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    481 
    482     for(j=0; j< PHYMOD_CONFIG_MAX_LANES_PER_CORE; j++) { /* Loop for all lanes. */
    483         if ((phy->access.lane_mask & (1<<j))==0) continue;
    484 
    485         phy_copy.access.lane_mask = (phy->access.lane_mask & (1<<j));
    486 
    487         if(PHYMOD_EYESCAN_F_ENABLE_GET(flags)) {
    488             PHYMOD_IF_ERR_RETURN(phy8806x_tsc_meas_eye_scan_start(&(phy_copy.access), 0));
    489 
    490             if(!PHYMOD_EYESCAN_F_ENABLE_DONT_WAIT_GET(flags)) {
    491                 PHYMOD_USLEEP(100000);
    492             }
    493         }
    494 
    495         if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    496 
    497             for (ii = 62; ii >= -62; ii=ii-2) { 
    498                 if (ii == 62) {
    499                     PHYMOD_DIAG_OUT(("\n\n\n"));
    500                     PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    501                     PHYMOD_DIAG_OUT(("    | EYESCAN Phy: 0x%03x lane_mask: 0x%02x                                 |\n", phy_copy.access.addr, phy_copy.access.lane_mask));
    502                     PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
    503                     /*display eyescan header*/
    504                     PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_header(&(phy_copy.access), 1));
    505                 }
    506 
    507                 rc  = phy8806x_tsc_read_eye_scan_stripe(&(phy_copy.access), stripe, &status);
    508                 if(rc != PHYMOD_E_NONE) {
    509                     _phy8806x_diag_uc_reg_dump(&(phy_copy.access));
    510                     PHYMOD_IF_ERR_RETURN(rc);
    511                 }
    512                 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_stripe(&(phy_copy.access), ii, &stripe[0]));
    513 
    514                 PHYMOD_DIAG_OUT(("\n"));
    515             }
    516 
    517             if (rc == PHYMOD_E_NONE) {
    518                 PHYMOD_IF_ERR_RETURN(phy8806x_tsc_display_eye_scan_footer(&(phy_copy.access), 1));
    519                 PHYMOD_DIAG_OUT(("\n"));
    520             }
    521         }
    522 
    523         if(PHYMOD_EYESCAN_F_DONE_GET(flags)) {
    524             PHYMOD_IF_ERR_RETURN(phy8806x_tsc_meas_eye_scan_done(&(phy_copy.access)));
    525         }
    526     }
    527     return PHYMOD_E_NONE;
    528 }
    529 
    530 STATIC int phy8806x_diagnostics_eyescan_run_lowber( 
    531     const phymod_phy_access_t* phy,
    532     uint32_t flags,
    533     const phymod_phy_eyescan_options_t* eyescan_options
    534     )   
    535 {
    536     uint32_t *buffer;
    537     int buffer_size = 64*64;
    538     int rv = PHYMOD_E_NONE;
    539 
    540     buffer = PHYMOD_MALLOC(sizeof(uint32_t) * buffer_size, "buffer");
    541     if (NULL == buffer) {
    542         return PHYMOD_E_MEMORY;
    543     }
    544     PHYMOD_MEMSET(buffer, 0, sizeof(uint32_t) * buffer_size);
    545 
    546     /*enable eyescan*/
    547     if(PHYMOD_EYESCAN_F_PROCESS_GET(flags)) {
    548 
    549         rv = phy8806x_phy_meas_lowber_eye (&(phy->access), eyescan_options, buffer);
    550         if (rv < 0) {
    551             goto cleanup;
    552         }
    553         rv = phy8806x_phy_display_lowber_eye (&(phy->access), eyescan_options, buffer);
    554         if (rv < 0) {
    555             goto cleanup;
    556         }
    557     }
    558     if (buffer != NULL) {
    559         PHYMOD_FREE(buffer);
    560     }
    561 
    562     if(PHYMOD_EYESCAN_F_DONE_GET(flags)) {
    563         PHYMOD_IF_ERR_RETURN(phy8806x_tsc_pmd_uc_cmd(&(phy->access), CMD_CAPTURE_BER_END, 0, 2000));
    564     }
    565 
    566     return PHYMOD_E_NONE;
    567 
    568 cleanup:
    569     if (buffer != NULL) {
    570         PHYMOD_FREE(buffer);
    571     }
    572 
    573     return rv;
    574 }
    575 
    576 int phy8806x_phy_eyescan_run(const phymod_phy_access_t* phy, 
    577                            uint32_t flags, 
    578                            phymod_eyescan_mode_t mode, 
    579                            const phymod_phy_eyescan_options_t* eyescan_options)
    580 {
    581     uint8_t  pmd_rx_lock=0;
    582 
    583     PHYMOD_IF_ERR_RETURN
    584       (phy8806x_tsc_pmd_lock_status(&phy->access, &pmd_rx_lock));
    585     if(pmd_rx_lock == 0) {
    586       PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Can not get eyescan when pmd_rx is not locked\n")));
    587     }
    588 
    589     /* If stage isn't set - perform all stages*/
    590     if(!PHYMOD_EYESCAN_F_ENABLE_GET(flags)
    591        && !PHYMOD_EYESCAN_F_PROCESS_GET(flags)
    592        && !PHYMOD_EYESCAN_F_DONE_GET(flags)) 
    593     {
    594         PHYMOD_EYESCAN_F_ENABLE_SET(flags);
    595         PHYMOD_EYESCAN_F_PROCESS_SET(flags);
    596         PHYMOD_EYESCAN_F_DONE_SET(flags);
    597     }
    598 
    599     switch(mode) {
    600         case phymodEyescanModeFast:
    601             return phy8806x_diagnostics_eyescan_run_uc(phy, flags);
    602         case phymodEyescanModeLowBER:
    603             return phy8806x_diagnostics_eyescan_run_lowber(phy, flags, eyescan_options);
    604         default:
    605             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported eyescan mode %u"), mode));
    606     }
    607 }
    608 
    609 
    610 #endif /* PHYMOD_PHY8806X_SUPPORT */