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;