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

tsce16_diagnostics.c (16574B)


      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 #include <phymod/phymod_util.h>
     15 #include "tsce16/tier1/temod16_enum_defines.h"
     16 #include "tsce16/tier1/temod16.h"
     17 #include "tsce16/tier1/te16PCSRegEnums.h"
     18 #include "merlin16/tier1/merlin16_diag.h"
     19 #include "merlin16/tier1/merlin16_debug_functions.h"
     20 #include "merlin16/tier1/common/srds_api_enum.h"
     21 #include "merlin16/tier1/merlin16_prbs.h"
     22 
     23 #ifdef PHYMOD_TSCE16_SUPPORT
     24 
     25 int tsce16_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type)
     26 {
     27     int start_lane, num_lane;
     28     int tmp_lane_mask;
     29     phymod_phy_access_t phy_copy;
     30 
     31     /* struct merlin16_detailed_lane_status_st lane_st[4]; */
     32     int i = 0;
     33     uint32_t cmd_type;
     34     int is_in_reset = 0;
     35 
     36 
     37     if (!type) {
     38         cmd_type = (uint32_t)TEMOD16_DIAG_DSC;
     39     } else if ((!PHYMOD_STRCMP(type, "ber")) ||
     40                (!PHYMOD_STRCMP(type, "Ber")) ||
     41                (!PHYMOD_STRCMP(type, "BER"))) {
     42         cmd_type = (uint32_t)TEMOD16_DIAG_BER;
     43     } else if ((!PHYMOD_STRCMP(type, "config")) ||
     44                (!PHYMOD_STRCMP(type, "Config")) ||
     45                (!PHYMOD_STRCMP(type, "CONFIG"))) {
     46         cmd_type = (uint32_t)TEMOD16_DIAG_CFG;
     47     } else if ((!PHYMOD_STRCMP(type, "cl72")) ||
     48                (!PHYMOD_STRCMP(type, "Cl72")) ||
     49                (!PHYMOD_STRCMP(type, "CL72"))) {
     50         cmd_type = (uint32_t)TEMOD16_DIAG_CL72;
     51     } else if ((!PHYMOD_STRCMP(type, "debug")) ||
     52                (!PHYMOD_STRCMP(type, "Debug")) ||
     53                (!PHYMOD_STRCMP(type, "DEBUG"))) {
     54         cmd_type = (uint32_t)TEMOD16_DIAG_DEBUG;
     55     } else if ((!PHYMOD_STRCMP(type, "state")) ||
     56                (!PHYMOD_STRCMP(type, "State")) ||
     57                (!PHYMOD_STRCMP(type, "STATE"))) {
     58         cmd_type = (uint32_t)TEMOD16_DIAG_STATE;
     59     } else if ((!PHYMOD_STRCMP(type, "verbose")) ||
     60                (!PHYMOD_STRCMP(type, "Verbose")) ||
     61                (!PHYMOD_STRCMP(type, "VERBOSE"))) {
     62         cmd_type = (uint32_t)TEMOD16_DIAG_ALL;
     63     } else if (!PHYMOD_STRCMP(type, "STD")) {
     64         cmd_type = (uint32_t)TEMOD16_DIAG_DSC_STD;
     65     } else {
     66         cmd_type = (uint32_t)TEMOD16_DIAG_STATE;
     67     }
     68 
     69     PHYMOD_DEBUG_ERROR((" %s:%d type = %d laneMask  = 0x%X\n", __func__, __LINE__, cmd_type, phy->access.lane_mask));
     70 
     71     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
     72  
     73     /*next figure out the lane num and start_lane based on the input*/
     74     PHYMOD_IF_ERR_RETURN
     75         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
     76 
     77     if (cmd_type == TEMOD16_DIAG_DSC) {
     78         PHYMOD_IF_ERR_RETURN
     79             (merlin16_display_core_state(&phy_copy.access));
     80         PHYMOD_IF_ERR_RETURN
     81             (merlin16_display_lane_state_hdr());
     82         for (i = 0; i < 4; i++) {
     83             phy_copy.access.lane_mask = 0x1 << i ;
     84             PHYMOD_IF_ERR_RETURN
     85                 (temod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset));
     86             if (is_in_reset) {
     87                 PHYMOD_DIAG_OUT(("    - skip lane=%0d\n", i));
     88                 continue;
     89             }
     90             PHYMOD_IF_ERR_RETURN
     91                 (merlin16_display_lane_state(&phy_copy.access));
     92        }
     93     } else if (cmd_type == TEMOD16_DIAG_DSC_STD) {
     94         PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
     95         PHYMOD_DIAG_OUT(("    | DSC Phy: 0x%03x lane_mask: 0x%02x                                  |\n", phy->access.addr, phy->access.lane_mask));
     96         PHYMOD_DIAG_OUT(("    +--------------------------------------------------------------------+\n"));
     97         PHYMOD_IF_ERR_RETURN
     98             (merlin16_display_core_state(&phy_copy.access));
     99         PHYMOD_IF_ERR_RETURN
    100             (merlin16_display_lane_state_hdr());
    101         for (i = 0; i < num_lane; i++) {
    102             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    103             PHYMOD_IF_ERR_RETURN
    104                 (temod16_pmd_x4_reset_get(&phy_copy.access, &is_in_reset));
    105             if (is_in_reset) {
    106                 PHYMOD_DIAG_OUT(("    - skip lane=%0d\n", (i + start_lane)));
    107                 continue;
    108             }
    109             PHYMOD_IF_ERR_RETURN
    110                 (merlin16_display_lane_state(&phy_copy.access));
    111         }
    112 
    113         PHYMOD_IF_ERR_RETURN
    114             (merlin16_read_event_log(&phy_copy.access));
    115     } else {
    116         for (i = 0; i < num_lane; i++) {
    117             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    118             
    119             switch (cmd_type) {
    120             case TEMOD16_DIAG_CFG:
    121                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    122                 if (i==0) {
    123                     tmp_lane_mask = phy_copy.access.lane_mask;
    124                     phy_copy.access.lane_mask = 1;
    125                     PHYMOD_IF_ERR_RETURN
    126                         (merlin16_display_core_config(&phy_copy.access));
    127                     phy_copy.access.lane_mask = tmp_lane_mask;
    128                 }
    129                 PHYMOD_IF_ERR_RETURN
    130                     (merlin16_display_lane_config(&phy_copy.access));
    131                 break;
    132             case TEMOD16_DIAG_CL72:
    133                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    134                 PHYMOD_IF_ERR_RETURN
    135                     (merlin16_display_cl72_status(&phy_copy.access));
    136                 break;
    137             case TEMOD16_DIAG_DEBUG:
    138                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    139                 PHYMOD_IF_ERR_RETURN
    140                     (merlin16_display_lane_debug_status(&phy_copy.access));
    141                 break;
    142             case TEMOD16_DIAG_BER:
    143                 PHYMOD_DEBUG_ERROR((" %s:%d type = BER\n", __func__, __LINE__));
    144                 break;
    145             case TEMOD16_DIAG_ALL:
    146                 PHYMOD_DEBUG_ERROR((" %s:%d type = CFG\n", __func__, __LINE__));
    147                 if (i==0) {
    148                     tmp_lane_mask = phy_copy.access.lane_mask;
    149                     phy_copy.access.lane_mask = 1;
    150                     PHYMOD_IF_ERR_RETURN
    151                         (merlin16_display_core_config(&phy_copy.access));
    152                     phy_copy.access.lane_mask = tmp_lane_mask;
    153                 }
    154                 PHYMOD_IF_ERR_RETURN
    155                     (merlin16_display_lane_config(&phy_copy.access));
    156 
    157                 PHYMOD_DEBUG_ERROR((" %s:%d type = CL72\n", __func__, __LINE__));
    158                 PHYMOD_IF_ERR_RETURN
    159                     (merlin16_display_cl72_status(&phy_copy.access));
    160 
    161                 PHYMOD_DEBUG_ERROR((" %s:%d type = DBG\n", __func__, __LINE__));
    162                 PHYMOD_IF_ERR_RETURN
    163                     (merlin16_display_lane_debug_status(&phy_copy.access));
    164                 break;
    165             case TEMOD16_DIAG_STATE:
    166             default:
    167                 PHYMOD_DEBUG_ERROR((" %s:%d type = DEF\n", __func__, __LINE__));
    168                  PHYMOD_IF_ERR_RETURN
    169                     (merlin16_display_core_state_hdr());
    170                  PHYMOD_IF_ERR_RETURN
    171                     (merlin16_display_core_state_line(&phy_copy.access));
    172                 PHYMOD_IF_ERR_RETURN
    173                     (merlin16_display_core_state(&phy_copy.access));
    174                 PHYMOD_IF_ERR_RETURN
    175                     (merlin16_display_lane_state_hdr());
    176                 PHYMOD_IF_ERR_RETURN
    177                     (merlin16_display_lane_state(&phy_copy.access));
    178                 PHYMOD_IF_ERR_RETURN
    179                     (merlin16_read_event_log(&phy_copy.access));
    180                 break;
    181             }
    182         }
    183     }
    184     return PHYMOD_E_NONE;
    185 }
    186 
    187 int tsce16_phy_pcs_info_dump(const phymod_phy_access_t* phy, const char* type)
    188 {
    189     phymod_phy_access_t phy_copy;
    190 
    191     PHYMOD_MEMCPY        (&phy_copy, phy, sizeof(phy_copy));
    192     PHYMOD_IF_ERR_RETURN (temod16_diag_disp(&phy_copy.access, type));
    193 
    194     return PHYMOD_E_NONE;
    195 }
    196 
    197 STATIC
    198 int _tsce16_prbs_poly_phymod_to_merlin16(phymod_prbs_poly_t phymod_poly, enum srds_prbs_polynomial_enum *merlin16_poly)
    199 {
    200     switch(phymod_poly){
    201     case phymodPrbsPoly7:
    202         *merlin16_poly = PRBS_7;
    203         break;
    204     case phymodPrbsPoly9:
    205         *merlin16_poly = PRBS_9;
    206         break;
    207     case phymodPrbsPoly11:
    208         *merlin16_poly = PRBS_11;
    209         break;
    210     case phymodPrbsPoly15:
    211         *merlin16_poly = PRBS_15;
    212         break;
    213     case phymodPrbsPoly23:
    214         *merlin16_poly = PRBS_23;
    215         break;
    216     case phymodPrbsPoly31:
    217         *merlin16_poly = PRBS_31;
    218         break;
    219     case phymodPrbsPoly58:
    220         *merlin16_poly = PRBS_58;
    221         break;
    222     default:
    223         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("unsupported poly for tsce16 %u"), phymod_poly));
    224     }
    225     return PHYMOD_E_NONE;
    226 }
    227 
    228 STATIC
    229 int _tsce16_prbs_poly_merlin16_to_phymod(enum srds_prbs_polynomial_enum merlin16_poly, phymod_prbs_poly_t *phymod_poly)
    230 {
    231     switch(merlin16_poly){
    232     case PRBS_7:
    233         *phymod_poly = phymodPrbsPoly7;
    234         break;
    235     case PRBS_9:
    236         *phymod_poly = phymodPrbsPoly9;
    237         break;
    238     case PRBS_11:
    239         *phymod_poly = phymodPrbsPoly11;
    240         break;
    241     case PRBS_15:
    242         *phymod_poly = phymodPrbsPoly15;
    243         break;
    244     case PRBS_23:
    245         *phymod_poly = phymodPrbsPoly23;
    246         break;
    247     case PRBS_31:
    248         *phymod_poly = phymodPrbsPoly31;
    249         break;
    250     case PRBS_58:
    251         *phymod_poly = phymodPrbsPoly58;
    252         break;
    253     default:
    254         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("uknown poly %u"), merlin16_poly));
    255     }
    256     return PHYMOD_E_NONE;
    257 }
    258 
    259 int tsce16_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs)
    260 {
    261     enum  srds_prbs_polynomial_enum merlin16_poly;
    262     int i, start_lane, num_lane;
    263     phymod_phy_access_t phy_copy;
    264     PHYMOD_IF_ERR_RETURN(_tsce16_prbs_poly_phymod_to_merlin16(prbs->poly, &merlin16_poly));
    265 
    266     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    267 
    268     /* next figure out the lane num and start_lane based on the input */
    269     PHYMOD_IF_ERR_RETURN
    270         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    271 
    272     /*first check which direction */
    273     if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    274         for (i = 0; i < num_lane; i++) {
    275             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    276                 continue;
    277             }
    278             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    279             PHYMOD_IF_ERR_RETURN
    280                     (merlin16_config_rx_prbs(&phy_copy.access, merlin16_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    281         }
    282     } else if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    283         for (i = 0; i < num_lane; i++) {
    284             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    285             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    286                 continue;
    287             }
    288             PHYMOD_IF_ERR_RETURN
    289                     (merlin16_config_tx_prbs(&phy_copy.access, merlin16_poly, prbs->invert));
    290         }
    291     } else {
    292         for (i = 0; i < num_lane; i++) {
    293             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    294             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    295                 continue;
    296             }
    297             PHYMOD_IF_ERR_RETURN
    298                     (merlin16_config_rx_prbs(&phy_copy.access, merlin16_poly, PRBS_INITIAL_SEED_HYSTERESIS,  prbs->invert));
    299             PHYMOD_IF_ERR_RETURN
    300                     (merlin16_config_tx_prbs(&phy_copy.access, merlin16_poly, prbs->invert));
    301         }
    302     }
    303 
    304     return PHYMOD_E_NONE;
    305 }
    306 
    307 int tsce16_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs)
    308 {
    309     enum srds_prbs_polynomial_enum merlin16_poly;
    310     enum srds_prbs_checker_mode_enum merlin16_checker_mode;
    311     uint8_t invert;
    312 
    313     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    314         PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_config(&phy->access, &merlin16_poly, &invert)); 
    315     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    316         PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_config(&phy->access, &merlin16_poly, &merlin16_checker_mode, &invert));
    317     } else {
    318         PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_config(&phy->access, &merlin16_poly, &invert));
    319     }
    320 
    321     prbs->invert = (uint32_t) invert;
    322     PHYMOD_IF_ERR_RETURN(_tsce16_prbs_poly_merlin16_to_phymod(merlin16_poly, &(prbs->poly)));
    323 
    324     return PHYMOD_E_NONE;
    325 }
    326 
    327 
    328 int tsce16_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable)
    329 {
    330     int i, start_lane, num_lane;
    331     phymod_phy_access_t phy_copy;
    332 
    333     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    334     /* next figure out the lane num and start_lane based on the input */
    335     PHYMOD_IF_ERR_RETURN
    336         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    337 
    338     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    339         for (i = 0; i < num_lane; i++) {
    340             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    341                 continue;
    342             }
    343             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    344             PHYMOD_IF_ERR_RETURN(merlin16_tx_prbs_en(&phy_copy.access, enable));
    345         }
    346     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    347         for (i = 0; i < num_lane; i++) {
    348             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    349                 continue;
    350             }
    351             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    352             PHYMOD_IF_ERR_RETURN(merlin16_rx_prbs_en(&phy_copy.access, enable));
    353         }
    354     } else {
    355         for (i = 0; i < num_lane; i++) {
    356             if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    357                 continue;
    358             }
    359             phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    360             PHYMOD_IF_ERR_RETURN(merlin16_tx_prbs_en(&phy_copy.access, enable));
    361             PHYMOD_IF_ERR_RETURN(merlin16_rx_prbs_en(&phy_copy.access, enable));
    362         }
    363     }
    364 
    365     return PHYMOD_E_NONE;
    366 }
    367 
    368 int tsce16_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable)
    369 {
    370     uint8_t enable_tmp;
    371 
    372     if (PHYMOD_PRBS_DIRECTION_TX_GET(flags)) {
    373         PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_en(&phy->access, &enable_tmp));
    374         *enable = enable_tmp;
    375     } else if (PHYMOD_PRBS_DIRECTION_RX_GET(flags)) {
    376         PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_en(&phy->access, &enable_tmp));
    377         *enable = enable_tmp;
    378     } else {
    379         PHYMOD_IF_ERR_RETURN(merlin16_get_tx_prbs_en(&phy->access, &enable_tmp));
    380         *enable = enable_tmp;
    381         PHYMOD_IF_ERR_RETURN(merlin16_get_rx_prbs_en(&phy->access, &enable_tmp));
    382         *enable &= enable_tmp;
    383     }
    384 
    385     return PHYMOD_E_NONE;
    386 }
    387 
    388 
    389 int tsce16_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status)
    390 {
    391     uint8_t status = 0;
    392     uint32_t prbs_err_count = 0;
    393     int i, start_lane, num_lane;
    394     phymod_phy_access_t phy_copy;
    395 
    396     PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy));
    397     /* next figure out the lane num and start_lane based on the input */
    398     PHYMOD_IF_ERR_RETURN
    399         (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane));
    400 
    401     prbs_status->prbs_lock = 0;
    402     prbs_status->error_count = 0;
    403     prbs_status->prbs_lock_loss = 0;
    404     prbs_status->prbs_lock = 1;
    405 
    406     for (i = 0; i < num_lane; i++) {
    407         if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) {
    408             continue;
    409         }
    410         phy_copy.access.lane_mask = 0x1 << (i + start_lane);
    411         PHYMOD_IF_ERR_RETURN(merlin16_prbs_chk_lock_state(&phy_copy.access, &status));
    412         if (status) {
    413             /*next check the lost of lock and error count */
    414             status = 0;
    415             PHYMOD_IF_ERR_RETURN
    416                 (merlin16_prbs_err_count_state(&phy_copy.access, &prbs_err_count, &status));
    417             PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS Error count :: %d\n", i, prbs_err_count));
    418             if (status) {
    419                 /*temp lost of lock */
    420                 prbs_status->prbs_lock_loss = 1;
    421             } else {
    422                 prbs_status->error_count += prbs_err_count;
    423             }
    424         } else {
    425             PHYMOD_DEBUG_VERBOSE((" Lane :: %d PRBS not locked\n", i ));
    426             prbs_status->prbs_lock = 0;
    427             /* return PHYMOD_E_NONE; */
    428         }
    429     }
    430 
    431     return PHYMOD_E_NONE;
    432 }
    433 
    434 
    435 #endif /* PHYMOD_TSCE16_SUPPORT */