openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

phymod_sdk_diag.c (10820B)


      1 /*
      2  *  
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  */
      7 
      8 #include <appl/diag/parse.h>
      9 #include <appl/diag/system.h>
     10 #include <shared/bsl.h>
     11 #ifdef PHYMOD_DIAG
     12 
     13 #include <phymod/phymod_diag.h>
     14 #include <phymod/phymod.h>
     15 #include <phymod/phymod_diagnostics.h>
     16 #include <appl/diag/phymod/phymod_sdk_diag.h>
     17 
     18 #define MAX_PHYS_ACCESS_STRUCTURES (144)
     19 #define MAX_PHYS_STRUCTS_PER_PORT (6)
     20 
     21 STATIC int
     22 enum_parse(enum_mapping_t *mapping, char *str, uint32_t *val)
     23 {
     24     char *key;
     25     int i = 0;
     26 
     27     key = mapping[0].key;
     28     while (key != NULL) {
     29         if (sal_strcasecmp(key, str) == 0) {
     30             *val = mapping[i].enum_value;
     31             return CMD_OK;
     32         }
     33         i++;
     34         key = mapping[i].key;
     35     }
     36     return CMD_FAIL;
     37 }
     38 
     39 
     40 /******************************************************************************
     41  * DSC
     42  */
     43 #define DSC_USAGE   "dsc <port>\n"
     44 
     45 STATIC cmd_result_t
     46 phymod_sdk_diag_dsc_wrapper(phymod_phy_access_t *phys, int array_size,  args_t *args)
     47 {
     48     int res;
     49     
     50     res = phymod_diag_dsc(phys, array_size);
     51     return (res == PHYMOD_E_NONE)? CMD_OK : CMD_FAIL;
     52 }
     53 
     54 /******************************************************************************
     55  * REG read/write
     56  */
     57 #define REG_READ_USAGE  "read <port> <addr>\n"
     58 #define REG_WRITE_USAGE "write <port> <addr> <val>\n"
     59 
     60 STATIC cmd_result_t
     61 phymod_sdk_diag_reg_read_wrapper(phymod_phy_access_t *phys, int array_size,  args_t *args)
     62 {
     63     char *str;
     64     uint32_t reg_addr;
     65     int res = PHYMOD_E_NONE;
     66 
     67     if ((str = ARG_GET(args)) == NULL) {
     68         return CMD_USAGE;
     69     }
     70     if(isint(str)){
     71         reg_addr = parse_integer(str);
     72         res = phymod_diag_reg_read(phys, array_size, reg_addr);
     73     } else{
     74         return CMD_USAGE;
     75     }
     76     
     77     return (res == PHYMOD_E_NONE)? CMD_OK : CMD_FAIL;
     78 }
     79 
     80 STATIC cmd_result_t
     81 phymod_sdk_diag_reg_write_wrapper(phymod_phy_access_t *phys, int array_size,  args_t *args)
     82 {
     83     char *str;
     84     uint32_t reg_addr;
     85     uint32_t val;
     86     int res;
     87 
     88     if ((str = ARG_GET(args)) == NULL) {
     89         return CMD_USAGE;
     90     }
     91     if(isint(str)){
     92         reg_addr = parse_integer(str);
     93             if ((str = ARG_GET(args)) == NULL) {
     94                 return CMD_USAGE;
     95             }
     96         val = parse_integer(str);        
     97         res = phymod_diag_reg_write(phys, array_size, reg_addr, val);
     98     }else{
     99         return CMD_USAGE;
    100     }
    101 
    102     return (res == PHYMOD_E_NONE)? CMD_OK : CMD_FAIL;
    103 }
    104 
    105 
    106 /******************************************************************************
    107  * PRBS
    108  */
    109 #define PRBS_USAGE \
    110     "prbs diagnostics usage:\n" \
    111     "prbs <ports> clear [rx] [tx]\n" \
    112     "prbs <ports> get <time_to_wait>\n" \
    113     "prbs <ports> set <Polynomial=<phymodPrbsPolyX>> [loopback] [enable] [invert] [rx] [tx]\n" \
    114     "\ndefault values: loopback=false, enable=true, invert=false rx=flase tx=false\n" \
    115     "note: when nor rx neither tx flags are set the PRBS set/clear operation will be performed on both\n"
    116 
    117 STATIC int
    118 phymod_sdk_diag_prbs_get_args_parse(args_t *args, phymod_diag_prbs_get_args_t *prbs_get_args)
    119 {
    120     char *str;
    121 
    122     if ((str = ARG_GET(args)) == NULL) {
    123         return CMD_USAGE;
    124     }
    125     prbs_get_args->time = parse_integer(str);
    126     return CMD_OK;
    127 }
    128 
    129 STATIC int
    130 phymod_sdk_diag_prbs_set_args_parse(args_t *args, phymod_diag_prbs_set_args_t *prbs_set_args)
    131 {
    132     parse_table_t pt;
    133     char *poly;
    134     int rx_flag;
    135     int tx_flag;
    136 
    137     parse_table_init(0, &pt); /* Unit meaning leess in parse table */
    138     parse_table_add(&pt, "polynomial", PQ_STRING, (void *)0, &poly, NULL);
    139     parse_table_add(&pt, "loopback",  PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &prbs_set_args->loopback, NULL);
    140     parse_table_add(&pt, "enable", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)1, &prbs_set_args->enable, NULL);
    141     parse_table_add(&pt, "invert", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &prbs_set_args->prbs_options.invert, NULL);
    142     parse_table_add(&pt, "rx", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &rx_flag, NULL);
    143     parse_table_add(&pt, "tx", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &tx_flag, NULL);
    144     if (parse_arg_eq(args, &pt) < 0) {
    145         cli_out("ERROR: invalid option: %s\n", ARG_CUR(args));
    146         parse_arg_eq_done(&pt);
    147         return CMD_USAGE;
    148     }
    149     if (poly == NULL || sal_strlen(poly) == 0) {
    150         parse_arg_eq_done(&pt);
    151         cli_out("missing parameter: polynomial\n");       
    152         return CMD_USAGE;
    153     }
    154     if (enum_parse(phymod_prbs_poly_t_mapping, poly, &prbs_set_args->prbs_options.poly) != CMD_OK) {
    155         cli_out("invalid polynomial %s\n", poly);
    156         parse_arg_eq_done(&pt);
    157         return CMD_USAGE;
    158     }
    159     /* Now free allocated strings */
    160     parse_arg_eq_done(&pt);
    161 
    162     if (rx_flag) {
    163         PHYMOD_PRBS_DIRECTION_RX_SET(prbs_set_args->flags);
    164     }
    165     if (tx_flag) {
    166         PHYMOD_PRBS_DIRECTION_TX_SET(prbs_set_args->flags);
    167     }
    168     return CMD_OK;   
    169 }
    170 
    171 STATIC int
    172 phymod_sdk_diag_prbs_clear_args_parse(args_t *args, phymod_diag_prbs_clear_args_t *prbs_clear_args)
    173 {
    174     parse_table_t pt;
    175     int rx_flag;
    176     int tx_flag;
    177 
    178     parse_table_init(0, &pt); /* Unit meaning leess in parse table */
    179     parse_table_add(&pt, "rx", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &rx_flag, NULL);
    180     parse_table_add(&pt, "tx", PQ_VAL | PQ_BOOL | PQ_NO_EQ_OPT, (void *)0, &tx_flag, NULL);
    181     if (parse_arg_eq(args, &pt) < 0) {
    182         cli_out("ERROR: invalid option: %s\n", ARG_CUR(args));
    183         return CMD_USAGE;
    184     }
    185     if (rx_flag) {
    186         PHYMOD_PRBS_DIRECTION_RX_SET(prbs_clear_args->flags);
    187     }
    188     if (tx_flag) {
    189         PHYMOD_PRBS_DIRECTION_TX_SET(prbs_clear_args->flags);
    190     }
    191     return CMD_OK;   
    192 }
    193 
    194 STATIC int
    195 phymod_sdk_diag_prbs_args_parse(args_t *args,  phymod_diag_prbs_args_t *prbs_args)
    196 {
    197     enum_mapping_t phymod_prbs_cmd[] = {
    198         {"clear", PhymodDiagPrbsClear},
    199         {"set", PhymodDiagPrbsSet},
    200         {"get",PhymodDiagPrbsGet},
    201         {NULL, 0}
    202     };
    203     int rv = CMD_OK;
    204     char *operation;
    205 
    206     operation = ARG_GET(args);
    207     if (operation == NULL) {
    208         return CMD_USAGE;
    209     }
    210     if (enum_parse(phymod_prbs_cmd, operation, &prbs_args->prbs_cmd) != CMD_OK) {
    211         cli_out("Invalid operation type %s\n", operation);
    212         return CMD_USAGE;
    213     }
    214     switch(prbs_args->prbs_cmd) {
    215     case PhymodDiagPrbsClear:
    216         /* No additional parameters */
    217         rv= phymod_sdk_diag_prbs_clear_args_parse(args, &prbs_args->args.clear_params);
    218         break;
    219     case PhymodDiagPrbsGet:
    220         rv = phymod_sdk_diag_prbs_get_args_parse(args, &prbs_args->args.get_params);
    221         break;
    222     case PhymodDiagPrbsSet:
    223         rv = phymod_sdk_diag_prbs_set_args_parse(args, &prbs_args->args.set_params);
    224         break;
    225     default:
    226         /* Not supposed to get here */
    227         return CMD_FAIL;
    228     }
    229     return rv;
    230    
    231 }
    232 
    233 STATIC cmd_result_t
    234 phymod_sdk_diag_prbs_wrapper(phymod_phy_access_t *phys, int array_size,  args_t *args)
    235 {
    236     phymod_diag_prbs_args_t prbs_diag_args;
    237     int rv;
    238     int res;
    239 
    240     rv = phymod_sdk_diag_prbs_args_parse(args, &prbs_diag_args);
    241     if (rv !=  CMD_OK) {
    242         return rv;
    243     }
    244     res = phymod_diag_prbs(phys, array_size, &prbs_diag_args);
    245     return (res == PHYMOD_E_NONE)? CMD_OK : CMD_FAIL;
    246 }
    247 
    248 /******************************************************************************
    249  * General
    250  */
    251 typedef cmd_result_t (*cmd_func_f)(phymod_phy_access_t *phys, int array_size,  args_t *args);
    252 
    253 
    254 typedef struct phymod_cmd_s {
    255     char* c_cmd;
    256     cmd_func_f  c_func;
    257     char* c_usage;
    258 } phymod_cmd_t;
    259 
    260 static phymod_cmd_t commands[] ={
    261     {"prbs",  phymod_sdk_diag_prbs_wrapper, PRBS_USAGE},
    262     {"read", phymod_sdk_diag_reg_read_wrapper, REG_READ_USAGE},
    263     {"write", phymod_sdk_diag_reg_write_wrapper, REG_WRITE_USAGE},
    264     {"dsc", phymod_sdk_diag_dsc_wrapper, DSC_USAGE},
    265 };
    266 
    267 STATIC void
    268 phymod_sdk_commands_print(void)
    269 {
    270     int i = 0;
    271 
    272     cli_out("command types:\n");
    273     for (i = 0; i < COUNTOF(commands); i++) {
    274         cli_out("  %s\n", commands[i].c_cmd);
    275     }
    276 }
    277 
    278 
    279 STATIC int 
    280 phymod_sdk_diag_parse_ports_str(int unit, char *port_str, bcm_pbmp_t *pbmp)
    281 {
    282     BCM_PBMP_CLEAR(*pbmp);
    283     if (parse_bcm_pbmp(unit, port_str, pbmp) < 0) {
    284         cli_out("ERROR: unrecognized port bitmap: %s\n", port_str);
    285         return CMD_FAIL;
    286     }
    287     return CMD_OK;
    288 }
    289 
    290 
    291 cmd_result_t
    292 phymod_sdk_diag(int unit, phymod_diag_map_func_f port_map ,args_t *args)
    293 {
    294     int i = 0;
    295     int rv;
    296     int port;
    297     int command_found = FALSE;
    298     bcm_pbmp_t ports_bmp;
    299     int access_array_size = 0;
    300     phymod_phy_access_t* access_array = NULL;
    301     int access_max_size = sizeof(phymod_phy_access_t) * MAX_PHYS_ACCESS_STRUCTURES;
    302     int nof_port_phy_accesses = 0;
    303     char *command;
    304     char *ports_str;
    305 
    306     /* Register the print function */
    307     phymod_diag_print_func = cli_out;
    308 
    309     command = ARG_GET(args);
    310     if (command == NULL) {
    311         phymod_sdk_commands_print();
    312         return CMD_NFND;
    313     }
    314 
    315     ports_str = ARG_GET(args);
    316     if (ports_str == NULL) {
    317         cli_out("missing port parameter\n");
    318         return CMD_NFND;
    319     }
    320 
    321     if(phymod_sdk_diag_parse_ports_str(unit, ports_str, &ports_bmp) != CMD_OK){
    322         cli_out("error parsing port parameter\n");
    323         return CMD_NFND;
    324     }
    325     access_array = sal_alloc(access_max_size, "access array");
    326     if (NULL == access_array) {
    327         return CMD_FAIL;
    328     }
    329 
    330     sal_memset(access_array, 0, access_max_size);
    331     BCM_PBMP_ITER(ports_bmp, port){
    332         nof_port_phy_accesses = 0;
    333         rv = port_map(unit, port, MAX_PHYS_STRUCTS_PER_PORT, &access_array[access_array_size], &nof_port_phy_accesses);
    334         if (rv != CMD_OK) {
    335             cli_out("error in translate port %d to phy access\n", port);
    336             if (access_array != NULL) {
    337                 sal_free(access_array);
    338             }
    339             return CMD_FAIL;
    340         }
    341         access_array_size += nof_port_phy_accesses;
    342     }
    343 
    344     for (i = 0; i < COUNTOF(commands); i++) {
    345         if (sal_strcasecmp(commands[i].c_cmd, command) == 0) {
    346             /* Command found */
    347             command_found = TRUE;
    348             break;
    349         }
    350     }
    351     if(command_found){
    352         rv = commands[i].c_func(access_array, access_array_size, args);
    353         if (rv == CMD_USAGE) {
    354             cli_out("%s", commands[i].c_usage);
    355             if (access_array != NULL) {
    356                 sal_free(access_array);
    357             }
    358             return CMD_FAIL;
    359         }
    360     }
    361     else{
    362         phymod_sdk_commands_print();
    363         if (access_array != NULL) {
    364             sal_free(access_array);
    365         }
    366         return CMD_NFND;
    367     }
    368     if (access_array != NULL) {
    369         sal_free(access_array);
    370     }
    371     return CMD_OK;
    372 }
    373 
    374 #endif /* PHYMOD_DIAG */
    375 
    376 int _phymod_sdk_diag_not_empty;