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

portmod.c (78062B)


      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 
     11 #include <appl/diag/shell.h>
     12 #include <appl/diag/system.h>
     13 #include <appl/diag/parse.h>
     14 #include <appl/diag/diag.h>
     15 #include <appl/diag/dport.h>
     16 #include <shared/bsl.h>
     17 #include <bcm/error.h>
     18 #include <bcm/debug.h>
     19 #include <bcm/port.h>
     20 
     21 #include <soc/portmod/portmod.h>
     22 #include <soc/portmod/portmod_internal.h>
     23 #include <soc/eyescan.h>
     24 #include <soc/phy/phyctrl.h>
     25 #include <phymod/phymod_diag.h>
     26 
     27 
     28 
     29 #define MAX_PORTS (500)
     30 #define START_PORT (1)
     31 #define MAX_PMS (66)
     32 #define SUB_PHYS_NUM (4)
     33 #define MAX_PHYS_PER_PORT (24)
     34 
     35 
     36 typedef cmd_result_t (*portmod_diag_action_func_ptr_t)(int unit, args_t* a);
     37 typedef void (*portmod_diag_usage_func_ptr_t)(int unit);
     38 typedef int (*portmod_diag_id_supported_func_ptr_t)(int unit, int diag_id);
     39 
     40 /*!
     41  * @struct portmod_port_diag_status_s
     42  * @brief This structure return port diagnostics information from the PMM 
     43  */ 
     44 typedef struct portmod_port_diag_status_s {
     45     int enable; /**< indicate port is enabled or disabled */
     46     int link; /**< indicate link status */
     47     int loopback; /**< indicate loopback status */
     48     int lf; /**< indicate local fault status */
     49     int rf; /**< indicate remote fault status */
     50     portmod_port_interface_config_t config;
     51     portmod_port_pcs_t encoding;
     52     phymod_autoneg_status_t an_status; /**< auto-negotiation status */
     53     portmod_llfc_control_t llfc_control; /**< llfc control status */
     54     portmod_pfc_control_t pfc_control; /**< pfc control status */
     55     portmod_pfc_config_t pfc_config; /**< pfc config status */
     56     portmod_port_ability_t local_ability; /**< local_ability */
     57     portmod_port_ability_t adv_ability; /**< adv_ability */
     58     portmod_port_ability_t remote_ability; /**< remote_ability */
     59     portmod_pbmp_t phys; /**< The PHYs that assemble the port */
     60     int sub_phy; /**< qsgmii only; Sub PHY index */
     61 } portmod_port_diag_status_t;
     62 
     63 
     64 /*!
     65  * @struct portmod_port_diag_fc_s
     66  * @brief This structure return port diagnostics flow control status from the PMM 
     67  */ 
     68 typedef struct portmod_port_diag_fc_s {
     69     portmod_llfc_control_t llfc_ctrl; /**< llfc control status */
     70     portmod_pfc_control_t pfc_ctrl; /**< pfc control status */
     71     portmod_pfc_config_t pfc_cfg; /**< pfc config status */
     72 } portmod_port_diag_fc_t;
     73 
     74 
     75 /*!
     76  * @struct portmod_port_diag_autoneg_s
     77  * @brief This structure return port diagnostics auto-negotiation status from the PMM 
     78  */ 
     79 typedef struct portmod_port_diag_autoneg_s {
     80     portmod_port_ability_t local_ability; /**< local_ability */
     81     portmod_port_ability_t adv_ability; /**< adv_ability */
     82     portmod_port_ability_t remote_ability; /**< remote_ability */
     83 } portmod_port_diag_autoneg_t;
     84 
     85 
     86 /*!
     87  * @struct portmod_port_diag_prbs_s
     88  * @brief This structure for prbs diagnostics including config/enable/status 
     89  */ 
     90 typedef struct portmod_port_diag_prbs_s {
     91     int enable; /**< prbs enable */
     92     int flags; /**< prbs direction */
     93     int mode; /**< phy or mac */
     94     char *cmd; /**< set/get/clear */
     95     int interval; /**< sleep interval */
     96     phymod_prbs_t prbs_config; /**< prbs config */
     97     phymod_prbs_status_t prbs_status; /**< prbs status */
     98 } portmod_port_diag_prbs_t;
     99 
    100 
    101 typedef struct portmod_diag_table_s {
    102     char* cmd_name; /*Command name*/
    103     portmod_diag_action_func_ptr_t action_func; /*Callback to command fuction*/
    104     char* cmd_short_desc; /*shortly describe the command*/
    105     portmod_diag_usage_func_ptr_t usage_func; /*Callback to command usage function*/
    106     int diag_id; /*diag id - used in order to make sure this command is supported by the device*/
    107 } portmod_diag_table_t;
    108 
    109 
    110 
    111 char portmod_diag_usage[] = "portmod <options>\n"
    112 #ifndef COMPILER_STRING_CONST_LIMIT
    113      "  usage                      -display detailed portmod diagnostic usage\n"
    114      "  info port[=port-id]        -display port detailed or summary SW information\n"
    115      "  info pm[=pm_id]]           -display pm detailed or summary SW information\n"
    116      "  status port[=port-id]      -display port detailed or summary HW status\n"
    117      "  fc port=<port-id>          -display PFC/LLFC information of the specific port\n"
    118      "  autoneg port=<port-id>     -display auto-negotiation ability of the specific port\n"
    119      "  core port=<port-id>        -display core information which the specific port belongs to\n"
    120      "  phy port=<port-id>         -display phy/lane information the specific port includes\n"
    121      "  prbs set port=<port-id> [mode=<phy|mac> polynomial=<value> Loopback=<true|false> Invert=<value>]\n"
    122      "                             -set PRBS generator on the port-id specific port\n"
    123      "  prbs get port=<port-id>    -get internal checker on the port-id specific port\n"
    124      "  prbs clear port=<port-id>  -clear internal PRBS configuration on the port-id specific port\n"
    125      "  eyescan port=<port-id> [vertical_max=<value> vertical_min=<value> vertical_step=<value>\n"
    126      "          horizontal_max=<value> horizontal_min=<value> horizontal_step=<value> \n"
    127      "          sample_time=<value> ber=<value> lane=<value> mode=<fast/lowBER>]\n"
    128      "                             -run eyescan test\n"
    129      "  regdump port=<port-id      -dump all registers of the sepecific port\n"
    130 #endif
    131      ;
    132 #ifdef PORTMOD_DIAG
    133 
    134 STATIC cmd_result_t
    135 enum_value_to_string(enum_mapping_t *mapping,  int val, char **str)
    136 {
    137     char *key;
    138     int i = 0;
    139 
    140     key = mapping[0].key;
    141     while (key != NULL) {
    142         if (val == mapping[i].enum_value) {
    143             *str = mapping[i].key;
    144             return CMD_OK;
    145         }
    146         i++;
    147         key = mapping[i].key;
    148     }
    149     return CMD_FAIL;
    150 }
    151 
    152 
    153 STATIC cmd_result_t
    154 portmod_port_diag_status_get(int unit, int port, portmod_port_diag_status_t *diag_status){
    155     int ret;
    156     portmod_port_interface_config_t config;
    157     portmod_port_diag_info_t diag_info;
    158     uint32 properties = 0;
    159 
    160     if(NULL == diag_status){
    161         cli_out("diag_status is null pointer");
    162         return CMD_FAIL;
    163     }
    164     sal_memset(&diag_info, 0, sizeof(portmod_port_diag_info_t));
    165     sal_memset(&config, 0, sizeof(portmod_port_interface_config_t));
    166     ret = portmod_port_interface_config_get(unit, port, &config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY);
    167     if(ret != SOC_E_NONE){
    168         cli_out("ERROR: Getting port interface config failed: %s\n", soc_errmsg(ret));
    169         return CMD_FAIL;
    170     }
    171     ret = portmod_port_encoding_get(unit, port, &properties, &diag_status->encoding);
    172 
    173     if(ret != SOC_E_NONE){
    174         cli_out("ERROR: Getting port encoding failed: %s\n", soc_errmsg(ret));
    175         return CMD_FAIL;
    176     }
    177     
    178     ret = portmod_port_link_get(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &diag_status->link);
    179     if(ret != SOC_E_NONE){     
    180         cli_out("ERROR: Getting port link failed: %s\n", soc_errmsg(ret));     
    181         return CMD_FAIL;                                    
    182     }  
    183     ret = portmod_port_autoneg_status_get(unit, port, &diag_status->an_status);
    184     if(ret != SOC_E_NONE){     
    185         cli_out("ERROR: Getting port auto-negociation status failed: %s\n", soc_errmsg(ret));     
    186         return CMD_FAIL;                                    
    187     }
    188     ret = portmod_port_loopback_get(unit, port, portmodLoopbackPhyRloopPMD, &diag_status->loopback);
    189     if(ret != SOC_E_NONE){     
    190         cli_out("ERROR: Getting port loopback status failed: %s\n", soc_errmsg(ret));     
    191         return CMD_FAIL;                                    
    192     }  
    193     ret = portmod_port_enable_get(unit, port, 0, &diag_status->enable);
    194     if(ret != SOC_E_NONE){     
    195         cli_out("ERROR: Getting port enable status failed: %s\n", soc_errmsg(ret));     
    196         return CMD_FAIL;                                    
    197     }  
    198     ret = portmod_port_local_fault_status_get(unit, port, &diag_status->lf);
    199     if(ret != SOC_E_NONE){     
    200         cli_out("ERROR: Getting port local fault status failed: %s\n", soc_errmsg(ret));     
    201         return CMD_FAIL;                                    
    202     }  
    203     ret = portmod_port_remote_fault_status_get(unit, port, &diag_status->rf);
    204     if(ret != SOC_E_NONE){     
    205         cli_out("ERROR: Getting port remote fault status failed: %s\n", soc_errmsg(ret));     
    206         return CMD_FAIL;                                    
    207     }  
    208 
    209     /*get port-phy mapping*/
    210     ret = portmod_port_diag_info_get(unit, port, &diag_info);
    211     if(ret != SOC_E_NONE){     
    212         cli_out("ERROR: Getting port info failed: %s\n", soc_errmsg(ret));     
    213         return CMD_FAIL;                                    
    214     }  
    215     sal_memcpy(&diag_status->phys, &diag_info.phys, sizeof(portmod_pbmp_t));
    216     
    217     return CMD_OK;
    218 }
    219 
    220 STATIC cmd_result_t
    221 portmod_port_diag_fc_get(int unit, int port, portmod_port_diag_fc_t* diag_fc){
    222     int ret;
    223 
    224     if(NULL == diag_fc){
    225         cli_out("diag_fc is null pointer");  
    226         return CMD_FAIL;
    227     }
    228 
    229     /* get flow control status */
    230     ret = portmod_port_llfc_control_get(unit, port, &diag_fc->llfc_ctrl);
    231     if(ret != SOC_E_NONE){     
    232         cli_out("ERROR: Getting port llfc control failed: %s\n", soc_errmsg(ret));     
    233         return CMD_FAIL;                                    
    234     } 
    235     ret = portmod_port_pfc_control_get(unit, port, &diag_fc->pfc_ctrl);
    236     if(ret != SOC_E_NONE){     
    237         cli_out("ERROR: Getting port pfc control failed: %s\n", soc_errmsg(ret));     
    238         return CMD_FAIL;                                    
    239     } 
    240     ret = portmod_port_pfc_config_get(unit, port, &diag_fc->pfc_cfg);
    241     if(ret != SOC_E_NONE){     
    242         cli_out("ERROR: Getting port pfc config: %s\n", soc_errmsg(ret));     
    243         return CMD_FAIL;                                    
    244     } 
    245 
    246     return CMD_OK;
    247 
    248 }
    249 
    250 STATIC cmd_result_t
    251 portmod_port_diag_autoneg_get(int unit, int port, portmod_port_diag_autoneg_t* diag_autoneg){
    252     int ret;
    253 
    254     if(NULL == diag_autoneg){
    255         cli_out("diag_autoneg is null pointer");
    256         return CMD_FAIL;
    257     }
    258     
    259     /* get flow control status */
    260     ret = portmod_port_ability_local_get(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &diag_autoneg->local_ability);
    261     if(ret != SOC_E_NONE){
    262         cli_out("ERROR: Getting port local ability failed: %s\n", soc_errmsg(ret));
    263         return CMD_FAIL;
    264     }
    265     ret = portmod_port_ability_advert_get(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &diag_autoneg->adv_ability);
    266     if(ret != SOC_E_NONE){
    267         cli_out("ERROR: Getting port advertisement ability failed: %s\n", soc_errmsg(ret));
    268         return CMD_FAIL;
    269     }
    270     ret = portmod_port_ability_remote_get(unit, port, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, &diag_autoneg->remote_ability);
    271     if(ret != SOC_E_NONE){
    272         cli_out("ERROR: Getting port recieved ability failed: %s\n", soc_errmsg(ret));
    273         return CMD_FAIL;
    274     }
    275 
    276     return CMD_OK;
    277 }
    278 
    279 STATIC cmd_result_t
    280 portmod_port_diag_core_info_get(int unit, int port, phymod_core_diagnostics_t* diag_core, phymod_core_firmware_info_t* diag_firmware){
    281     int ret, nof_cores;
    282     phymod_core_access_t core_access;
    283     portmod_access_get_params_t access_param;
    284 
    285     if(NULL == diag_core){
    286         cli_out("diag_core is null pointer");  
    287         return CMD_FAIL;
    288     }
    289     if(NULL == diag_firmware){
    290         cli_out("diag_firmware is null pointer");  
    291         return CMD_FAIL;
    292     }
    293 
    294     /* get phy polority and nof_phys */
    295     ret = portmod_access_get_params_t_init(unit, &access_param);
    296     if(ret != SOC_E_NONE){     
    297         cli_out("ERROR: Access parameters init failed: %s\n", soc_errmsg(ret));     
    298         return CMD_FAIL;                                    
    299     } 
    300     ret = portmod_port_main_core_access_get(unit, port, -1, &core_access, &nof_cores);
    301     if(ret != SOC_E_NONE){     
    302         cli_out("ERROR: Core access get failed: %s\n", soc_errmsg(ret));     
    303         return CMD_FAIL;                                    
    304     } 
    305     ret = phymod_core_diagnostics_get(&core_access, diag_core);
    306     if(ret != SOC_E_NONE){     
    307         cli_out("ERROR: Getting core diag failed: %s\n", soc_errmsg(ret));     
    308         return CMD_FAIL;                                    
    309     }   
    310     ret = phymod_core_firmware_info_get(&core_access, diag_firmware);
    311     if(ret != SOC_E_NONE){     
    312         cli_out("ERROR: Getting core firmware info failed: %s\n", soc_errmsg(ret));     
    313         return CMD_FAIL;                                    
    314     } 
    315 
    316     return CMD_OK;
    317 }
    318 
    319 STATIC cmd_result_t
    320 portmod_port_diag_phy_info_get(int unit, int port, int phyn, int lane, int port_loc, phymod_phy_diagnostics_t* diag_phy){
    321     int ret, nof_phys;
    322     phymod_phy_access_t phy_access;
    323     phymod_phy_access_t phy_access12[3];
    324     portmod_access_get_params_t access_param;
    325 
    326     if(NULL == diag_phy){
    327         cli_out("diag_phy is null pointer");  
    328         return CMD_FAIL;
    329     }
    330 
    331     /* get phy polority and nof_phys */
    332     ret = portmod_access_get_params_t_init(unit, &access_param);
    333     access_param.phyn = phyn;
    334     access_param.lane = lane;
    335     access_param.sys_side = port_loc;
    336 
    337     if(ret != SOC_E_NONE){
    338         cli_out("ERROR: Access parameters init failed: %s\n", soc_errmsg(ret));
    339         return CMD_FAIL;
    340     } 
    341     if (IS_C_PORT(unit, port)) {
    342         ret = portmod_port_phy_lane_access_get(unit, port, &access_param,
    343                                                3, &phy_access12[0], 
    344                                                &nof_phys, NULL);
    345     } else {
    346         ret = portmod_port_phy_lane_access_get(unit, port, &access_param,
    347                                                1, &phy_access, &nof_phys, NULL);
    348     }
    349     if(ret != SOC_E_NONE){
    350         cli_out("ERROR: Core access get failed: %s\n", soc_errmsg(ret));
    351         return CMD_FAIL;
    352     }
    353     if (IS_C_PORT(unit, port)) {
    354         if(nof_phys > 0){
    355             if(phy_access12[0].access.lane_mask){
    356                 ret = phymod_phy_diagnostics_get(&phy_access12[0], diag_phy);
    357             }
    358         } else {
    359             cli_out("ERROR: Getting phy diagnostics info failed. No matching phy found.\n");
    360             return CMD_FAIL;
    361         }
    362     } else {
    363         ret = phymod_phy_diagnostics_get(&phy_access, diag_phy);
    364     }
    365     if(ret != SOC_E_NONE){
    366         cli_out("ERROR: Getting phy diagnostics info failed: %s\n", soc_errmsg(ret));
    367         return CMD_FAIL;
    368     } 
    369 
    370     return CMD_OK;
    371 }
    372 
    373 STATIC cmd_result_t
    374 portmod_port_diag_prbs_run(int unit, int port, portmod_port_diag_prbs_t* diag_prbs){
    375     int ret;
    376 
    377     if(NULL == diag_prbs){
    378         cli_out("diag_prbs is null pointer");  
    379         return CMD_FAIL;
    380     }
    381 
    382     if (sal_strcasecmp(diag_prbs->cmd, "set") == 0){
    383         /* Set prbs configuration and enable prbs*/
    384         ret = portmod_port_prbs_config_set(unit, port, diag_prbs->mode, diag_prbs->flags, &diag_prbs->prbs_config);
    385         if(ret != SOC_E_NONE){     
    386             cli_out("ERROR: port prbs config set failed: %s\n", soc_errmsg(ret));     
    387             return CMD_FAIL;                                    
    388         }
    389         ret = portmod_port_prbs_enable_set(unit, port, diag_prbs->mode, diag_prbs->flags, diag_prbs->enable);
    390         if(ret != SOC_E_NONE){     
    391             cli_out("ERROR: port prbs enable set failed: %s\n", soc_errmsg(ret));     
    392             return CMD_FAIL;                                    
    393         }
    394     }
    395     else if (sal_strcasecmp(diag_prbs->cmd, "clear") == 0){
    396         /*disable prbs*/
    397         ret = portmod_port_prbs_enable_set(unit, port, diag_prbs->mode, diag_prbs->flags, diag_prbs->enable);
    398         if(ret != SOC_E_NONE){     
    399             cli_out("ERROR: port prbs enable set failed: %s\n", soc_errmsg(ret));     
    400             return CMD_FAIL;                                    
    401         }
    402     }
    403     else if (sal_strcasecmp(diag_prbs->cmd, "get") == 0){ 
    404         sal_sleep(diag_prbs->interval);
    405         /*check prbs results*/
    406         ret = portmod_port_prbs_status_get(unit, port, diag_prbs->mode, diag_prbs->flags, &diag_prbs->prbs_status);
    407         if(ret != SOC_E_NONE){     
    408             cli_out("ERROR: port prbs status get failed: %s\n", soc_errmsg(ret));     
    409             return CMD_FAIL;                                    
    410         }
    411     }
    412 
    413     return CMD_OK;
    414 }
    415 
    416 STATIC cmd_result_t
    417 portmod_port_diag_phy_regdump(int unit, int port){
    418     int ret, nof_phys;
    419     phymod_phy_access_t phy_access;
    420     phymod_phy_access_t phy_access12[3];
    421     portmod_access_get_params_t access_param;
    422 
    423     /* get phy polority and nof_phys */
    424     ret = portmod_access_get_params_t_init(unit, &access_param);
    425     if(ret != SOC_E_NONE){     
    426         cli_out("ERROR: Access parameters init failed: %s\n", soc_errmsg(ret));     
    427         return CMD_FAIL;                                    
    428     } 
    429     if (IS_C_PORT(unit, port)) {
    430         ret = portmod_port_phy_lane_access_get(unit, port, &access_param,
    431                                                3, &phy_access12[0], &nof_phys, NULL);
    432     } else {
    433         ret = portmod_port_phy_lane_access_get(unit, port, &access_param,
    434                                                1, &phy_access, &nof_phys, NULL);
    435     }
    436     if(ret != SOC_E_NONE){     
    437         cli_out("ERROR: phy access get failed: %s\n", soc_errmsg(ret));     
    438         return CMD_FAIL;                                    
    439     } 
    440     if (IS_C_PORT(unit, port)) {
    441         ret = phymod_phy_status_dump(&phy_access12[0]);
    442     } else {
    443         ret = phymod_phy_status_dump(&phy_access);
    444     }
    445     if(ret != SOC_E_NONE){     
    446         cli_out("ERROR: phy status dump %s\n", soc_errmsg(ret));     
    447         return CMD_FAIL;                                    
    448     } 
    449 
    450     return CMD_OK;
    451 }
    452 
    453 
    454 STATIC cmd_result_t
    455 portmod_info_pm_summary_diag(int unit){
    456     cmd_result_t ret = CMD_OK;
    457     int phy, port, pm;
    458     int range_start, range_end;
    459     char *pm_type = "";
    460     char *unknow_string = "unknown";
    461     int is_first_range;
    462     int is_virtual = FALSE;
    463     portmod_pm_diag_info_t diag_info;
    464 
    465    
    466     cli_out(" PM id |    type     |    phys    | logic ports \n");
    467     cli_out("------------------------------------------------\n");
    468     for( pm = 0; pm <= MAX_PMS; pm++){
    469         ret = portmod_pm_diag_info_get(unit, pm, &diag_info);
    470         if (BCM_FAILURE(ret)){
    471             continue;
    472         }
    473         if(diag_info.type == portmodDispatchTypeCount){
    474             /*invalid port*/
    475             continue;
    476         }
    477         ret = enum_value_to_string(portmod_dispatch_type_t_mapping, diag_info.type, &pm_type);
    478         if(CMD_OK != ret){
    479             pm_type = unknow_string;
    480         }
    481         cli_out("   %02d  | %-10s  | ",  pm, pm_type);
    482         is_virtual = TRUE;
    483         /*add phys_str*/
    484 
    485         PORTMOD_PBMP_ITER(diag_info.phys, phy){
    486             is_virtual = FALSE;
    487             break;
    488         }
    489         if(is_virtual){
    490             cli_out("\n");
    491             continue;
    492         } 
    493         
    494         range_start = phy;
    495         range_end = phy;
    496         is_first_range = TRUE;
    497         PORTMOD_PBMP_ITER(diag_info.phys, phy){
    498             if(phy == range_start){ /*first one*/
    499                 continue;
    500             }
    501             if(phy != range_end + 1){
    502                 if(!is_first_range){
    503                     cli_out(",");
    504                 }
    505                 cli_out("%03d - %03d", range_start, range_end);
    506                 range_start = phy;
    507                 range_end = phy;
    508                 is_first_range = FALSE;
    509             }
    510             else{
    511                 range_end++;
    512             }
    513         }
    514         if(!is_first_range){
    515             cli_out(",");
    516         }
    517         cli_out("%03d - %03d  |", range_start, range_end);
    518 
    519 
    520         /*display ports which belongs to this PM*/
    521         SOC_PBMP_ITER(diag_info.ports, port){
    522             break;
    523         }
    524         if (port >= MAX_PORTS){
    525             cli_out("no port attached\n");
    526             continue;
    527         }
    528 
    529         range_start = port;
    530         range_end = port;
    531         is_first_range = TRUE;
    532         SOC_PBMP_ITER(diag_info.ports, port){
    533             if(port == range_start){ 
    534                 continue;
    535             }
    536             if(port != range_end + 1){
    537                 if(!is_first_range){
    538                     cli_out(",");
    539                 }
    540                 if (range_start == range_end){
    541                     cli_out("%03d", range_start);
    542                 } 
    543                 else {
    544                     cli_out("%03d - %03d", range_start, range_end);
    545                 }
    546                 range_start = port;
    547                 range_end = port;
    548                 is_first_range = FALSE;
    549             }
    550             else{
    551                 range_end++;
    552             }
    553         }
    554         if(!is_first_range){
    555             cli_out(",");
    556         }
    557         if (range_start == range_end){
    558             cli_out("%03d\n", range_start);
    559         }else {
    560             cli_out("%03d - %03d\n", range_start, range_end);
    561         }
    562 
    563 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    564         if(diag_info.type == portmodDispatchTypePm4x10_qtc){
    565             /*Pm4x10_qtc uses two pm ids*/
    566             pm ++;
    567         }
    568 #endif
    569     }
    570     return CMD_OK;
    571 }
    572 
    573 
    574 STATIC cmd_result_t
    575 portmod_info_pm_detail_diag(int unit, int pm){
    576     cmd_result_t ret = CMD_OK;
    577     int i, phy, port;
    578     int range_start, range_end;
    579     char *pm_type = "";
    580     char *ref_clk = "";
    581     char *unknow_string = "unknown";
    582     int is_first_range;
    583     portmod_pm_diag_info_t diag_info;
    584 
    585     sal_memset(&diag_info, 0, sizeof(portmod_pm_diag_info_t));
    586     ret = portmod_pm_diag_info_get(unit, pm, &diag_info);
    587     if (BCM_FAILURE(ret)){
    588         return CMD_FAIL;
    589     }
    590     if(diag_info.type == portmodDispatchTypeCount){
    591         /*invalid port*/
    592         return CMD_USAGE;
    593     }
    594     
    595     ret = enum_value_to_string(portmod_dispatch_type_t_mapping, diag_info.type, &pm_type);
    596     if(CMD_OK != ret){
    597         pm_type = unknow_string;
    598     }
    599     cli_out("PM ID: %02d\n",  pm);
    600     cli_out("PM Type: %-10s\n", pm_type);
    601 
    602     /*add phys_str*/
    603     cli_out("Phys: ");
    604     /*is_virtual = TRUE;*/
    605     PORTMOD_PBMP_ITER(diag_info.phys, phy){
    606         break;
    607     }
    608     
    609     range_start = phy;
    610     range_end = phy;
    611     is_first_range = TRUE;
    612     PORTMOD_PBMP_ITER(diag_info.phys, phy){
    613         if(phy == range_start){ /*first one*/
    614             continue;
    615         }
    616         if(phy != range_end + 1){
    617             if(!is_first_range){
    618                 cli_out(",");
    619             }
    620             cli_out("%03d - %03d", range_start, range_end);
    621             range_start = phy;
    622             range_end = phy;
    623             is_first_range = FALSE;
    624         }
    625         else{
    626             range_end++;
    627         }
    628     }
    629     if(!is_first_range){
    630         cli_out(",");
    631     }
    632     cli_out("%03d - %03d\n", range_start, range_end);
    633 
    634     /*display ports attached to this PM*/
    635     cli_out("Logical Ports Attached: ");
    636     SOC_PBMP_ITER(diag_info.ports, port){
    637         break;
    638     }
    639     if (port >= MAX_PORTS){
    640         cli_out("no\n");
    641     }
    642     else{
    643         range_start = port;
    644         range_end = port;
    645         is_first_range = TRUE;
    646         SOC_PBMP_ITER(diag_info.ports, port){
    647             if(port == range_start){ 
    648                 continue;
    649             }
    650             if(port != range_end + 1){
    651                 if(!is_first_range){
    652                     cli_out(",");
    653                 }
    654                 if (range_start == range_end){
    655                     cli_out("%03d", range_start);
    656                 }
    657                 else {
    658                     cli_out("%03d - %03d", range_start, range_end);
    659                 }
    660                 range_start = port;
    661                 range_end = port;
    662                 is_first_range = FALSE;
    663             }
    664             else{
    665                 range_end++;
    666             }
    667         }
    668         if(!is_first_range){
    669             cli_out(",");
    670         }
    671         if (range_start == range_end){
    672             cli_out("%03d\n", range_start);
    673         }
    674         else {
    675             cli_out("%03d - %03d\n", range_start, range_end);
    676         }        
    677     }
    678     /*display PM reference clock*/
    679     ret = enum_value_to_string(phymod_ref_clk_t_mapping, diag_info.core_info.ref_clk, &ref_clk);
    680     if(CMD_OK != ret){
    681         ref_clk = unknow_string;
    682     }
    683     /*display PM lane map*/
    684     for (i = 0; i < diag_info.core_info.lane_map.num_of_lanes; i++){
    685         if (0 == i){
    686             cli_out("Lane Map RX: ");
    687         }
    688         cli_out("%d", diag_info.core_info.lane_map.lane_map_rx[i]);
    689         if (i < diag_info.core_info.lane_map.num_of_lanes-1){
    690             cli_out("-");
    691         }
    692         else{
    693             cli_out("\n");
    694         }
    695     }
    696     for (i = 0; i < diag_info.core_info.lane_map.num_of_lanes; i++){
    697         if (0 == i){
    698             cli_out("Lane Map TX: ");
    699         }
    700         cli_out("%d", diag_info.core_info.lane_map.lane_map_tx[i]);
    701         if (i < diag_info.core_info.lane_map.num_of_lanes-1){
    702             cli_out("-");
    703         }
    704         else{
    705             cli_out("\n");
    706         }
    707     }
    708 
    709     return CMD_OK;
    710 }
    711 
    712 
    713 
    714 STATIC cmd_result_t
    715 portmod_info_port_summary_diag(int unit){
    716     int port, rv;
    717     int phy;
    718     int range_start, range_end;
    719     int is_first_range;
    720     int is_virtual = FALSE;
    721     char *interface_types_names[] = SOC_PORT_IF_NAMES_INITIALIZER;
    722     portmod_port_diag_info_t diag_info;
    723     portmod_dispatch_type_t port_type;
    724     char *mac[2] = {"XLMAC", "CLMAC"};
    725     int mac_type = 0;
    726 
    727     sal_memset(&diag_info, 0, sizeof(portmod_port_diag_info_t));
    728     cli_out("port | alias | PM id | port type | phys | mac           \n");
    729     cli_out("--------------------------------------------------\n");
    730     BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port){
    731         rv = portmod_port_diag_info_get(unit, port, &diag_info);
    732         if (BCM_FAILURE(rv)){
    733             continue;
    734         }
    735         rv = portmod_port_pm_type_get(unit, port, &port, &port_type);
    736         if (BCM_FAILURE(rv)) {
    737             continue;
    738         }
    739 
    740         switch(port_type) {
    741 #ifdef PORTMOD_PM4X25_SUPPORT
    742             case portmodDispatchTypePm4x25:
    743                 mac_type = 1;
    744                 break;
    745 #endif
    746 #ifdef PORTMOD_PM4X25TD_SUPPORT
    747             case portmodDispatchTypePm4x25td:
    748                 mac_type = 1;
    749                 break;
    750 #endif
    751 #ifdef PORTMOD_PM12X10_SUPPORT
    752             case portmodDispatchTypePm12x10:
    753                 mac_type = 1;
    754                 break;
    755 #endif
    756 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
    757             case portmodDispatchTypePm12x10_xgs:
    758                 mac_type = 1;
    759                 break;
    760 #endif
    761 
    762 #ifdef PORTMOD_PM4X10_SUPPORT
    763             case portmodDispatchTypePm4x10:
    764                 mac_type = 0;
    765                 break;
    766 
    767 #endif
    768 #ifdef PORTMOD_PM4X10TD_SUPPORT
    769             case portmodDispatchTypePm4x10td:
    770                 mac_type = 0;
    771                 break;
    772 #endif
    773 #ifdef PORTMOD_PM4x10Q_SUPPORT
    774             case portmodDispatchTypePm4x10Q:
    775                 mac_type = 0;
    776                 break;
    777 #endif
    778             default :
    779                 mac_type = 0;
    780                 break;
    781         }
    782 
    783         if(diag_info.pm_id < 0){
    784             /*invalid port*/
    785             continue;
    786         }
    787         if(diag_info.original_port == port){
    788             cli_out(" %03d |       |   %02d  | %-9s | ", port, diag_info.pm_id, interface_types_names[diag_info.interface]);
    789         }
    790         else{
    791             cli_out(" %03d | %03d |   %02d  | %-9s | ", port, diag_info.original_port, diag_info.pm_id, interface_types_names[diag_info.interface]);
    792         }
    793         is_virtual = TRUE;
    794         /*add phys_str*/
    795 
    796         PORTMOD_PBMP_ITER(diag_info.phys, phy){
    797             is_virtual = FALSE;
    798             break;
    799         }
    800         if(is_virtual){
    801             cli_out("virtual\n");
    802             continue;
    803         } 
    804         if(diag_info.interface == SOC_PORT_IF_QSGMII){
    805             /* coverity[uninit_use_in_call] */
    806             cli_out("%03d.%d", phy, diag_info.sub_phy);
    807             continue;
    808         }
    809         
    810         range_start = phy;
    811         range_end = phy;
    812         is_first_range = TRUE;
    813         PORTMOD_PBMP_ITER(diag_info.phys, phy){
    814             if(phy == range_start){ /*first one*/
    815                 continue;
    816             }
    817             if(phy != range_end + 1){
    818                 if(!is_first_range){
    819                     cli_out(",");
    820                 }
    821                 if(range_start == range_end){
    822                     cli_out("%03d", range_start);
    823                 } else {
    824                     cli_out("%03d - %03d", range_start, range_end);
    825                 }
    826                 range_start = phy;
    827                 range_end = phy;
    828                 is_first_range = FALSE;
    829             }
    830             else{
    831                 range_end++;
    832             }
    833         }
    834         if(!is_first_range){
    835             cli_out(",");
    836         }
    837         if(range_start == range_end){
    838             cli_out("%03d", range_start);
    839         } else {
    840             cli_out("%03d - %03d", range_start, range_end);
    841         }
    842         
    843         cli_out("  | %s\n", mac[mac_type]);
    844     }
    845     return CMD_OK;
    846 }
    847 
    848 
    849 
    850 STATIC cmd_result_t
    851 portmod_info_port_detail_diag(int unit, int port){
    852     int rv, i;
    853     int phy, is_most_ext=0, phyn=0;
    854     int range_start, range_end;
    855     int is_first_range;
    856     int is_virtual = FALSE;
    857     char *mode_str = "";
    858     char *unknow_str = "unknow";
    859     int nof_cores; /**< core number */
    860     phymod_core_access_t core_access[1 + MAX_PHYN];
    861     portmod_port_diag_info_t diag_info;
    862     portmod_dispatch_type_t port_type;
    863     char *mac[2] = {"XLMAC", "CLMAC"};
    864     int mac_type = 0;
    865    
    866     rv = portmod_port_diag_info_get(unit, port, &diag_info);
    867     if (BCM_FAILURE(rv)){
    868         return CMD_FAIL;
    869     }
    870     if(diag_info.pm_id < 0){
    871         /*invalid port*/
    872         return CMD_FAIL;
    873     }
    874     cli_out("Port: %03d\n", port);
    875     cli_out("Parent PM: %03d\n", diag_info.pm_id);
    876     cli_out("Phys: ");
    877 
    878     is_virtual = TRUE;
    879     /*add phys_str*/
    880     PORTMOD_PBMP_ITER(diag_info.phys, phy){
    881         is_virtual = FALSE;
    882         break;
    883     }
    884     if(is_virtual){
    885         cli_out("virtual\n");
    886         return CMD_FAIL;;
    887     }
    888     if(diag_info.interface == SOC_PORT_IF_QSGMII){
    889         /* coverity[uninit_use_in_call] */
    890         cli_out("%03d.%d\n", phy, diag_info.sub_phy);
    891         return CMD_FAIL;;
    892     }
    893     
    894     range_start = phy;
    895     range_end = phy;
    896     is_first_range = TRUE;
    897     PORTMOD_PBMP_ITER(diag_info.phys, phy){
    898         if(phy == range_start){ /*first one*/
    899             continue;
    900         }
    901         if(phy != range_end + 1){
    902             if(!is_first_range){
    903                 cli_out(",");
    904             }
    905             if(range_start == range_end){
    906                 cli_out("%03d", range_start);
    907             } else {
    908                 cli_out("%03d - %03d", range_start, range_end);
    909             }
    910             range_start = phy;
    911             range_end = phy;
    912             is_first_range = FALSE;
    913         }
    914         else{
    915             range_end++;
    916         }
    917     }
    918     if(!is_first_range){
    919         cli_out(",");
    920     }
    921     if(range_start == range_end){
    922         cli_out("%03d\n", range_start);
    923     } else {
    924         cli_out("%03d - %03d\n", range_start, range_end);
    925     }
    926 
    927     rv = portmod_port_pm_type_get(unit, port, &port, &port_type);
    928     if (BCM_FAILURE(rv)) {
    929         return CMD_FAIL;
    930     }
    931 
    932     switch(port_type) {
    933 #ifdef PORTMOD_PM4X25_SUPPORT
    934             case portmodDispatchTypePm4x25:
    935                 mac_type = 1;
    936                 break;
    937 #endif
    938 #ifdef PORTMOD_PM4X25TD_SUPPORT
    939             case portmodDispatchTypePm4x25td:
    940                 mac_type = 1;
    941                 break;
    942 #endif
    943 #ifdef PORTMOD_PM12X10_SUPPORT
    944             case portmodDispatchTypePm12x10:
    945                 mac_type = 1;
    946                 break;
    947 #endif
    948 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
    949             case portmodDispatchTypePm12x10_xgs:
    950                 mac_type = 1;
    951                 break;
    952 #endif
    953 
    954 #ifdef PORTMOD_PM4X10_SUPPORT
    955             case portmodDispatchTypePm4x10:
    956                 mac_type = 0;
    957                 break;
    958 
    959 #endif
    960 #ifdef PORTMOD_PM4X10TD_SUPPORT
    961             case portmodDispatchTypePm4x10td:
    962                 mac_type = 0;
    963                 break;
    964 #endif
    965 #ifdef PORTMOD_PM4x10Q_SUPPORT
    966             case portmodDispatchTypePm4x10Q:
    967                 mac_type = 0;
    968                 break;
    969 #endif
    970             default :
    971                 mac_type = 0;
    972                 break;
    973         }
    974 
    975     /* display mac driver type*/
    976     cli_out("Mac: %s\n", mac[mac_type]);
    977 
    978     /* display polarity*/
    979     cli_out("Polarity: TX:%d, RX:%d\n", diag_info.polarity.tx_polarity, diag_info.polarity.rx_polarity);
    980 
    981 
    982     /*display PM phy address*/
    983     while (!is_most_ext) {
    984         rv = portmod_port_core_access_get(unit, port, phyn, MAX_PHYN, core_access, &nof_cores, &is_most_ext);
    985         if (BCM_FAILURE(rv)){
    986             return CMD_FAIL;
    987         }
    988 
    989         for (i=0 ; i<nof_cores ; i++) {
    990             if (phyn == 0) {
    991                 cli_out("Internal PHY Address: %d\n", core_access[i].access.addr);
    992             } else {
    993                 cli_out("External PHY Address: %d\n", core_access[i].access.addr);
    994             }
    995         }
    996 
    997         phyn++;
    998     }
    999 
   1000     if (phyn <=1 ) {
   1001         cli_out("External PHY Address: Not Attached\n");
   1002     }
   1003 
   1004     /* display core port mode */
   1005     rv = enum_value_to_string(portmod_core_port_mode_t_mapping, diag_info.core_mode.cur_mode, &mode_str);
   1006     if(CMD_OK != rv) {
   1007         mode_str = unknow_str;
   1008     }
   1009     cli_out("Core Mode: %s\n", mode_str);
   1010         
   1011     return CMD_OK;
   1012 }
   1013 
   1014 
   1015 
   1016 STATIC cmd_result_t
   1017 portmod_status_port_summary_diag(int unit){
   1018     int port;
   1019     int phy;
   1020     int range_start, range_end;
   1021     int is_first_range;
   1022     int is_virtual = TRUE;
   1023     cmd_result_t ret = CMD_OK;
   1024 
   1025     char *interface_types_names[] = SOC_PORT_IF_NAMES_INITIALIZER;
   1026     char *port_encoding_names[] = SOC_PORT_ENCODING_NAMES_INITIALIZER;
   1027     portmod_port_diag_status_t diag_status;
   1028 
   1029     sal_memset(&diag_status, 0, sizeof(portmod_port_diag_status_t));
   1030     cli_out("Port | Intf type | Speed | Encoding      | LINK | AN       | LT  | LB  | EN | Fault | Phys  |\n");
   1031     cli_out("---------------------------------------------------------------------------------------------\n");
   1032     BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port){
   1033         ret = portmod_port_diag_status_get(unit, port, &diag_status);
   1034         if (BCM_FAILURE(ret)){
   1035             continue;
   1036         }
   1037         cli_out(" %03d | %-9s | %03dG  | %-13s | %-4s | %-8s | %-3s | %-3s | %-2s | %-5s |", \
   1038             port, interface_types_names[diag_status.config.interface], diag_status.config.speed/1000, \
   1039             port_encoding_names[diag_status.encoding], (0 == diag_status.link)?"DOWN":"UP", \
   1040             (0 == diag_status.an_status.enabled)?"OFF":((0 == diag_status.an_status.locked)?"UNLOCKED":"LOCKED"), \
   1041             "OFF", (0 == diag_status.loopback)?"OFF":"ON", (0 == diag_status.enable)?"N":"Y", \
   1042             ((0 == diag_status.lf&&0 == diag_status.rf)?"NONE":((0 != diag_status.lf&&0 == diag_status.rf)?"LF": \
   1043             ((0 == diag_status.lf&&0 != diag_status.rf)?"RF":"LF,RF"))));
   1044         /*display port-phy mapping*/
   1045         PORTMOD_PBMP_ITER(diag_status.phys, phy){
   1046             is_virtual = FALSE;
   1047             break;
   1048         }
   1049         if(is_virtual){
   1050             cli_out("virtual\n");
   1051             return CMD_FAIL;;
   1052         }
   1053         if(diag_status.config.interface == SOC_PORT_IF_QSGMII){
   1054             /* coverity[uninit_use_in_call] */
   1055             cli_out("%03d.%d\n", phy, diag_status.sub_phy);
   1056             return CMD_FAIL;;
   1057         }
   1058         
   1059         range_start = phy;
   1060         range_end = phy;
   1061         is_first_range = TRUE;
   1062         PORTMOD_PBMP_ITER(diag_status.phys, phy){
   1063             if(phy == range_start){ /*first one*/
   1064                 continue;
   1065             }
   1066             if(phy != range_end + 1){
   1067                 if(!is_first_range){
   1068                     cli_out(",");
   1069                 }
   1070                 if(range_start == range_end){
   1071                     cli_out("%03d", range_start);
   1072                 } else {
   1073                     cli_out("%03d-%03d", range_start, range_end);
   1074                 }
   1075                 range_start = phy;
   1076                 range_end = phy;
   1077                 is_first_range = FALSE;
   1078             }
   1079             else{
   1080                 range_end++;
   1081             }
   1082         }
   1083         if(!is_first_range){
   1084             cli_out(",");
   1085         }
   1086         if(range_start == range_end){
   1087             cli_out("%03d\n", range_start);
   1088         } else {
   1089             cli_out("%03d-%03d\n", range_start, range_end);
   1090         }
   1091         
   1092     }
   1093     
   1094     return CMD_OK;
   1095 }
   1096 
   1097 
   1098 
   1099 STATIC cmd_result_t
   1100 portmod_status_port_detail_diag(int unit, int port){
   1101     int rv;
   1102     int phy;
   1103     int range_start, range_end;
   1104     int is_first_range;
   1105     int is_virtual = FALSE;
   1106     portmod_port_diag_info_t diag_info;
   1107   
   1108    
   1109     rv = portmod_port_diag_info_get(unit, port, &diag_info);
   1110     if (BCM_FAILURE(rv)){
   1111         return CMD_FAIL;
   1112     }
   1113     if(diag_info.pm_id < 0){
   1114         /*invalid port*/
   1115         return CMD_FAIL;
   1116     }
   1117     cli_out("Port: %03d\n", port);
   1118     cli_out("Parent PM: %03d\n", diag_info.pm_id);
   1119     cli_out("Phys:");
   1120 
   1121     is_virtual = TRUE;
   1122     /*add phys_str*/
   1123     PORTMOD_PBMP_ITER(diag_info.phys, phy){
   1124         is_virtual = FALSE;
   1125         break;
   1126     }
   1127     if(is_virtual){
   1128         cli_out("virtual\n");
   1129         return CMD_FAIL;;
   1130     }
   1131     if(diag_info.interface == SOC_PORT_IF_QSGMII){
   1132         /* coverity[uninit_use_in_call] */
   1133         cli_out("%03d.%d\n", phy, diag_info.sub_phy);
   1134         return CMD_FAIL;;
   1135     }
   1136     
   1137     range_start = phy;
   1138     range_end = phy;
   1139     is_first_range = TRUE;
   1140     PORTMOD_PBMP_ITER(diag_info.phys, phy){
   1141         if(phy == range_start){ /*first one*/
   1142             continue;
   1143         }
   1144         if(phy != range_end + 1){
   1145             if(!is_first_range){
   1146                 cli_out(",");
   1147             }
   1148             if(range_start == range_end){
   1149                 cli_out("%03d", range_start);
   1150             } else {
   1151                 cli_out("%03d - %03d", range_start, range_end);
   1152             }
   1153             range_start = phy;
   1154             range_end = phy;
   1155             is_first_range = FALSE;
   1156         }
   1157         else{
   1158             range_end++;
   1159         }
   1160     }
   1161     if(!is_first_range){
   1162         cli_out(",");
   1163     }
   1164     if(range_start == range_end){
   1165         cli_out("%03d\n", range_start);
   1166     } else {
   1167         cli_out("%03d - %03d\n", range_start, range_end);
   1168     }
   1169         
   1170     return CMD_OK;
   1171 }
   1172 
   1173 
   1174 STATIC cmd_result_t
   1175 portmod_port_ability_display(portmod_port_ability_t *port_ability){
   1176     int i, string_len;
   1177     char *port_ability_speed_string[] = SOC_PA_SPEED_STRING;
   1178     char *port_ability_pause_string[] = SOC_PA_PAUSE_STRING;
   1179     char *port_ability_intf_string[] = SOC_PA_INTF_STRING;
   1180     char *port_ability_medium_string[] = SOC_PA_MEDIUM_STRING;
   1181     char *port_ability_lb_string[] = SOC_PA_LB_STRING;
   1182     char *port_ability_flags_string[] = _SHR_PA_FLAGS_STRING;
   1183     char *port_ability_eee_string[] = SOC_PA_EEE_STRING;
   1184     char *port_ability_encap_string[] = SOC_PA_ENCAP_STRING;
   1185 
   1186     if(port_ability == NULL) {
   1187         return CMD_FAIL;
   1188     }
   1189     string_len = sizeof(port_ability_speed_string)/sizeof(char *);
   1190     cli_out("Half Duplex Speed: |");
   1191     for (i = 0;i < string_len;i++){
   1192         if (port_ability->speed_half_duplex&(1<<i)){
   1193             cli_out("%s|", port_ability_speed_string[i]);
   1194         }
   1195     }
   1196     cli_out("\n");
   1197 
   1198     string_len = sizeof(port_ability_speed_string)/sizeof(char *);
   1199     cli_out("Full Duplex Speed: |");
   1200     for (i = 0;i < string_len;i++){
   1201         if (port_ability->speed_full_duplex&(1<<i)){
   1202             cli_out("%s|", port_ability_speed_string[i]);
   1203         }        
   1204     }
   1205     cli_out("\n");
   1206     
   1207     cli_out("Pause:             |");
   1208     string_len = sizeof(port_ability_pause_string)/sizeof(char *);
   1209     port_ability->pause = 3;
   1210     for (i = 0;i < string_len;i++){
   1211         if (port_ability->pause&(1<<i)){
   1212             cli_out("%s|", port_ability_pause_string[i]);
   1213         }        
   1214     }
   1215     cli_out("\n");
   1216 
   1217     string_len = sizeof(port_ability_intf_string)/sizeof(char *);
   1218     cli_out("Interface:         |");
   1219     port_ability->interface = 15;
   1220     for (i = 0;i < string_len;i++){
   1221         if (port_ability->interface&(1<<i)){
   1222             cli_out("%s|", port_ability_intf_string[i]);
   1223         }        
   1224     }
   1225     cli_out("\n");
   1226     
   1227     string_len = sizeof(port_ability_medium_string)/sizeof(char *);
   1228     cli_out("Medium:            |");
   1229     port_ability->medium= 15;
   1230     for (i = 0;i < string_len;i++){
   1231         if (port_ability->medium&(1<<i)){
   1232             cli_out("%s|", port_ability_medium_string[i]);
   1233         }        
   1234     }
   1235     cli_out("\n");
   1236 
   1237     string_len = sizeof(port_ability_lb_string)/sizeof(char *);
   1238     cli_out("Loopback:          |");
   1239     port_ability->loopback= 15;
   1240     for (i = 0;i < string_len;i++){
   1241         if (port_ability->loopback&(1<<i)){
   1242             cli_out("%s|", port_ability_lb_string[i]);
   1243         }        
   1244     }
   1245     cli_out("\n");
   1246 
   1247     string_len = sizeof(port_ability_flags_string)/sizeof(char *);
   1248     cli_out("Flags:             |");
   1249     port_ability->flags= 15;
   1250     for (i = 0;i < string_len;i++){
   1251         if (port_ability->flags&(1<<i)){
   1252             cli_out("%s|", port_ability_flags_string[i]);
   1253         }        
   1254     }
   1255     cli_out("\n");
   1256 
   1257     string_len = sizeof(port_ability_eee_string)/sizeof(char *);
   1258     cli_out("EEE:               |");
   1259     port_ability->eee= 15;
   1260     for (i = 0;i < string_len;i++){
   1261         if (port_ability->eee&(1<<i)){
   1262             cli_out("%s|", port_ability_eee_string[i]);
   1263         }        
   1264     }
   1265     cli_out("\n");
   1266 
   1267     string_len = sizeof(port_ability_encap_string)/sizeof(char *);
   1268     cli_out("ENCAP:             |");
   1269     port_ability->encap= 15;
   1270     for (i = 0;i < string_len;i++){
   1271         if (port_ability->encap&(1<<i)){
   1272             cli_out("%s|", port_ability_encap_string[i]);
   1273         }        
   1274     }
   1275     cli_out("\n");
   1276     
   1277     
   1278     return CMD_OK;
   1279 }
   1280 
   1281 
   1282 STATIC cmd_result_t
   1283 portmod_info_diag(int unit, args_t *a){
   1284     char *c;
   1285 	int pm, port;
   1286 	parse_table_t pt;
   1287     cmd_result_t ret = CMD_OK;
   1288 
   1289 	if (NULL == (c = ARG_CUR(a))){
   1290         ret = CMD_USAGE;
   1291     }
   1292     else if(sal_strcasecmp(c, "pm") == 0){
   1293         ret = portmod_info_pm_summary_diag(unit);
   1294     }
   1295     else if(sal_strcasecmp(c, "port") == 0){
   1296         ret = portmod_info_port_summary_diag(unit);
   1297     }
   1298     else{
   1299         parse_table_init(unit, &pt);
   1300         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, 0);
   1301         parse_table_add(&pt, "pm", PQ_INT, (void *)MAX_PMS, &pm, 0);
   1302         if (parse_arg_eq(a, &pt) < 0){
   1303             parse_arg_eq_done(&pt);
   1304             return CMD_USAGE;
   1305         }
   1306         parse_arg_eq_done(&pt);
   1307         if((MAX_PORTS == port) && (MAX_PMS == pm)) {
   1308             return CMD_USAGE;
   1309         }
   1310         if(MAX_PORTS > port){
   1311             /* coverity[overrun-local] */
   1312             if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1313                 cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1314                 return CMD_FAIL;       
   1315             }
   1316             ret = portmod_info_port_detail_diag(unit, port);
   1317         }
   1318         else if(MAX_PMS > pm){
   1319             ret = portmod_info_pm_detail_diag(unit, pm);
   1320         }
   1321         else{
   1322             ret = CMD_USAGE;
   1323         }
   1324     }
   1325     ARG_NEXT(a);
   1326     
   1327     return ret;
   1328 }
   1329 
   1330 
   1331 STATIC void 
   1332 portmod_info_usage(int unit){
   1333     cli_out("command:\n");
   1334     cli_out("  info pm=<pm-id>      -display the the detailed information of the pm-id specific PM.\n");
   1335     cli_out("  info pm              -display the summary information of all PMs.\n");
   1336     cli_out("  info port=<port-id>  -display the the detailed information of the port-id specific port.\n");
   1337     cli_out("  info port            -display the summary information of all ports.\n");
   1338     cli_out("example:\n");
   1339     cli_out("  portmod info pm=0\n");
   1340     cli_out("  portmod info pm\n");
   1341     cli_out("  portmod info port=1\n");
   1342     cli_out("  portmod info port\n");
   1343 }
   1344 
   1345 
   1346 STATIC cmd_result_t
   1347 portmod_status_diag(int unit, args_t *a){
   1348     char *c;
   1349 	int port;
   1350 	parse_table_t pt;
   1351     cmd_result_t ret = CMD_OK;
   1352 
   1353 	if (NULL == (c = ARG_CUR(a))){
   1354         ret = CMD_USAGE;
   1355     } 
   1356     else if(sal_strcasecmp(c, "port") == 0){
   1357         ret = portmod_status_port_summary_diag(unit);
   1358     }
   1359     else{
   1360         parse_table_init(unit, &pt);
   1361         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, 0);
   1362         if (parse_arg_eq(a, &pt) < 0){
   1363             parse_arg_eq_done(&pt);
   1364             return CMD_USAGE;
   1365         }
   1366         parse_arg_eq_done(&pt);
   1367         if(MAX_PORTS == port) {
   1368             return CMD_USAGE;
   1369         }
   1370         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1371             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1372             return CMD_FAIL;       
   1373         }
   1374         ret = portmod_status_port_detail_diag(unit, port);
   1375     }
   1376     ARG_NEXT(a);
   1377     
   1378     return ret;
   1379 }
   1380 
   1381 
   1382 STATIC void 
   1383 portmod_status_usage(int unit){
   1384     cli_out("command:\n");
   1385     cli_out("  status port=<port-id>  -display the the detailed status of the port-id specific port.\n");
   1386     cli_out("  status port            -display the summary status of all ports.\n");
   1387     cli_out("example:\n");
   1388     cli_out("  portmod status port=1\n");
   1389     cli_out("  portmod status port\n");
   1390 }
   1391 
   1392 
   1393 STATIC cmd_result_t
   1394 portmod_fc_diag(int unit, args_t *a){
   1395     int port;
   1396 	parse_table_t pt;
   1397     portmod_port_diag_fc_t diag_fc;
   1398     int ret = CMD_OK;
   1399 
   1400     sal_memset(&diag_fc, 0, sizeof(portmod_port_diag_fc_t));
   1401     if (!ARG_CNT(a)) {  
   1402         ret = CMD_USAGE;
   1403     }
   1404     else{
   1405         parse_table_init(unit, &pt);
   1406         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, 0);
   1407         if (parse_arg_eq(a, &pt) < 0){
   1408             parse_arg_eq_done(&pt);
   1409             return CMD_FAIL;
   1410         }
   1411         parse_arg_eq_done(&pt);
   1412         if(MAX_PORTS == port) {
   1413             return CMD_USAGE;
   1414         }
   1415         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1416             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1417             return CMD_FAIL;       
   1418         }
   1419         ret = portmod_port_diag_fc_get(unit, port, &diag_fc);
   1420         if(ret != SOC_E_NONE){      
   1421             cli_out("ERROR: Getting flow control status failed: %s\n", soc_errmsg(ret));     
   1422             return CMD_FAIL;                                    
   1423         }
   1424         if(MAX_PORTS > port){        
   1425             cli_out("PFC config type: %d\n", diag_fc.pfc_cfg.type);
   1426             cli_out("PFC config opcode: %d\n", diag_fc.pfc_cfg.opcode);
   1427             cli_out("PFC config classes: %d\n", diag_fc.pfc_cfg.classes);
   1428             cli_out("PFC config da_oui: %d\n", diag_fc.pfc_cfg.da_oui);
   1429             cli_out("PFC config da_nonoui: %d\n", diag_fc.pfc_cfg.da_nonoui);
   1430             cli_out("PFC config rxpass: %d\n\n", diag_fc.pfc_cfg.rxpass);
   1431 
   1432             cli_out("PFC control rx_enable: %d\n", diag_fc.pfc_ctrl.rx_enable);
   1433             cli_out("PFC control tx_enable: %d\n", diag_fc.pfc_ctrl.tx_enable);
   1434             cli_out("PFC control stats_en: %d\n", diag_fc.pfc_ctrl.stats_en);
   1435             cli_out("PFC control force_xon: %d\n", diag_fc.pfc_ctrl.force_xon);
   1436             cli_out("PFC control refresh_timer: %d\n", diag_fc.pfc_ctrl.refresh_timer);
   1437             cli_out("PFC control xoff_timer: %d\n\n", diag_fc.pfc_ctrl.xoff_timer);
   1438 
   1439             cli_out("LLFC control rx_enable: %d\n", diag_fc.llfc_ctrl.rx_enable);
   1440             cli_out("LLFC control tx_enable: %d\n", diag_fc.llfc_ctrl.tx_enable);
   1441             cli_out("LLFC control crc_ignore: %d\n", diag_fc.llfc_ctrl.crc_ignore);
   1442             cli_out("LLFC control in_ipg_only: %d\n", diag_fc.llfc_ctrl.in_ipg_only);
   1443         
   1444         }
   1445         else{
   1446             ret = CMD_USAGE;
   1447         }
   1448     }
   1449     return ret;
   1450 }
   1451 
   1452 STATIC void 
   1453 portmod_fc_usage(int unit){
   1454     cli_out("command:\n");
   1455     cli_out("  fc port=<port-id>\n");
   1456     cli_out("example:\n");
   1457     cli_out("  portmod fc port=1\n");
   1458 }
   1459 
   1460 STATIC cmd_result_t
   1461 portmod_autoneg_diag(int unit, args_t *a){
   1462 	int port;
   1463 	parse_table_t    pt;
   1464     portmod_port_diag_autoneg_t diag_autoneg;
   1465     int ret = CMD_OK;
   1466 
   1467     sal_memset(&diag_autoneg, 0, sizeof(portmod_port_diag_autoneg_t));
   1468     if (!ARG_CNT(a)) {  
   1469         ret = CMD_USAGE;
   1470     }
   1471     else{
   1472         parse_table_init(unit, &pt);
   1473         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, 0);
   1474         if (parse_arg_eq(a, &pt) < 0){
   1475             parse_arg_eq_done(&pt);
   1476             return CMD_FAIL;
   1477         }
   1478         parse_arg_eq_done(&pt);
   1479         if(MAX_PORTS == port) {
   1480             return CMD_USAGE;
   1481         }
   1482         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1483             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1484             return CMD_FAIL;       
   1485         }
   1486         ret = portmod_port_diag_autoneg_get(unit, port, &diag_autoneg);
   1487         if(ret != SOC_E_NONE){      
   1488             cli_out("ERROR: Getting auto-negotiation status failed: %s\n", soc_errmsg(ret));     
   1489             return CMD_FAIL;                                    
   1490         }
   1491         if(MAX_PORTS > port){        
   1492             cli_out("**********************************************************\n");
   1493             cli_out("****Auto-negociation local port supported ability*********\n");
   1494             cli_out("**********************************************************\n");
   1495             portmod_port_ability_display(&diag_autoneg.local_ability);
   1496             cli_out("**********************************************************\n");
   1497             cli_out("****Auto-negociation local port advertised ability********\n");
   1498             cli_out("**********************************************************\n");
   1499             portmod_port_ability_display(&diag_autoneg.adv_ability);
   1500             cli_out("**********************************************************\n");
   1501             cli_out("****Auto-negociation received ability from partner********\n");
   1502             cli_out("**********************************************************\n");
   1503             portmod_port_ability_display(&diag_autoneg.remote_ability);
   1504         }
   1505         else{
   1506             ret = CMD_USAGE;
   1507         }
   1508     }
   1509     return ret;
   1510 }
   1511 
   1512 
   1513 STATIC void 
   1514 portmod_autoneg_usage(int unit){
   1515     cli_out("command:\n");
   1516     cli_out("  autoneg port=<port-id>\n");
   1517     cli_out("example:\n");
   1518     cli_out("  portmod autoneg port=1\n");
   1519 }
   1520 
   1521 
   1522 STATIC cmd_result_t
   1523 portmod_core_diag(int unit, args_t *a){
   1524     parse_table_t pt;
   1525     int port;
   1526     phymod_core_diagnostics_t core_diag;
   1527     phymod_core_firmware_info_t core_firmware;
   1528     int ret = SOC_E_NONE;
   1529 
   1530     sal_memset(&core_diag, 0, sizeof(phymod_core_diagnostics_t));
   1531     sal_memset(&core_firmware, 0, sizeof(phymod_core_firmware_info_t));
   1532     if (!ARG_CNT(a)) {  
   1533         ret = CMD_USAGE;
   1534     }
   1535     else{
   1536         parse_table_init(unit, &pt);
   1537         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, NULL);
   1538         if (parse_arg_eq(a, &pt) < 0) {
   1539             cli_out("ERROR: invalid option: %s\n", ARG_CUR(a));
   1540             parse_arg_eq_done(&pt);
   1541             return CMD_FAIL;
   1542         }    
   1543         /* Now free allocated strings */
   1544         parse_arg_eq_done(&pt);
   1545         if(MAX_PORTS == port) {
   1546             return CMD_USAGE;
   1547         }
   1548         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1549             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1550             return CMD_FAIL;       
   1551         }
   1552         ret = portmod_port_diag_core_info_get(unit, port, &core_diag, &core_firmware);
   1553         if(ret != SOC_E_NONE){      
   1554             cli_out("ERROR: Getting core status failed: %s\n", soc_errmsg(ret));     
   1555             return CMD_FAIL;                                    
   1556         }
   1557         cli_out("Port%2d(%s): Core temperature is %d\n", port, BCM_PORT_NAME(unit, port), \
   1558             core_diag.temperature);
   1559         cli_out("Port%2d(%s): Core pll range is %d\n", port, BCM_PORT_NAME(unit, port), \
   1560             core_diag.pll_range);
   1561         cli_out("Port%2d(%s): Core firmware version is %d\n", port, BCM_PORT_NAME(unit, port), \
   1562             core_firmware.fw_version);
   1563         cli_out("Port%2d(%s): Core firmware crc is %d\n", port, BCM_PORT_NAME(unit, port), \
   1564             core_firmware.fw_crc);
   1565     }
   1566     
   1567     return CMD_OK;
   1568 }
   1569 
   1570 
   1571 STATIC void 
   1572 portmod_core_usage(int unit){
   1573     cli_out("command:\n");
   1574     cli_out("  core port=<port-id>\n");
   1575     cli_out("example:\n");
   1576     cli_out("  portmod core port=1\n");
   1577 }
   1578 
   1579 
   1580 STATIC cmd_result_t
   1581 portmod_phy_diag(int unit, args_t *a){
   1582     parse_table_t pt;
   1583     int port, phyn, lane;
   1584     char *osr_str = "";
   1585     char *pmd_str = "";
   1586     char *unknow_str = "unknow";
   1587     char *if_str;
   1588     int port_loc = 0;
   1589     phymod_phy_diagnostics_t phy_diag;
   1590     int ret = CMD_OK;
   1591 
   1592     sal_memset(&phy_diag, 0, sizeof(phymod_phy_diagnostics_t));
   1593     if (!ARG_CNT(a)) {  
   1594         ret = CMD_USAGE;
   1595     }
   1596     else{
   1597         parse_table_init(unit, &pt);
   1598         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, NULL);
   1599         parse_table_add(&pt, "phychain", PQ_INT,(void *)-1, &phyn, NULL);
   1600         parse_table_add(&pt, "lane", PQ_INT,(void *)0, &lane, NULL);
   1601         parse_table_add(&pt, "if", PQ_STRING, 0, &if_str, NULL);
   1602 
   1603         if (parse_arg_eq(a, &pt) < 0) {
   1604             cli_out("ERROR: invalid option: %s\n", ARG_CUR(a));
   1605             parse_arg_eq_done(&pt);
   1606             return CMD_FAIL;
   1607         }   
   1608 
   1609         port_loc = PORTMOD_SIDE_LINE ;
   1610         if (if_str) {
   1611             if (sal_strcasecmp(if_str, "sys") == 0) {
   1612                 port_loc = PORTMOD_SIDE_SYSTEM ;
   1613             } else if (sal_strcasecmp(if_str, "line") == 0) {
   1614                 port_loc = PORTMOD_SIDE_LINE ;
   1615             } else if (if_str[0] != 0) {
   1616                 cli_out("InterFace must be sys or line.\n");
   1617                 return CMD_FAIL;
   1618             }
   1619         }
   1620  
   1621         /* Now free allocated strings */
   1622         parse_arg_eq_done(&pt);
   1623         if(MAX_PORTS == port) {
   1624             return CMD_USAGE;
   1625         }
   1626         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1627             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1628             return CMD_FAIL;       
   1629         }
   1630         
   1631         ret = portmod_port_diag_phy_info_get(unit, port, phyn, lane, port_loc,  &phy_diag);
   1632         if(ret != SOC_E_NONE){      
   1633             cli_out("ERROR: Getting phy status failed: %s\n", soc_errmsg(ret));     
   1634             return CMD_FAIL;                                    
   1635         }     
   1636         ret = enum_value_to_string(phymod_osr_mode_t_mapping, phy_diag.osr_mode, &osr_str);
   1637         if(CMD_OK != ret){
   1638             osr_str = unknow_str;
   1639         }
   1640         ret = enum_value_to_string(phymod_pmd_mode_t_mapping, phy_diag.pmd_mode, &pmd_str);
   1641         if(CMD_OK != ret){
   1642             pmd_str = unknow_str;
   1643         }
   1644         cli_out("PHY signal_detect: %d\n", phy_diag.signal_detect);
   1645         cli_out("PHY vga_bias_reduced: %d\n", phy_diag.vga_bias_reduced);
   1646         cli_out("PHY postc_metric: %d\n", phy_diag.postc_metric);
   1647         cli_out("PHY osr_mode: %d\n", phy_diag.signal_detect);
   1648         cli_out("PHY pmd_mode: %d\n", phy_diag.signal_detect);
   1649         cli_out("PHY rx_lock: %d\n", phy_diag.rx_lock);
   1650         cli_out("PHY rx_ppm: %d\n", phy_diag.rx_ppm);
   1651         cli_out("PHY tx_ppm: %d\n", phy_diag.tx_ppm);
   1652         cli_out("PHY k90_offset %d\n", phy_diag.clk90_offset);
   1653         cli_out("PHY clkp1_offset: %d\n", phy_diag.clkp1_offset);
   1654         cli_out("PHY p1_lvl: %d\n", phy_diag.p1_lvl);
   1655         cli_out("PHY m1_lvl: %d\n", phy_diag.m1_lvl);
   1656         cli_out("PHY dfe1_dcd: %d\n", phy_diag.dfe1_dcd);
   1657         cli_out("PHY dfe2_dcd: %d\n", phy_diag.dfe2_dcd);
   1658         cli_out("PHY slicer_target: %d\n", phy_diag.slicer_target);
   1659 
   1660         cli_out("PHY slicer_offset.offset_pe %d\n", phy_diag.slicer_offset.offset_pe);
   1661         cli_out("PHY slicer_offset.offset_ze %d\n", phy_diag.slicer_offset.offset_ze);
   1662         cli_out("PHY slicer_offset.offset_me %d\n", phy_diag.slicer_offset.offset_me);
   1663         cli_out("PHY slicer_offset.offset_po %d\n", phy_diag.slicer_offset.offset_po);
   1664         cli_out("PHY slicer_offset.offset_zo %d\n", phy_diag.slicer_offset.offset_zo);
   1665         cli_out("PHY slicer_offset.offset_mo %d\n", phy_diag.slicer_offset.offset_mo);
   1666 
   1667         cli_out("PHY eyescan.heye_left: %d\n", phy_diag.eyescan.heye_left);
   1668         cli_out("PHY eyescan.heye_right: %d\n", phy_diag.eyescan.heye_right);
   1669         cli_out("PHY eyescan.veye_upper: %d\n", phy_diag.eyescan.veye_upper);
   1670         cli_out("PHY eyescan.veye_lower: %d\n", phy_diag.eyescan.veye_lower);
   1671 
   1672         cli_out("PHY state_machine_status: %d\n", phy_diag.state_machine_status);
   1673         cli_out("PHY link_time : %d\n", phy_diag.link_time);
   1674         cli_out("PHY pf_main : %d\n", phy_diag.pf_main);
   1675         cli_out("PHY pf_hiz : %d\n", phy_diag.pf_hiz);
   1676         cli_out("PHY pf_bst: %d\n", phy_diag.pf_bst);
   1677         cli_out("PHY pf_low: %d\n", phy_diag.pf_low);
   1678         cli_out("PHY pf2_ctrl: %d\n", phy_diag.pf2_ctrl);
   1679         cli_out("PHY vga: %d\n", phy_diag.vga);
   1680         cli_out("PHY dc_offset: %d\n", phy_diag.dc_offset);
   1681         cli_out("PHY p1_lvl_ctrl: %d\n", phy_diag.p1_lvl_ctrl);
   1682         cli_out("PHY dfe1: %d\n", phy_diag.dfe1);
   1683         cli_out("PHY dfe2: %d\n", phy_diag.dfe2);
   1684         cli_out("PHY dfe3: %d\n", phy_diag.dfe3);
   1685         cli_out("PHY dfe4: %d\n", phy_diag.dfe4);
   1686         cli_out("PHY dfe5: %d\n", phy_diag.dfe5);
   1687         cli_out("PHY dfe6: %d\n", phy_diag.dfe6);
   1688         cli_out("PHY txfir_pre: %d\n", phy_diag.txfir_pre);
   1689         cli_out("PHY txfir_main: %d\n", phy_diag.txfir_main);
   1690         cli_out("PHY txfir_post1: %d\n", phy_diag.txfir_post1);
   1691         cli_out("PHY txfir_post2: %d\n", phy_diag.txfir_post2);
   1692         cli_out("PHY txfir_post3: %d\n", phy_diag.txfir_post3);
   1693         cli_out("PHY tx_amp_ctrl: %d\n", phy_diag.tx_amp_ctrl);
   1694         cli_out("PHY br_pd_en: %d\n", phy_diag.br_pd_en);
   1695 
   1696         }
   1697     
   1698     return ret;
   1699 }
   1700 
   1701 
   1702 STATIC void 
   1703 portmod_phy_usage(int unit){
   1704     cli_out("command:\n");
   1705     cli_out("  phy port=<port-id> [phychain=<phyn> lane=<lane number> if=<sys|line>]\n");
   1706     cli_out("example:\n");
   1707     cli_out("  portmod phy port=1\n");
   1708 }
   1709 
   1710 
   1711 STATIC cmd_result_t
   1712 portmod_prbs_diag(int unit, args_t *a){
   1713     int ret = CMD_OK;
   1714     int port;
   1715     parse_table_t pt;    
   1716     portmod_port_diag_prbs_t diag_prbs;
   1717     int poly = 0, invert = 0, flags = 0, interval=10;
   1718     int enable, mode = 0;
   1719     char *c, *mode_str;
   1720     char *prbs_polys[] = {"X7_X6_1", "X15_X14_1", "X23_X18_1", "X31_X28_1", "X9_X5_1", "X11_X9_1", "X58_X31_1",
   1721                          "0", "1", "2", "3", "4", "5", "6"};    
   1722     enum { PORTMOD_PRBS_SI_MODE, PORTMOD_PRBS_HC_MODE };
   1723 
   1724     sal_memset(&diag_prbs, 0, sizeof(portmod_port_diag_prbs_t));
   1725     if (NULL == (c = ARG_GET(a))) {
   1726         return CMD_USAGE;
   1727     }
   1728     else if (sal_strcasecmp(c, "set") == 0){
   1729         diag_prbs.cmd = "set";
   1730         enable = 1;
   1731     } 
   1732     else if (sal_strcasecmp(c, "get") == 0){
   1733         diag_prbs.cmd = "get";
   1734         enable = 0;
   1735     } 
   1736     else if (sal_strcasecmp(c, "clear") == 0){
   1737         diag_prbs.cmd = "clear";
   1738         enable = 0;
   1739     } 
   1740     else{
   1741         return CMD_USAGE;
   1742     }
   1743 
   1744     parse_table_init(unit, &pt);
   1745     parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, NULL);
   1746     parse_table_add(&pt, "mode", PQ_STRING, 0, &mode_str, NULL);
   1747     if (sal_strcasecmp(diag_prbs.cmd, "set") == 0) {
   1748         parse_table_add(&pt, "polynomial", PQ_DFL|PQ_MULTI,
   1749                         (void *)(0), &poly, &prbs_polys);
   1750         parse_table_add(&pt, "invert", PQ_DFL|PQ_BOOL,
   1751                 (void *)(0), &invert, NULL);
   1752     } else if (sal_strcasecmp(diag_prbs.cmd, "get") == 0) {
   1753         parse_table_add(&pt, "interval", PQ_DFL|PQ_INT,
   1754                 (void *)(0), &interval, NULL);
   1755     }
   1756     if (parse_arg_eq(a, &pt) < 0){
   1757         cli_out("ERROR: invalid option: %s\n", ARG_CUR(a));
   1758         parse_arg_eq_done(&pt);
   1759         return CMD_FAIL;
   1760     }
   1761     if (mode_str) {
   1762         if ((sal_strcasecmp(mode_str, "si") == 0) || (sal_strcasecmp(mode_str, "mac") == 0)) {
   1763             mode = 1;
   1764         } else if ((sal_strcasecmp(mode_str, "hc") == 0) || (sal_strcasecmp(mode_str, "phy") == 0)) {
   1765             mode = 0;
   1766         }
   1767     }
   1768     /* Now free allocated strings */
   1769     parse_arg_eq_done(&pt);    
   1770     if(MAX_PORTS == port) {
   1771         return CMD_USAGE;
   1772     }
   1773     if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1774         cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1775         return CMD_FAIL;       
   1776     }
   1777     diag_prbs.enable = enable;
   1778     diag_prbs.flags = flags;
   1779     diag_prbs.mode = mode;
   1780     diag_prbs.prbs_config.poly = poly%7;
   1781     diag_prbs.prbs_config.invert = invert; 
   1782     diag_prbs.interval = interval;
   1783     ret = portmod_port_diag_prbs_run(unit, port, &diag_prbs);
   1784     if(ret != SOC_E_NONE){      
   1785         cli_out("ERROR: run prbs diagnostic failed: %s\n", soc_errmsg(ret));     
   1786         return CMD_FAIL;                                    
   1787     }     
   1788     if (sal_strcasecmp(diag_prbs.cmd, "get") == 0){ 
   1789         /*display prbs results*/
   1790         cli_out("Port%2d(%s): PRBS is %scurrently locked!\n", port, BCM_PORT_NAME(unit, port), \
   1791             (0 == diag_prbs.prbs_status.prbs_lock)?"not ":"");
   1792         cli_out("Port%2d(%s): PRBS is %sunlocked since last call!\n", port, BCM_PORT_NAME(unit, port), \
   1793             (0 == diag_prbs.prbs_status.prbs_lock_loss)?"not ":"");
   1794         cli_out("Port%2d(%s): PRBS has %d errors count!\n", port, BCM_PORT_NAME(unit, port), \
   1795             diag_prbs.prbs_status.error_count);
   1796     }
   1797     
   1798     return ret;
   1799 }
   1800 
   1801 
   1802 STATIC void 
   1803 portmod_prbs_usage(int unit){
   1804     cli_out("command:\n");
   1805     cli_out("  set port=<port-id> [mode=<phy|mac> polynomial=<value> Loopback=<true|false> Invert=<value>]\n");
   1806     cli_out("  get port=<port-id> [Interval=<value>]\n");
   1807     cli_out("  clear port=<port-id>\n");
   1808     cli_out("example:\n");
   1809     cli_out("  portmod prbs set port=1 mode=phy\n");
   1810 }
   1811 
   1812 
   1813 STATIC cmd_result_t
   1814 portmod_eyescan_diag(int unit, args_t *a){
   1815     int i, nof_phys, port;
   1816     int port_ids[PHYMOD_CONFIG_MAX_CORES_PER_PORT] ;
   1817     int line_rates[PHYMOD_CONFIG_MAX_CORES_PER_PORT];
   1818     phymod_phy_access_t phy_access[PHYMOD_CONFIG_MAX_CORES_PER_PORT];
   1819     portmod_access_get_params_t access_param;
   1820     portmod_port_interface_config_t interface_config;
   1821     char *mode_str = NULL;
   1822     phymod_eyescan_mode_t mode = phymodEyescanModeCount;
   1823     phymod_phy_eyescan_options_t eyescan_options;
   1824     parse_table_t pt;
   1825     int ret = CMD_OK;
   1826     uint32  sys_lane_mask=0xFFFFFFFF;
   1827     char *if_str= NULL;
   1828     int phy_unit=-1;   
   1829  
   1830     /*default values*/
   1831   /* coverity[check_return] */
   1832     portmod_access_get_params_t_init(unit, &access_param);
   1833     access_param.phyn = -1;
   1834     access_param.lane = 0;
   1835 
   1836     /*default values */
   1837     eyescan_options.timeout_in_milliseconds = 1000;
   1838     eyescan_options.horz_max = 31; 
   1839     eyescan_options.horz_min = -31;
   1840     eyescan_options.hstep = 1;
   1841     eyescan_options.vert_max = 31;
   1842     eyescan_options.vert_min = -31;
   1843     eyescan_options.vstep = 1;
   1844     eyescan_options.mode = 0; /*ber mode*/
   1845 
   1846     if (!ARG_CNT(a)) {  
   1847         ret = CMD_USAGE;
   1848     }
   1849     else{
   1850         parse_table_init(unit, &pt);
   1851         parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, NULL);
   1852         parse_table_add(&pt, "ber", PQ_DFL | PQ_INT, (void *)(0),
   1853                         &(eyescan_options.mode), NULL);
   1854         parse_table_add(&pt, "vertical_max", PQ_DFL | PQ_INT, (void *)(0),
   1855                         &(eyescan_options.vert_max), NULL);
   1856         parse_table_add(&pt, "vertical_min", PQ_DFL | PQ_INT, (void *)(0),
   1857                         &(eyescan_options.vert_min), NULL);
   1858         parse_table_add(&pt, "vertical_step", PQ_DFL | PQ_INT, (void *)(0),
   1859                         &(eyescan_options.vstep), NULL);
   1860         parse_table_add(&pt, "horizontal_max", PQ_DFL | PQ_INT, (void *)(0),
   1861                         &(eyescan_options.horz_max), NULL);
   1862         parse_table_add(&pt, "horizontal_min", PQ_DFL | PQ_INT, (void *)(0),
   1863                         &(eyescan_options.horz_min), NULL);
   1864         parse_table_add(&pt, "horizontal_step", PQ_DFL | PQ_INT, (void *)(0),
   1865                         &(eyescan_options.hstep), NULL);
   1866         parse_table_add(&pt, "sample_time", PQ_DFL | PQ_INT, (void *)(0),
   1867                         &(eyescan_options.timeout_in_milliseconds), NULL);
   1868         parse_table_add(&pt, "lane", PQ_DFL | PQ_INT, (void *)(0), &access_param.lane, NULL);
   1869         parse_table_add(&pt, "unit", PQ_DFL | PQ_INT, (void *)(0), &phy_unit, NULL);
   1870         parse_table_add(&pt, "sys_lane_mask", PQ_DFL | PQ_INT, (void *)(0), &sys_lane_mask, NULL);
   1871         parse_table_add(&pt, "mode", PQ_STRING, 0, &mode_str, NULL);
   1872         parse_table_add(&pt, "if", PQ_STRING, 0, &if_str, NULL);
   1873     
   1874         if (parse_arg_eq(a, &pt) < 0) {
   1875             cli_out("ERROR: could not parse parameters\n");
   1876             parse_arg_eq_done(&pt);
   1877             return CMD_USAGE;
   1878         }
   1879     
   1880         if (mode_str) {
   1881             if (0 == sal_strcasecmp(mode_str, "fast")){
   1882                 mode = phymodEyescanModeFast;
   1883             } 
   1884             else if (0 == sal_strcasecmp(mode_str, "lowBER")){
   1885                 mode = phymodEyescanModeLowBER;
   1886             }
   1887             else{
   1888                 cli_out("Mode must be fast or lowBER.\n");
   1889                 return CMD_FAIL;
   1890             }
   1891         }
   1892 
   1893         if(phy_unit == 0){
   1894             access_param.phyn = 0; /* internal */
   1895         } else { /* otherwise most ext. */
   1896             access_param.phyn = -1; /* internal */
   1897         }
   1898 
   1899         access_param.sys_side = PORTMOD_SIDE_LINE; 
   1900         if (if_str) {
   1901             if (sal_strcasecmp(if_str, "sys") == 0) {
   1902                 access_param.sys_side = PORTMOD_SIDE_SYSTEM; 
   1903             } else if (sal_strcasecmp(if_str, "line") == 0) {
   1904                 access_param.sys_side = PORTMOD_SIDE_LINE; 
   1905             } else if (if_str[0] != 0) {
   1906                 cli_out("InterFace must be sys or line.\n");
   1907                 return CMD_FAIL;
   1908             }
   1909         } 
   1910 
   1911         parse_arg_eq_done(&pt);
   1912         if(MAX_PORTS == port) {
   1913             return CMD_USAGE;
   1914         }
   1915         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   1916             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   1917             return CMD_FAIL;       
   1918         }
   1919 
   1920         ret = portmod_port_phy_lane_access_get(unit, port, &access_param, PHYMOD_CONFIG_MAX_CORES_PER_PORT, 
   1921                                                phy_access, &nof_phys, NULL);
   1922         if(ret != SOC_E_NONE){    
   1923             cli_out("ERROR: get phy access failed: %s\n", soc_errmsg(ret));     
   1924             return CMD_FAIL;        
   1925         }
   1926 
   1927         if(nof_phys == 0){
   1928             cli_out("ERROR: Invalid lane# \n");
   1929             return CMD_FAIL;
   1930         }
   1931 
   1932         ret = portmod_port_interface_config_get(unit, port, &interface_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY);
   1933         if(ret != SOC_E_NONE){
   1934             cli_out("ERROR: get interface config failed: %s\n", soc_errmsg(ret));
   1935             return CMD_FAIL;
   1936         }
   1937         for (i = 0;i < PHYMOD_CONFIG_MAX_CORES_PER_PORT;i++){
   1938             line_rates[i] = interface_config.speed;
   1939             port_ids[i]   = port;
   1940         }
   1941 
   1942         /* if the phys/lane are identical, run eyescan on only once. */
   1943         if ( nof_phys == 3 ){
   1944             if( !sal_memcmp( &phy_access[0],&phy_access[1], sizeof(phymod_phy_access_t)) &&
   1945                 !sal_memcmp( &phy_access[0],&phy_access[2], sizeof(phymod_phy_access_t))){
   1946             
   1947                 cli_out("Removing repeated entries.\n");     
   1948                  nof_phys = 1;
   1949             }
   1950         }
   1951 
   1952         /* Check for System Side request. */
   1953         if( sys_lane_mask != 0xFFFFFFFF) {
   1954             cli_out("sys_lane_mask no longer support here, use if=sys  lane=<lane#> \n");
   1955             return CMD_FAIL;        
   1956         }
   1957 
   1958         ret = phymod_diag_eyescan_run(phy_access, unit, port_ids, line_rates, nof_phys, mode, &eyescan_options);
   1959         if(ret != SOC_E_NONE){    
   1960             cli_out("ERROR: run eyescan diagnostic failed: %s\n", soc_errmsg(ret));     
   1961             return CMD_FAIL;        
   1962         }
   1963     }
   1964     
   1965     return ret;
   1966 }
   1967 
   1968 int portmod_eyescan_diag_dispatch(int unit, soc_port_t port,  args_t *a)
   1969 {
   1970 
   1971     int i, nof_phys;
   1972     int line_rates[PHYMOD_CONFIG_MAX_CORES_PER_PORT];
   1973     int port_ids[PHYMOD_CONFIG_MAX_CORES_PER_PORT];
   1974     phymod_phy_access_t phy_access[PHYMOD_CONFIG_MAX_CORES_PER_PORT];
   1975     portmod_access_get_params_t access_param;
   1976     portmod_port_interface_config_t interface_config;
   1977     char *mode_str = NULL;
   1978     parse_table_t pt;
   1979     int ret = CMD_OK;
   1980     uint32  sys_lane_mask=0xFFFFFFFF;
   1981     char *if_str= NULL;
   1982     phymod_eyescan_mode_t mode = 0;
   1983     phymod_phy_eyescan_options_t eyescan_options;
   1984     int phy_unit=-1;
   1985 
   1986     /*default values*/
   1987     /* coverity[check_return] */
   1988     portmod_access_get_params_t_init(unit, &access_param);
   1989     access_param.phyn = phy_unit;
   1990     access_param.lane = 0;
   1991     mode = phymodEyescanModeFast;
   1992 
   1993     /*default values */
   1994     eyescan_options.timeout_in_milliseconds = 1000;
   1995     eyescan_options.horz_max = 31; 
   1996     eyescan_options.horz_min = -31;
   1997     eyescan_options.hstep = 1;
   1998     eyescan_options.vert_max = 31;
   1999     eyescan_options.vert_min = -31;
   2000     eyescan_options.vstep = 1;
   2001     eyescan_options.mode = 0; /*ber mode*/
   2002 
   2003     if (!ARG_CNT(a)) {  
   2004         ret = CMD_USAGE;
   2005     }
   2006     else{
   2007         parse_table_init(unit, &pt);
   2008         parse_table_add(&pt, "ber", PQ_DFL | PQ_INT, (void *)(0),
   2009                         &(eyescan_options.mode), NULL);
   2010         parse_table_add(&pt, "vertical_max", PQ_DFL | PQ_INT, (void *)(0),
   2011                         &(eyescan_options.vert_max), NULL);
   2012         parse_table_add(&pt, "vertical_min", PQ_DFL | PQ_INT, (void *)(0),
   2013                         &(eyescan_options.vert_min), NULL);
   2014         parse_table_add(&pt, "vertical_step", PQ_DFL | PQ_INT, (void *)(0),
   2015                         &(eyescan_options.vstep), NULL);
   2016         parse_table_add(&pt, "horizontal_max", PQ_DFL | PQ_INT, (void *)(0),
   2017                         &(eyescan_options.horz_max), NULL);
   2018         parse_table_add(&pt, "horizontal_min", PQ_DFL | PQ_INT, (void *)(0),
   2019                         &(eyescan_options.horz_min), NULL);
   2020         parse_table_add(&pt, "horizontal_step", PQ_DFL | PQ_INT, (void *)(0),
   2021                         &(eyescan_options.hstep), NULL);
   2022         parse_table_add(&pt, "sample_time", PQ_DFL | PQ_INT, (void *)(0),
   2023                         &(eyescan_options.timeout_in_milliseconds), NULL);
   2024         parse_table_add(&pt, "lane", PQ_DFL | PQ_INT, (void *)(0), &access_param.lane, NULL);
   2025         parse_table_add(&pt, "unit", PQ_DFL | PQ_INT, (void *)(0), &phy_unit, NULL);
   2026         parse_table_add(&pt, "sys_lane_mask", PQ_DFL | PQ_INT, (void *)(0), &sys_lane_mask, NULL);
   2027         parse_table_add(&pt, "mode", PQ_STRING, 0, &mode_str, NULL);
   2028         parse_table_add(&pt, "if", PQ_STRING, 0, &if_str, NULL);
   2029     
   2030         if (parse_arg_eq(a, &pt) < 0) {
   2031             cli_out("ERROR: could not parse parameters\n");
   2032             parse_arg_eq_done(&pt);
   2033             return CMD_USAGE;
   2034         }
   2035     
   2036         if (mode_str) {
   2037             if (0 == sal_strcasecmp(mode_str, "fast")){
   2038                 mode = phymodEyescanModeFast;
   2039             } 
   2040             else if (0 == sal_strcasecmp(mode_str, "lowBER")){
   2041                 mode = phymodEyescanModeLowBER;
   2042             }
   2043             else{
   2044                 mode = phymodEyescanModeCount;
   2045             }
   2046         }
   2047         if(phy_unit == 0){
   2048             access_param.phyn = 0; /* internal */
   2049         } else { /* otherwise most ext. */
   2050             access_param.phyn = -1; /* internal */
   2051         }
   2052 
   2053         access_param.sys_side = PORTMOD_SIDE_LINE; 
   2054         if (if_str) {
   2055             if (sal_strcasecmp(if_str, "sys") == 0) {
   2056                 access_param.sys_side = PORTMOD_SIDE_SYSTEM; 
   2057             } else if (sal_strcasecmp(if_str, "line") == 0) {
   2058                 access_param.sys_side = PORTMOD_SIDE_LINE; 
   2059             } else if (if_str[0] != 0) {
   2060                 cli_out("InterFace must be sys or line.\n");
   2061                 return CMD_FAIL;
   2062             }
   2063         } 
   2064 
   2065         parse_arg_eq_done(&pt);
   2066         if(MAX_PORTS == port) {
   2067             return CMD_USAGE;
   2068         }
   2069         if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   2070             cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   2071             return CMD_FAIL;       
   2072         }
   2073 
   2074         ret = portmod_port_phy_lane_access_get(unit, port, &access_param, PHYMOD_CONFIG_MAX_CORES_PER_PORT, 
   2075                                                phy_access, &nof_phys, NULL);
   2076         if(ret != SOC_E_NONE){    
   2077             cli_out("ERROR: get phy access failed: %s\n", soc_errmsg(ret));     
   2078             return CMD_FAIL;        
   2079         }
   2080 
   2081         if(nof_phys == 0){
   2082             cli_out("ERROR: Invalid lane# \n");
   2083             return CMD_FAIL;
   2084         }
   2085 
   2086         ret = portmod_port_interface_config_get(unit, port, &interface_config, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY);
   2087         if(ret != SOC_E_NONE){    
   2088             cli_out("ERROR: get interface config failed: %s\n", soc_errmsg(ret));     
   2089             return CMD_FAIL;        
   2090         }        
   2091         for (i = 0;i < PHYMOD_CONFIG_MAX_CORES_PER_PORT;i++){
   2092             line_rates[i] = interface_config.speed;
   2093             port_ids[i]   = port;
   2094         }
   2095 
   2096         /* if the phys/lane are identical, run eyescan on only once. */
   2097         if ( nof_phys == 3 ){
   2098             if( !sal_memcmp( &phy_access[0],&phy_access[1], sizeof(phymod_phy_access_t)) &&
   2099                 !sal_memcmp( &phy_access[0],&phy_access[2], sizeof(phymod_phy_access_t))){
   2100             
   2101                 cli_out("Removing repeated entries.\n");     
   2102                  nof_phys = 1;
   2103             }
   2104         }
   2105 
   2106         /* Check for System Side request. */
   2107         if( sys_lane_mask != 0xFFFFFFFF) {
   2108             cli_out("sys_lane_mask no longer support here, use if=sys  lane=<lane#> \n");
   2109             return CMD_FAIL;        
   2110         }
   2111 
   2112         ret = phymod_diag_eyescan_run(phy_access, unit, port_ids, line_rates, nof_phys, mode, &eyescan_options);
   2113         if(ret != SOC_E_NONE){    
   2114             cli_out("ERROR: run eyescan diagnostic failed: %s\n", soc_errmsg(ret));     
   2115             return CMD_FAIL;        
   2116         }
   2117     }
   2118     
   2119     return ret;
   2120 }
   2121 
   2122 STATIC void 
   2123 portmod_eyescan_usage(int unit){
   2124     cli_out("command:\n");
   2125     cli_out("  eyescan port=<port-id> [vertical_max=<value> vertical_min=<value> vertical_step=<value>\n");
   2126     cli_out("          horizontal_max=<value> horizontal_min=<value> horizontal_step=<value>\n");
   2127     cli_out("          sample_time=<value> ber=<value> lane=<value> mode=<fast/lowBER>]\n");
   2128     cli_out("          if=<sys/line> \n");
   2129     cli_out("example:\n");
   2130     cli_out("  portmod eyescan port=1 mode=fast\n");
   2131 }
   2132 
   2133 
   2134 STATIC cmd_result_t
   2135 portmod_regdump_diag(int unit, args_t *a){
   2136     parse_table_t pt;
   2137     int port;
   2138     int ret = CMD_OK;
   2139     char *c;
   2140 
   2141     if (NULL == (c = ARG_CUR(a))) {
   2142         cli_out("ERROR: please input port ID: port=<id>\n");
   2143         return CMD_FAIL;
   2144     }
   2145     parse_table_init(unit, &pt);
   2146     parse_table_add(&pt, "port", PQ_INT,(void *)MAX_PORTS, &port, NULL);
   2147     if (parse_arg_eq(a, &pt) < 0) {
   2148         cli_out("ERROR: invalid option: %s\n", ARG_CUR(a));
   2149         parse_arg_eq_done(&pt);
   2150         return CMD_FAIL;
   2151     }
   2152 
   2153     /* Now free allocated strings */
   2154     parse_arg_eq_done(&pt);
   2155     if(MAX_PORTS == port) {
   2156         return CMD_USAGE;
   2157     }
   2158     if(!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
   2159         cli_out("ERROR: Port %d is not valid for unit %d\n", port, unit);     
   2160         return CMD_FAIL;       
   2161     }
   2162     ret = portmod_port_diag_phy_regdump(unit, port);
   2163     if(SOC_E_NONE != ret){      
   2164         cli_out("ERROR: Getting phy status failed: %s\n", soc_errmsg(ret));     
   2165         return CMD_FAIL;                                    
   2166     }     
   2167 
   2168     return ret;
   2169 }
   2170 
   2171 
   2172 STATIC void 
   2173 portmod_regdump_usage(int unit){
   2174     cli_out("command:\n");
   2175     cli_out("  regdump port=<port-id>\n");
   2176     cli_out("example:\n");
   2177     cli_out("  portmod regdump port=1\n");
   2178 }
   2179 
   2180 #endif
   2181 
   2182 
   2183 STATIC cmd_result_t 
   2184 portmod_diag_pack_usage(int unit, args_t *a);
   2185 
   2186 /*portmod diag pack*/ 
   2187 const portmod_diag_table_t portmod_diag_pack[] = {
   2188     /*CMD_NAME,    CMD_ACTION,                     CMD_SHORT_DESC,              CMD_USAGE,                      CMD_ID*/
   2189     {"usage",     portmod_diag_pack_usage, "display usage",         NULL,                     0},
   2190     {"info",      portmod_info_diag,       "show SW state",         portmod_info_usage,       0},
   2191     {"status",    portmod_status_diag,     "show HW status",        portmod_status_usage,     0},
   2192     {"fc",        portmod_fc_diag,         "show FC info",          portmod_fc_usage,         0},
   2193     {"autoneg",   portmod_autoneg_diag,    "show autoneg info",     portmod_autoneg_usage,    0},
   2194     {"core",      portmod_core_diag,       "show core info",        portmod_core_usage,       0},
   2195     {"phy",       portmod_phy_diag,        "show lane info",        portmod_phy_usage,        0},
   2196     {"prbs",      portmod_prbs_diag,       "run prbs test",         portmod_prbs_usage,       0},
   2197     {"eyescan",   portmod_eyescan_diag,    "run eyescan",           portmod_eyescan_usage,    0},
   2198     {"regdump",   portmod_regdump_diag,    "dump all registers",    portmod_regdump_usage,    0},
   2199     {NULL,        NULL,                    "NULL",                  NULL,                     0}
   2200 };
   2201 
   2202 
   2203 cmd_result_t
   2204 cmd_portmod_diag(int unit, args_t *a){
   2205     char *c;
   2206     cmd_result_t ret = CMD_OK;
   2207     int i, diag_count;
   2208     const portmod_diag_table_t *diag_pack;
   2209 
   2210     if (!sh_check_attached(ARG_CMD(a), unit)) {
   2211         return CMD_FAIL;
   2212     }
   2213     if (NULL == (c = ARG_GET(a))){
   2214         return CMD_USAGE;
   2215     }
   2216 
   2217     diag_pack = portmod_diag_pack;
   2218     diag_count = sizeof(portmod_diag_pack)/sizeof(portmod_diag_table_t);
   2219     for (i = 0;i < diag_count;i++){
   2220         if(diag_pack[i].cmd_name && !sal_strcasecmp(c, diag_pack[i].cmd_name)){
   2221             if (NULL != diag_pack[i].action_func){
   2222                 ret = diag_pack[i].action_func(unit, a);
   2223             }
   2224             if ((CMD_USAGE == ret)&&(NULL != diag_pack[i].usage_func)){
   2225                 diag_pack[i].usage_func(unit);
   2226                 return CMD_FAIL;
   2227             }
   2228             return ret;
   2229         }
   2230     }
   2231 
   2232     return CMD_USAGE;    
   2233 }
   2234 
   2235 
   2236 STATIC cmd_result_t 
   2237 portmod_diag_pack_usage(int unit, args_t *a){
   2238     int i, diag_count;
   2239     const portmod_diag_table_t *diag_pack;
   2240         
   2241 
   2242     cli_out("PortMod Diagnostic Pack Usage:\n");
   2243     cli_out("------------------------------\n");
   2244 
   2245     diag_pack = portmod_diag_pack;
   2246     diag_count = sizeof(portmod_diag_pack)/sizeof(portmod_diag_table_t);
   2247     for (i = 0;i < diag_count;i++){
   2248         if (NULL != diag_pack[i].usage_func){
   2249             diag_pack[i].usage_func(unit);
   2250         }
   2251     }
   2252     
   2253     return CMD_OK;
   2254 }
   2255