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

phymod_diag.c (18306B)


      1 /* 
      2  *  
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  */
      7 #include <phymod/phymod_diag.h>
      8 #include <phymod/phymod_system.h>
      9 #include <phymod/phymod_util.h>
     10 #include <phymod/phymod_debug.h>
     11 
     12 #ifdef PHYMOD_QSGMIIE_SUPPORT
     13 #include <phymod/chip/bcmi_qsgmiie_serdes_sym.h>
     14 #endif /*PHYMOD_QSGMIIE_SUPPORT  */
     15 #ifdef PHYMOD_TSCE_SUPPORT
     16 #include <phymod/chip/bcmi_tsce_xgxs_sym.h>
     17 #endif /*PHYMOD_TSCE_SUPPORT  */
     18 #ifdef PHYMOD_TSCF_SUPPORT
     19 #include <phymod/chip/bcmi_tscf_xgxs_sym.h> 
     20 #include <phymod/chip/bcmi_tscf_xgxs_defs.h> 
     21 #include <phymod/chip/bcmi_tscf_xgxs_gen2_sym.h>
     22 #endif /*PHYMOD_TSCF_SUPPORT  */
     23 #if 0 /* #ifdef PHYMOD_PHY8806X_SUPPORT */
     24 #include <phymod/chip/bcmi_phy8806x_xgxs_sym.h>
     25 #endif /*PHYMOD_PHY8806X_SUPPORT  */
     26 #ifdef PHYMOD_EAGLE_SUPPORT
     27 #include <phymod/chip/bcmi_eagle_xgxs_sym.h>
     28 #endif /*PHYMOD_EAGLE_SUPPORT  */
     29 #ifdef PHYMOD_FALCON_SUPPORT
     30 #include <phymod/chip/bcmi_falcon_xgxs_sym.h>
     31 #endif /*PHYMOD_FALCON_SUPPORT  */
     32 #ifdef PHYMOD_VIPER_SUPPORT
     33 #include <phymod/chip/bcmi_viper_xgxs_defs.h>
     34 #include <phymod/chip/bcmi_viper_xgxs_sym.h>
     35 #include <phymod/chip/bcmi_sgmiip2x4_serdes_sym.h>
     36 #endif /*PHYMOD_VIPER_SUPPORT  */
     37 #ifdef PHYMOD_TSCF16_SUPPORT
     38 #include <phymod/chip/bcmi_tscf_16nm_xgxs_sym.h>
     39 #endif /*PHYMOD_TSCF16_SUPPORT  */
     40 #ifdef PHYMOD_TSCE_DPLL_SUPPORT
     41 #include <phymod/chip/bcmi_tsce_dpll_xgxs_sym.h>
     42 #endif /*PHYMOD_TSCE_DPLL_SUPPORT  */
     43 #ifdef PHYMOD_BLACKHAWK_SUPPORT
     44 #include <phymod/chip/bcmi_blackhawk_xgxs_sym.h>
     45 #endif /*PHYMOD_BLACKHAWK_SUPPORT  */
     46 #ifdef PHYMOD_TSCE16_SUPPORT
     47 #include <phymod/chip/bcmi_tsce16_xgxs_sym.h>
     48 #endif
     49 #ifdef PHYMOD_TSCBH_SUPPORT
     50 #include <phymod/chip/bcmi_tscbh_xgxs_sym.h>
     51 #endif /*PHYMOD_TSCBH_SUPPORT  */
     52 #ifdef PHYMOD_TSCE16_SUPPORT
     53 #include <phymod/chip/bcmi_tsce16_xgxs_sym.h>
     54 #endif
     55 #ifdef PHYMOD_TSCF_GEN3_SUPPORT
     56 #include <phymod/chip/bcmi_tscf_gen3_xgxs_sym.h>
     57 #endif /*PHYMOD_TSCF_GEN3_SUPPORT  */
     58 #ifdef PHYMOD_BLACKHAWK_SUPPORT
     59 #include <phymod/chip/bcmi_blackhawk_xgxs_sym.h>
     60 #endif /*PHYMOD_BLACKHAWK_SUPPORT  */
     61 #ifdef PHYMOD_QTCE16_SUPPORT
     62 #include <phymod/chip/bcmi_qtce16_serdes_sym.h>
     63 #endif /*PHYMOD_QTCE16_SUPPORT  */
     64 
     65 #define _PHYMOD_PHY_MSG(phy, string) ("Phy 0x%x lanes 0x%02x: " string), (phy)->access.addr, (phy)->access.lane_mask
     66 #define _PHYMOD_CORE_MSG(core, string) ("Core 0x%x: " string), (core)->access.addr
     67 
     68 #define PHYMOD_DIAG_PRINT_FUNC_VALIDATE if(phymod_diag_print_func == NULL) return PHYMOD_E_IO
     69 
     70 print_func_f phymod_diag_print_func = NULL;
     71 
     72 
     73 int phymod_diag_symbols_table_get(phymod_phy_access_t *phy, phymod_symbols_t **symbols)
     74 {
     75     switch(phy->type){
     76 #ifdef PHYMOD_QSGMIIE_SUPPORT
     77     case phymodDispatchTypeQsgmiie:
     78         *symbols = &bcmi_qsgmiie_serdes_symbols;
     79         break;
     80 #endif /*PHYMOD_QSGMIIE_SUPPORT  */
     81 #ifdef PHYMOD_TSCE_SUPPORT
     82     case phymodDispatchTypeTsce:
     83         *symbols = &bcmi_tsce_xgxs_symbols;
     84         break;
     85 #endif /*PHYMOD_TSCE_SUPPORT  */
     86 #ifdef PHYMOD_TSCF_SUPPORT
     87     case phymodDispatchTypeTscf:
     88     {
     89         /* first need to get the tscf model number */
     90       MAIN0_SERDESIDr_t serdesid;
     91       uint32_t model; 
     92 
     93       /* next check serdes ID to see if gen2 or not */
     94       READ_MAIN0_SERDESIDr(&phy->access, &serdesid);
     95       model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid);
     96 
     97       /* check if tscf_gen2 version */
     98       if (model == 0x15)  {
     99         *symbols = &bcmi_tscf_xgxs_gen2_symbols;
    100       } else {
    101         *symbols = &bcmi_tscf_xgxs_symbols;
    102       }
    103         break;
    104     }
    105 #endif /*PHYMOD_TSCF_SUPPORT  */
    106 #if 0 /* #ifdef PHYMOD_PHY8806X_SUPPORT */
    107     case phymodDispatchTypePhy8806x:
    108         *symbols = &bcmi_phy8806x_xgxs_symbols;
    109         break;
    110 #endif /*PHYMOD_PHY8806X_SUPPORT  */
    111 #ifdef PHYMOD_EAGLE_SUPPORT
    112     case phymodDispatchTypeEagle:
    113         *symbols = &bcmi_eagle_xgxs_symbols;
    114         break;
    115 #endif /*PHYMOD_EAGLE_SUPPORT  */
    116 #ifdef PHYMOD_FALCON_SUPPORT
    117     case phymodDispatchTypeFalcon:
    118         *symbols = &bcmi_falcon_xgxs_symbols;
    119         break;
    120 #endif /*PHYMOD_FALCON_SUPPORT  */
    121 #ifdef PHYMOD_VIPER_SUPPORT
    122     case phymodDispatchTypeViper:
    123     {
    124         SERDESID0r_t serdes_id;
    125         uint32_t model = 0;
    126 
    127         READ_SERDESID0r(&phy->access, &serdes_id);
    128         model = SERDESID0r_MODEL_NUMBERf_GET(serdes_id);
    129 
    130         /* check if SGMIIPLUS2x4 core */
    131         if (model == 0xf) {
    132             *symbols = &bcmi_sgmiip2x4_serdes_symbols;
    133         } else {
    134             *symbols = &bcmi_viper_xgxs_symbols;
    135         }
    136 
    137         break;
    138     }
    139 #endif /*PHYMOD_VIPER_SUPPORT  */
    140 #ifdef PHYMOD_TSCF16_SUPPORT
    141     case phymodDispatchTypeTscf16:
    142         *symbols = &bcmi_tscf_16nm_xgxs_symbols;
    143         break;
    144 #endif /*PHYMOD_TSCF16_SUPPORT  */
    145 #ifdef PHYMOD_TSCE_DPLL_SUPPORT
    146     case phymodDispatchTypeTsce_dpll:
    147         *symbols = &bcmi_tsce_dpll_xgxs_symbols;
    148         break;
    149 #endif
    150 #ifdef PHYMOD_TSCE16_SUPPORT
    151     case phymodDispatchTypeTsce16:
    152         *symbols = &bcmi_tsce16_xgxs_symbols;
    153         break;
    154 #endif
    155 #ifdef PHYMOD_TSCF_GEN3_SUPPORT
    156     case phymodDispatchTypeTscf_gen3:
    157         *symbols = &bcmi_tscf_gen3_xgxs_symbols;
    158         break;
    159 #endif /*PHYMOD_TSCF_GEN3_SUPPORT  */
    160 #ifdef PHYMOD_BLACKHAWK_SUPPORT
    161     case phymodDispatchTypeBlackhawk:
    162         *symbols = &bcmi_blackhawk_xgxs_symbols;
    163         break;
    164 #endif
    165 #ifdef PHYMOD_TSCBH_SUPPORT
    166     case phymodDispatchTypeTscbh:
    167         *symbols = &bcmi_tscbh_xgxs_symbols;
    168         break;
    169 #endif
    170 #ifdef PHYMOD_QTCE16_SUPPORT
    171     case phymodDispatchTypeQtce16:
    172         *symbols = &bcmi_qtce16_xgxs_symbols;
    173         break;
    174 #endif /*PHYMOD_QTCE16_SUPPORT  */
    175     default:
    176         PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(phy,"unsupported SerDes type(%d) for symbolic access \n"), phy->type));
    177         return PHYMOD_E_UNAVAIL;
    178     }
    179     return PHYMOD_E_NONE;
    180 }
    181 
    182 /******************************************************************************
    183  Firmware load
    184  */
    185 
    186 int phymod_diag_firmware_load(phymod_core_access_t *cores, int array_size, char *firwmware_file){
    187     int i = 0;
    188 
    189     /*unsigned short firmware_crc;
    190     unsigned short firmware_verision;
    191     unsigned short firmware_length;*/
    192     unsigned short phy_type = -1;
    193     
    194     PHYMOD_DIAG_PRINT_FUNC_VALIDATE;
    195     
    196     
    197       
    198     for(i = 0 ; i < array_size ; i++){
    199         if(cores[i].type != phy_type){
    200             PHYMOD_DEBUG_ERROR((_PHYMOD_CORE_MSG(&cores[i],"The firmware is not compatible with the core\n")));
    201             return PHYMOD_E_FAIL;
    202         }
    203     }
    204     return PHYMOD_E_NONE;
    205 }
    206 
    207 
    208 /******************************************************************************
    209  Register read/write
    210  */
    211 int phymod_diag_reg_read(phymod_phy_access_t *phys, int array_size, uint32_t reg_addr){
    212     uint32_t val = 0;
    213     int rv;
    214     int i;
    215 
    216     PHYMOD_DIAG_PRINT_FUNC_VALIDATE;
    217     
    218     for(i = 0 ; i < array_size ; i++){
    219        rv = phymod_phy_reg_read(&phys[i], reg_addr, &val);
    220        if(rv == PHYMOD_E_NONE){
    221            PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Reg 0x%08x: 0x%04x\n"), reg_addr, val));
    222        }
    223        else{
    224            PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Reg 0x%08x: Error read register!\n"), reg_addr));
    225        }
    226     }
    227     return PHYMOD_E_NONE;
    228 }
    229 
    230 
    231 int phymod_diag_reg_write(phymod_phy_access_t *phys, int array_size, uint32_t reg_addr, uint32_t val){
    232     int i;
    233     int rv;
    234 
    235     PHYMOD_DIAG_PRINT_FUNC_VALIDATE;
    236     
    237     for(i = 0 ; i < array_size ; i++){
    238        rv = phymod_phy_reg_write(&phys[i], reg_addr, val);
    239        if(rv != PHYMOD_E_NONE){
    240            PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Reg 0x%08x: Error write register!\n"), reg_addr));
    241        }
    242     }
    243     return PHYMOD_E_NONE;
    244 }
    245 
    246 
    247 /******************************************************************************
    248  PRBS
    249  */
    250 STATIC
    251 void phymod_diag_prbs_get_results_print(phymod_phy_access_t *phy, phymod_prbs_status_t *status) {
    252     if (status->prbs_lock == 0) {
    253         if (status->error_count) {
    254             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG
    255                                        (phy, "prbs unlocked with %d errors during PRBS test\n"),
    256                                         status->error_count));   
    257         } else {
    258             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(phy, "prbs unlocked\n")));
    259         } 
    260     } else if (status->prbs_lock_loss == 1) {
    261         PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(phy, "prbs unlocked during the PRBS test\n")));
    262     } else {
    263         if (status->error_count) {
    264             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG
    265                                        (phy, "prbs locked with %d errors during PRBS test\n"),
    266                                         status->error_count));   
    267         } else { 
    268             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(phy, "prbs locked\n")));
    269             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(phy, "PRBS OK!\n")));
    270         }
    271     }
    272 }
    273 
    274 
    275 STATIC
    276 int phymod_diag_prbs_set(phymod_phy_access_t *phys, int array_size, phymod_diag_prbs_set_args_t *params){
    277     int i = 0;
    278     int rv;
    279     
    280     phymod_prbs_t_validate(&params->prbs_options);
    281     
    282        
    283     if(params->loopback == 1){
    284         for(i = 0 ; i < array_size ; i++){
    285             rv = phymod_phy_loopback_set(&phys[i], phymodLoopbackGlobal, 1);
    286             if(rv != PHYMOD_E_NONE){
    287                 PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Failed set loopback\n")));
    288                 return rv;
    289             }
    290         }
    291     }    
    292     for(i = 0 ; i < array_size ; i++){
    293         if(phymod_phy_prbs_config_set(&phys[i], params->flags, &params->prbs_options) != PHYMOD_E_NONE){
    294             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Failed set PRBS\n")));
    295             return PHYMOD_E_FAIL;
    296         }
    297         if(phymod_phy_prbs_enable_set(&phys[i], params->flags,  params->enable) != PHYMOD_E_NONE){
    298             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Failed enable PRBS\n")));
    299             return PHYMOD_E_FAIL;
    300         }
    301 
    302     }
    303     return PHYMOD_E_NONE;
    304 }
    305 
    306 
    307 
    308 STATIC
    309 int phymod_diag_prbs_get(phymod_phy_access_t *phys, int array_size, phymod_diag_prbs_get_args_t *params){
    310     int i = 0;
    311     int rv;
    312     phymod_prbs_status_t status;
    313     uint32_t enable;
    314     uint32_t flags = 0;
    315 
    316     
    317     for(i = 0 ; i < array_size ; i++){
    318 
    319         PHYMOD_PRBS_DIRECTION_RX_SET(flags);
    320         rv = phymod_phy_prbs_enable_get(&phys[i], flags, &enable);
    321         if(rv != PHYMOD_E_NONE){
    322             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Failed get PRBS configuration\n")));
    323             return rv;
    324         }
    325         if(enable == 0){
    326             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"PRBS status get can not be called when rx PRBS is disabled\n")));
    327             return PHYMOD_E_FAIL;
    328         }
    329         /*clear the status*/
    330         rv = phymod_phy_prbs_status_get(&phys[i], PHYMOD_PRBS_STATUS_F_CLEAR_ON_READ, &status);
    331         if(rv != PHYMOD_E_NONE){
    332             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"PRBS clear status failed\n")));
    333             return rv;
    334         }
    335     }
    336     /*wait*/
    337     PHYMOD_SLEEP(params->time);
    338 
    339     /*read the status*/
    340     for(i = 0 ; i < array_size ; i++){
    341         rv = phymod_phy_prbs_status_get(&phys[i], PHYMOD_PRBS_STATUS_F_CLEAR_ON_READ, &status);
    342         if(rv != PHYMOD_E_NONE){
    343             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"PRBS status read failed\n")));
    344             return rv;
    345         }
    346         phymod_diag_prbs_get_results_print(&phys[i], &status);
    347     }
    348     return PHYMOD_E_NONE;
    349 }
    350 
    351 
    352 STATIC
    353 int phymod_diag_prbs_clear(phymod_phy_access_t *phys, int array_size, phymod_diag_prbs_clear_args_t *params){
    354     int i = 0;
    355     int rv;
    356     
    357     for(i = 0 ; i < array_size ; i++){
    358         rv = phymod_phy_prbs_enable_set(&phys[i], params->flags, 0);
    359         if(rv  != PHYMOD_E_NONE){
    360             PHYMOD_DEBUG_ERROR((_PHYMOD_PHY_MSG(&phys[i],"Failed clear prbs\n")));
    361             return rv;
    362         }
    363     }
    364     return PHYMOD_E_NONE;
    365 }
    366 
    367 
    368 int phymod_diag_prbs(phymod_phy_access_t *phys, int array_size, phymod_diag_prbs_args_t *prbs_diag_args){
    369     int rv = PHYMOD_E_NONE;
    370 
    371     PHYMOD_DIAG_PRINT_FUNC_VALIDATE;
    372 
    373     switch(prbs_diag_args->prbs_cmd){
    374     case PhymodDiagPrbsClear:
    375         rv = phymod_diag_prbs_clear(phys, array_size, &prbs_diag_args->args.clear_params);
    376         break;
    377     case PhymodDiagPrbsGet:
    378         rv = phymod_diag_prbs_get(phys, array_size, &prbs_diag_args->args.get_params);
    379         break;
    380     case PhymodDiagPrbsSet:
    381         rv = phymod_diag_prbs_set(phys, array_size, &prbs_diag_args->args.set_params);
    382         break;
    383     default:
    384         PHYMOD_DEBUG_ERROR(("Failed parsing PRBS command type\n"));
    385         rv = PHYMOD_E_FAIL;
    386     }
    387     return rv;
    388 }
    389 
    390 
    391 /******************************************************************************
    392 DSC
    393  */
    394 int phymod_diag_dsc(phymod_phy_access_t *phys, int array_size){
    395 
    396     int i, rv = PHYMOD_E_NONE;
    397     uint32_t lane, lane_index;
    398 
    399     for(i = 0 ; i < array_size ; i++){
    400         lane = phys[i].access.lane_mask;
    401         for( lane_index = 0 ; lane_index < PHYMOD_MAX_LANES_PER_CORE; lane_index++){
    402             /*if lane is not selected pass*/
    403             if( (lane & (1<<lane_index)) == 0){
    404                 continue;
    405             }
    406             phys[i].access.lane_mask = lane & (1<<lane_index);
    407             /*collect info*/
    408             rv = phymod_phy_pmd_info_dump(&(phys[i]), NULL); 
    409 
    410             if(rv != PHYMOD_E_NONE) {
    411                 break;
    412             }
    413         }
    414         phys[i].access.lane_mask = lane;
    415         if(rv != PHYMOD_E_NONE) {
    416             break;
    417         }
    418     }
    419     return rv;
    420 }
    421 
    422 /******************************************************************************
    423 DSC
    424  */
    425 int phymod_diag_dsc_std(phymod_phy_access_t *phys, int array_size){
    426 
    427     int i, rv = PHYMOD_E_NONE;
    428     uint32_t lane, lane_index;
    429 
    430     for(i = 0 ; i < array_size ; i++){
    431         lane = phys[i].access.lane_mask;
    432         for( lane_index = 0 ; lane_index < PHYMOD_MAX_LANES_PER_CORE; lane_index++){
    433             /*if lane is not selected pass*/
    434             if( (lane & (1<<lane_index)) == 0){
    435                 continue;
    436             }
    437             phys[i].access.lane_mask |= lane & (1<<lane_index);
    438 
    439         }
    440         if (phys[i].access.lane_mask) {
    441             rv = phymod_phy_pmd_info_dump(&(phys[i]), "STD"); 
    442 
    443             if(rv != PHYMOD_E_NONE) {
    444                 break;
    445             }
    446         }
    447         phys[i].access.lane_mask = lane; 
    448     }
    449     return rv;
    450 }
    451 
    452 /******************************************************************************
    453 DSC
    454  */
    455 int phymod_diag_dsc_config(phymod_phy_access_t *phys, int array_size){
    456 
    457     int i, rv = PHYMOD_E_NONE;
    458     uint32_t lane, lane_index;
    459 
    460     for(i = 0 ; i < array_size ; i++){
    461         lane = phys[i].access.lane_mask;
    462         for( lane_index = 0 ; lane_index < PHYMOD_MAX_LANES_PER_CORE; lane_index++){
    463             /*if lane is not selected pass*/
    464             if( (lane & (1<<lane_index)) == 0){
    465                 continue;
    466             }
    467             phys[i].access.lane_mask = lane & (1<<lane_index);
    468             /*collect info*/
    469             rv = phymod_phy_pmd_info_dump(&(phys[i]), "config"); 
    470 
    471             if(rv != PHYMOD_E_NONE) {
    472                 break;
    473             }
    474         }
    475         phys[i].access.lane_mask = lane;
    476         if(rv != PHYMOD_E_NONE) {
    477             break;
    478         }
    479     }
    480     return rv;
    481 }
    482 
    483 
    484 /******************************************************************************
    485 Eyescan
    486  */
    487 int phymod_diag_eyescan_run( 
    488     phymod_phy_access_t *phys,
    489     int unit,
    490     int* port_ids,
    491     int* line_rates, 
    492     int num_phys,
    493     phymod_eyescan_mode_t mode,
    494     phymod_phy_eyescan_options_t* eyescan_options
    495     )   
    496 {
    497     const phymod_phy_access_t    *pa;
    498     int                 idx, rc = PHYMOD_E_NONE, rc_done = PHYMOD_E_NONE;
    499     uint32_t            flags;
    500     if(eyescan_options) {
    501       /* new code for BER projection */
    502       if(mode == phymodEyescanModeBERProj) {
    503         PHYMOD_DIAG_OUT((" ber_scan_mode   = %d\n", eyescan_options->ber_proj_scan_mode));
    504         PHYMOD_DIAG_OUT((" timer_control   = %d\n", eyescan_options->ber_proj_timer_cnt));
    505         PHYMOD_DIAG_OUT((" max_err_control = %d\n", eyescan_options->ber_proj_err_cnt));
    506       } else {
    507         PHYMOD_DIAG_OUT((" Timeout = %d ms\n",  eyescan_options->timeout_in_milliseconds));
    508         PHYMOD_DIAG_OUT((" Hmax    = %d\n",     eyescan_options->horz_max));
    509         PHYMOD_DIAG_OUT((" Hmin    = %d\n",     eyescan_options->horz_min));
    510         PHYMOD_DIAG_OUT((" Hstep   = %d\n",     eyescan_options->hstep));
    511         PHYMOD_DIAG_OUT((" Vmax    = %d\n",     eyescan_options->vert_max));
    512         PHYMOD_DIAG_OUT((" Vmin    = %d\n",     eyescan_options->vert_min));
    513         PHYMOD_DIAG_OUT((" Vstep   = %d\n",     eyescan_options->vstep));
    514         PHYMOD_DIAG_OUT((" mode    = %d\n",     eyescan_options->mode));
    515       }
    516     }
    517 
    518     /*enable eyescan*/
    519     flags = 0;
    520     PHYMOD_EYESCAN_F_ENABLE_SET(flags);
    521     PHYMOD_EYESCAN_F_ENABLE_DONT_WAIT_SET(flags);
    522 
    523     for (idx = 0; idx < num_phys; idx++) {
    524         pa = &(phys[idx]);
    525         rc = PHYMOD_E_NONE;
    526         if (pa->access.lane_mask){
    527             rc = phymod_phy_eyescan_run(pa, flags, mode, NULL);
    528         }
    529         if (rc != PHYMOD_E_NONE) {
    530             PHYMOD_DIAG_OUT(("Failed in phymod_phy_eyescan_run (enable) \n"));
    531             goto exit;
    532         }
    533     }
    534 
    535     PHYMOD_USLEEP(100000);
    536 
    537     /*process eyescan*/
    538     flags = 0;
    539     PHYMOD_EYESCAN_F_PROCESS_SET(flags);
    540 
    541     for (idx = 0; idx < num_phys; idx++) {
    542         pa = &(phys[idx]);
    543 
    544         if(eyescan_options && line_rates) {
    545             eyescan_options->linerate_in_khz = line_rates[idx];
    546         }
    547 
    548         PHYMOD_DIAG_OUT(("for u=%0d p=%0d lane_mask=%0x:\n", unit, port_ids[idx], pa->access.lane_mask));
    549         rc = phymod_phy_eyescan_run(pa, flags, mode, eyescan_options);
    550         if (rc != PHYMOD_E_NONE) {
    551             PHYMOD_DIAG_OUT(("Failed in phymod_phy_eyescan_run (process) \n"));
    552         }
    553     }
    554 
    555 exit:    
    556     /*disable eyescan mode*/
    557     flags = 0;
    558     PHYMOD_EYESCAN_F_DONE_SET(flags);
    559 
    560     for (idx = 0; idx < num_phys; idx++) {
    561 
    562         pa = &(phys[idx]);
    563 
    564         rc_done = phymod_phy_eyescan_run(pa, flags, mode, eyescan_options);
    565         if (rc_done != PHYMOD_E_NONE) {
    566             PHYMOD_DIAG_OUT(("Failed in phymod_phy_eyescan_run (done) \n"));
    567             if(rc == PHYMOD_E_NONE) { /* Update returned error code */
    568                 rc = rc_done;
    569             }
    570         }
    571     }
    572 
    573     return rc;
    574 }