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

dino_diagnostics.c (17903B)


      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_diagnostics.h>
     13 #include <phymod/phymod_diagnostics_dispatch.h>
     14 
     15 #ifdef PHYMOD_DINO_SUPPORT
     16 #include "../tier1/dino_cfg_seq.h"
     17 #include "../tier1/dino_diag_seq.h"
     18 #include "../tier1/dino_serdes/common/srds_api_enum.h"
     19 
     20 int _dino_phymod_prbs_poly_to_serdes_prbs_poly(uint16_t phymod_poly, uint16_t *serdes_poly)
     21 {
     22     switch (phymod_poly) {
     23         case phymodPrbsPoly7:
     24             *serdes_poly = PRBS_7;
     25         break;
     26         case phymodPrbsPoly9:
     27             *serdes_poly = PRBS_9;
     28         break;
     29         case phymodPrbsPoly11:
     30             *serdes_poly = PRBS_11;
     31         break;
     32         case phymodPrbsPoly15:
     33             *serdes_poly = PRBS_15;
     34         break;
     35         case phymodPrbsPoly23:
     36             *serdes_poly = PRBS_23;
     37         break;
     38         case phymodPrbsPoly31:
     39             *serdes_poly = PRBS_31;
     40         break;
     41         case phymodPrbsPoly58:
     42             *serdes_poly = PRBS_58;
     43         break;
     44         default: 
     45             return PHYMOD_E_PARAM;
     46     }
     47 
     48     return PHYMOD_E_NONE;
     49 }
     50 int _dino_serdes_prbs_poly_to_phymod_prbs_poly(uint16_t serdes_poly, phymod_prbs_poly_t *phymod_poly)
     51 {
     52     switch (serdes_poly) {
     53         case PRBS_7:
     54             *phymod_poly = phymodPrbsPoly7;
     55         break; 
     56         case PRBS_9:
     57             *phymod_poly = phymodPrbsPoly9;
     58         break; 
     59         case PRBS_11:
     60             *phymod_poly = phymodPrbsPoly11;
     61         break; 
     62         case PRBS_15:
     63             *phymod_poly = phymodPrbsPoly15;
     64         break; 
     65         case PRBS_23:
     66             *phymod_poly = phymodPrbsPoly23;
     67         break; 
     68         case PRBS_31:
     69             *phymod_poly = phymodPrbsPoly31;
     70         break; 
     71         case PRBS_58:
     72             *phymod_poly = phymodPrbsPoly58;
     73         break; 
     74         default: 
     75             return PHYMOD_E_PARAM;
     76     }
     77 
     78     return PHYMOD_E_NONE;
     79 }
     80 
     81 int dino_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs)
     82 {
     83     uint16_t lane = 0;
     84     uint16_t lane_mask = 0; 
     85     uint16_t if_side = 0;
     86     int num_lanes = 0;
     87     uint32_t chip_id = 0;
     88     uint32_t rev_id = 0;
     89     const phymod_access_t *pa = &phy->access;
     90 
     91     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
     92     DINO_GET_INTF_SIDE(phy, if_side);
     93     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
     94     DINO_GET_NUM_LANES(chip_id, num_lanes);
     95 
     96     for (lane = 0; lane < num_lanes ; lane ++) {
     97         if (lane_mask & (1 << lane)) {
     98             PHYMOD_IF_ERR_RETURN (
     99                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    100             PHYMOD_IF_ERR_RETURN(
    101                 _dino_phy_prbs_config_set(pa, flags, if_side, lane, prbs)); 
    102         }
    103     }
    104     PHYMOD_IF_ERR_RETURN (
    105         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    106 
    107     return PHYMOD_E_NONE;
    108 }
    109 
    110 int dino_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs)
    111 {
    112     uint16_t lane = 0;
    113     uint16_t lane_mask = 0;
    114     uint16_t if_side = 0;
    115     uint16_t serdes_poly = 0;
    116     uint16_t   chkr_mode = 0;
    117     int num_lanes = 0;
    118     uint32_t chip_id = 0;
    119     uint32_t rev_id = 0;
    120     const phymod_access_t *pa = &phy->access;
    121 
    122     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    123     DINO_GET_INTF_SIDE(phy, if_side);
    124     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    125     DINO_GET_NUM_LANES(chip_id, num_lanes);
    126 
    127     for (lane = 0; lane < num_lanes; lane ++) {
    128         if ((lane_mask & (1 << lane))) {
    129             PHYMOD_IF_ERR_RETURN (
    130                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    131             PHYMOD_IF_ERR_RETURN(
    132                 _dino_phy_prbs_config_get(pa, flags, if_side, lane, prbs, &serdes_poly, &chkr_mode)); 
    133             break;
    134         }
    135     }
    136     PHYMOD_IF_ERR_RETURN (
    137         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    138     PHYMOD_DEBUG_VERBOSE(("Checker POLY:%d\n", serdes_poly));
    139     PHYMOD_DEBUG_VERBOSE(("Checker mode:%d\n", chkr_mode));
    140     PHYMOD_IF_ERR_RETURN (
    141         _dino_serdes_prbs_poly_to_phymod_prbs_poly(serdes_poly, &prbs->poly));
    142 
    143     return PHYMOD_E_NONE;
    144 }
    145 
    146 int dino_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable)
    147 {
    148     uint16_t lane = 0;
    149     uint16_t lane_mask = 0;
    150     uint16_t if_side = 0;
    151     int num_lanes = 0;
    152     uint32_t chip_id = 0;
    153     uint32_t rev_id = 0;
    154     const phymod_access_t *pa = &phy->access;
    155 
    156     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    157     DINO_GET_INTF_SIDE(phy, if_side);
    158     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    159     DINO_GET_NUM_LANES(chip_id, num_lanes);
    160 
    161     for (lane = 0; lane < num_lanes; lane ++) {
    162         if (lane_mask & (1 << lane)) {
    163              PHYMOD_IF_ERR_RETURN (
    164                  _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    165              PHYMOD_IF_ERR_RETURN(
    166                  _dino_phy_prbs_enable_set(pa, flags, if_side, lane, enable));
    167         }
    168     }
    169     PHYMOD_IF_ERR_RETURN (
    170         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    171 
    172     return PHYMOD_E_NONE;
    173 }
    174 
    175 int dino_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable)
    176 {
    177     uint16_t lane = 0;
    178     uint16_t lane_mask = 0;
    179     uint16_t if_side = 0;
    180     int num_lanes = 0;
    181     uint32_t chip_id = 0;
    182     uint32_t rev_id = 0;
    183     const phymod_access_t *pa = &phy->access;
    184 
    185     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    186     DINO_GET_INTF_SIDE(phy, if_side);
    187     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    188     DINO_GET_NUM_LANES(chip_id, num_lanes);
    189 
    190     for (lane = 0; lane < num_lanes; lane ++) {
    191         if ((lane_mask & (1 << lane))) {
    192             PHYMOD_IF_ERR_RETURN (
    193                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    194             PHYMOD_IF_ERR_RETURN(
    195                 _dino_phy_prbs_enable_get(pa, flags, if_side, lane, enable));
    196             break;
    197         }
    198     }
    199     PHYMOD_IF_ERR_RETURN (
    200         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    201 
    202     return PHYMOD_E_NONE;
    203 }
    204 
    205 int dino_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status)
    206 {
    207     uint16_t lane = 0;
    208     uint16_t lane_mask = 0;
    209     uint16_t if_side = 0;
    210     int num_lanes = 0;
    211     uint32_t chip_id = 0;
    212     uint32_t rev_id = 0;
    213     const phymod_access_t *pa = &phy->access;
    214 
    215     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    216     DINO_GET_INTF_SIDE(phy, if_side);
    217     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    218     DINO_GET_NUM_LANES(chip_id, num_lanes);
    219 
    220     prbs_status->prbs_lock = 1;
    221     prbs_status->prbs_lock_loss = 1;
    222     prbs_status->error_count = 0;
    223 
    224     for (lane = 0; lane < num_lanes; lane ++) {
    225         if ((lane_mask & (1 << lane))) {
    226             PHYMOD_IF_ERR_RETURN (
    227                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    228             PHYMOD_IF_ERR_RETURN(
    229                 _dino_phy_prbs_status_get(pa, flags, if_side, lane, prbs_status));
    230         }
    231     }
    232     PHYMOD_IF_ERR_RETURN (
    233         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    234 
    235     return PHYMOD_E_NONE; 
    236 }
    237 
    238 int dino_core_diagnostics_get(const phymod_core_access_t* core, phymod_core_diagnostics_t* diag)
    239 {
    240     phymod_phy_access_t phy;
    241     const phymod_access_t *pa = &core->access;
    242     uint16_t lane_mask = 0;
    243     uint16_t if_side = 0; 
    244     uint16_t lane = 0;
    245     int num_lanes = 0;
    246     uint32_t chip_id = 0;
    247     uint32_t rev_id = 0;
    248 
    249     PHYMOD_MEMCPY(&phy, core, sizeof(phymod_core_access_t));
    250     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    251     DINO_GET_INTF_SIDE((&phy), if_side);
    252     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&core->access, &chip_id, &rev_id));
    253     DINO_GET_NUM_LANES(chip_id, num_lanes);
    254 
    255     for (lane = 0; lane < num_lanes; lane ++) {
    256         if ((lane_mask & (1 << lane))) {
    257             PHYMOD_IF_ERR_RETURN (
    258                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    259             PHYMOD_IF_ERR_RETURN(
    260                 _dino_core_diagnostics_get(pa, if_side, lane, diag));
    261             break;
    262         }
    263     }
    264     PHYMOD_IF_ERR_RETURN (
    265         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    266 
    267     return PHYMOD_E_NONE;
    268 }
    269 
    270 int dino_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag)
    271 {
    272     uint16_t lane = 0;
    273     uint16_t lane_mask = 0;
    274     uint16_t if_side = 0;
    275     int num_lanes = 0;
    276     uint32_t chip_id = 0;
    277     uint32_t rev_id = 0;
    278     const phymod_access_t *pa = &phy->access;
    279 
    280     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    281     DINO_GET_INTF_SIDE(phy, if_side);
    282     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    283     DINO_GET_NUM_LANES(chip_id, num_lanes);
    284 
    285     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    286     PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr));
    287     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    288     PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side));
    289     PHYMOD_DEBUG_VERBOSE(("***********************************************\n"));
    290 
    291     for (lane = 0; lane < num_lanes; lane ++) {
    292         if ((lane_mask & (1 << lane))) {
    293             PHYMOD_IF_ERR_RETURN (
    294                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    295             PHYMOD_IF_ERR_RETURN(
    296                 _dino_phy_diagnostics_get(pa, if_side, lane, diag));
    297         }
    298     }
    299     PHYMOD_IF_ERR_RETURN (
    300         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    301 
    302     return PHYMOD_E_NONE;
    303 }
    304 
    305 int dino_phy_eyescan_run (const phymod_phy_access_t* phy, uint32_t flags, phymod_eyescan_mode_t mode, const phymod_phy_eyescan_options_t* eyescan_options)
    306 {
    307     uint16_t lane = 0;
    308     uint16_t lane_mask = 0;
    309     uint16_t if_side = 0;
    310     int num_lanes = 0;
    311     uint32_t chip_id = 0;
    312     uint32_t rev_id = 0;
    313     const phymod_access_t *pa = &phy->access;
    314 
    315     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    316     DINO_GET_INTF_SIDE(phy, if_side);
    317     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    318     DINO_GET_NUM_LANES(chip_id, num_lanes);
    319 
    320     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    321     PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr));
    322     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    323     PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side));
    324     PHYMOD_DEBUG_VERBOSE(("***********************************************\n"));
    325 
    326     for (lane = 0; lane < num_lanes; lane ++) {
    327         if ((lane_mask & (1 << lane))) {
    328             PHYMOD_IF_ERR_RETURN (
    329                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    330             if (PHYMOD_EYESCAN_F_DONE_GET(flags)) {
    331                 switch(mode) {
    332                 case phymodEyescanModeFast:
    333                     PHYMOD_IF_ERR_RETURN (
    334                        _dino_phy_display_eyescan(pa, if_side, lane));
    335                  break;
    336                 case phymodEyescanModeBERProj:
    337                     PHYMOD_IF_ERR_RETURN (
    338                       _dino_ber_proj(phy, if_side, lane, eyescan_options));
    339                  break;
    340                 default:
    341                     PHYMOD_IF_ERR_RETURN (
    342                         _dino_phy_display_eyescan(pa, if_side, lane));
    343                   break;
    344                 }
    345             } else {
    346                 return PHYMOD_E_NONE;
    347             }
    348         }
    349     }
    350     PHYMOD_IF_ERR_RETURN (
    351         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    352    
    353     return PHYMOD_E_NONE;
    354 }
    355 
    356 int dino_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type)
    357 {
    358     uint16_t lane = 0;
    359     uint16_t lane_mask = 0;
    360     uint16_t if_side = 0;
    361     int num_lanes = 0;
    362     uint32_t chip_id = 0;
    363     uint32_t rev_id = 0;
    364     const phymod_access_t *pa = &phy->access;
    365 
    366     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    367     DINO_GET_INTF_SIDE(phy, if_side);
    368     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    369     DINO_GET_NUM_LANES(chip_id, num_lanes);
    370 
    371     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    372     PHYMOD_DEBUG_VERBOSE(("******* PHY status dump for PHY ID:%d ********\n", pa->addr));
    373     PHYMOD_DEBUG_VERBOSE(("**********************************************\n"));
    374     PHYMOD_DEBUG_VERBOSE(("**** PHY status dump for interface side:%d ****\n", if_side));
    375     PHYMOD_DEBUG_VERBOSE(("***********************************************\n"));
    376 
    377     /* For core status dump */
    378     for (lane = 0; lane < num_lanes; lane ++) {
    379         if ((lane_mask & (1 << lane))) {
    380             PHYMOD_IF_ERR_RETURN (
    381                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    382             PHYMOD_IF_ERR_RETURN(
    383                 _dino_phy_status_dump(pa, if_side, lane));
    384         }
    385     }
    386     PHYMOD_IF_ERR_RETURN (
    387         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    388 
    389     return PHYMOD_E_NONE;
    390 }
    391 
    392 /**  FC/PCS checker enable set
    393  *   This function is used to enable or disable FC/PCS checker
    394  *
    395  *    @param phy                Pointer to phymod phy access structure
    396  *    @param fcpcs_chkr_mode    FC/PCS checker mode
    397  *    @param enable             Enable or disable
    398  *        1 -  enable
    399  *        0 -  disable
    400  *
    401  *    @return PHYMOD_E_NONE     successful function execution
    402  */
    403 int dino_phy_link_mon_enable_set(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t fcpcs_chkr_mode, uint32_t enable)
    404 {
    405     uint16_t lane = 0;
    406     uint16_t lane_mask = 0;
    407     uint16_t if_side = 0;
    408     int num_lanes = 0;
    409     uint32_t chip_id = 0;
    410     uint32_t rev_id = 0;
    411     const phymod_access_t *pa = &phy->access;
    412 
    413     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    414     DINO_GET_INTF_SIDE(phy, if_side);
    415     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    416     DINO_GET_NUM_LANES(chip_id, num_lanes);
    417 
    418     for (lane = 0; lane < num_lanes; lane ++) {
    419         if ((lane_mask & (1 << lane))) {
    420             PHYMOD_IF_ERR_RETURN (
    421                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    422             PHYMOD_IF_ERR_RETURN(
    423                 _dino_phy_link_mon_enable_set(pa, enable));
    424         }
    425     }
    426 
    427     PHYMOD_IF_ERR_RETURN (
    428         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    429 
    430     return PHYMOD_E_NONE;
    431 }
    432 /**  FC/PCS checker enable get
    433  *   This function is used to check whether or not FC/PCS checker enabled
    434  *
    435  *    @param phy                Pointer to phymod phy access structure
    436  *    @param fcpcs_chkr_mode    FC/PCS checker mode
    437  *    @param enable             Enable or disable
    438  *        1 -  enable
    439  *        0 -  disable
    440  *
    441  *    @return PHYMOD_E_NONE     successful function execution
    442  */
    443 int dino_phy_link_mon_enable_get(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t fcpcs_chkr_mode, uint32_t *enable)
    444 {
    445     uint16_t lane = 0;
    446     uint16_t lane_mask = 0;
    447     uint16_t if_side = 0;
    448     int num_lanes = 0;
    449     uint32_t chip_id = 0;
    450     uint32_t rev_id = 0;
    451     const phymod_access_t *pa = &phy->access;
    452 
    453     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    454     DINO_GET_INTF_SIDE(phy, if_side);
    455     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    456     DINO_GET_NUM_LANES(chip_id, num_lanes);
    457     *enable = 1;
    458 
    459     for (lane = 0; lane < num_lanes; lane ++) {
    460         if ((lane_mask & (1 << lane))) {
    461             PHYMOD_IF_ERR_RETURN (
    462                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    463             PHYMOD_IF_ERR_RETURN (
    464                 _dino_phy_link_mon_enable_get(pa, enable));
    465             break;
    466         }
    467     }
    468     PHYMOD_IF_ERR_RETURN (
    469         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    470 
    471     return PHYMOD_E_NONE;
    472 }
    473 /**  FC/PCS checker status get
    474  *   This function is used to lock, loss of lock, error count status of the FC/PCS checker
    475  *
    476  *    @param phy                Pointer to phymod phy access structure
    477  *    @param lock_status        Live lock status
    478  *        1 - Locked
    479  *        0 - Not locked
    480  *    @param lock_lost_lh       Loss of lock
    481  *        1 -  Loss of lock happened
    482  *        0 -  No Loss of lock happended
    483  *    @param error_count        Error count
    484  *
    485  *    @return PHYMOD_E_NONE     successful function execution
    486  */
    487 int dino_phy_link_mon_status_get(const phymod_phy_access_t* phy, uint32_t* lock_status, uint32_t* lock_lost_lh, uint32_t* error_count)
    488 {
    489     uint16_t lane = 0;
    490     uint16_t lane_mask = 0;
    491     uint16_t if_side = 0;
    492     int num_lanes = 0;
    493     uint32_t chip_id = 0;
    494     uint32_t rev_id = 0;
    495     uint32_t enable = 0;
    496     const phymod_access_t *pa = &phy->access;
    497 
    498     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    499     DINO_GET_INTF_SIDE(phy, if_side);
    500     PHYMOD_IF_ERR_RETURN (dino_get_chipid(&phy->access, &chip_id, &rev_id));
    501     DINO_GET_NUM_LANES(chip_id, num_lanes);
    502     
    503     *lock_status = 1;
    504     *lock_lost_lh = 1;
    505     *error_count = 0;
    506     enable = 1;
    507 
    508     for (lane = 0; lane < num_lanes; lane ++) {
    509         if ((lane_mask & (1 << lane))) {
    510             PHYMOD_IF_ERR_RETURN (
    511                 _dino_set_slice_reg (pa, DINO_SLICE_UNICAST, if_side, lane));
    512             PHYMOD_IF_ERR_RETURN (
    513                 _dino_phy_link_mon_enable_get(pa, &enable));
    514             if (enable) {
    515                 PHYMOD_IF_ERR_RETURN (
    516                     _dino_phy_link_mon_status_get(pa, lock_status, lock_lost_lh, error_count));
    517             } else {
    518                 *lock_status &= 0;
    519                 *lock_lost_lh &= 1;
    520                 *error_count = 0;
    521             }
    522         }
    523     }
    524     PHYMOD_IF_ERR_RETURN (
    525         _dino_set_slice_reg (pa, DINO_SLICE_RESET, DINO_IF_LINE, 0));
    526 
    527     return PHYMOD_E_NONE;
    528 }
    529 #endif /* PHYMOD_DINO_SUPPORT */