1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 Marvell International Ltd. 3 */ 4 5 #include <stdlib.h> 6 7 #include <cmdline_parse.h> 8 #include <cmdline_parse_num.h> 9 #include <cmdline_parse_string.h> 10 11 #include <rte_ethdev.h> 12 13 #include "testpmd.h" 14 15 #define PARSE_DELIMITER " \f\n\r\t\v" 16 17 static int 18 parse_uint(uint64_t *value, const char *str) 19 { 20 char *next = NULL; 21 uint64_t n; 22 23 errno = 0; 24 /* Parse number string */ 25 n = strtol(str, &next, 10); 26 if (errno != 0 || str == next || *next != '\0') 27 return -1; 28 29 *value = n; 30 31 return 0; 32 } 33 34 static int 35 parse_cman_obj_str(char *str, uint64_t *obj) 36 { 37 char *token; 38 39 token = strtok_r(str, PARSE_DELIMITER, &str); 40 if (token == NULL) 41 return 0; 42 43 if (strcasecmp(token, "queue") == 0) 44 *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE; 45 else if (strcasecmp(token, "queue_mempool") == 0) 46 *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL; 47 else 48 return -1; 49 50 return 0; 51 } 52 53 static int 54 parse_cman_mode_str(char *str, uint64_t *mode) 55 { 56 char *token; 57 58 token = strtok_r(str, PARSE_DELIMITER, &str); 59 if (token == NULL) 60 return 0; 61 62 if (strcasecmp(token, "red") == 0) 63 *mode = RTE_CMAN_RED; 64 else 65 return -1; 66 67 return 0; 68 } 69 70 static int 71 parse_cman_params_str(uint16_t port_id, char *str, 72 struct rte_eth_cman_config *cfg) 73 { 74 uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0; 75 struct rte_eth_cman_info info; 76 char *token; 77 int ret; 78 79 token = strtok_r(str, PARSE_DELIMITER, &str); 80 if (!strcasecmp(token, "default")) { 81 ret = rte_eth_cman_config_init(port_id, cfg); 82 if (ret) { 83 fprintf(stderr, "error in default initialization\n"); 84 return ret; 85 } 86 return 0; 87 } 88 89 /* First token: obj name */ 90 token = strtok_r(str, PARSE_DELIMITER, &str); 91 if (token == NULL) { 92 fprintf(stderr, "Object param parse error\n"); 93 goto error; 94 } 95 96 ret = parse_cman_obj_str(token, &obj); 97 if (ret) { 98 fprintf(stderr, "Object value is invalid\n"); 99 goto error; 100 } 101 102 /* Second token: mode name */ 103 token = strtok_r(str, PARSE_DELIMITER, &str); 104 if (token == NULL) { 105 fprintf(stderr, " Mode param is invalid\n"); 106 goto error; 107 } 108 109 token = strtok_r(str, PARSE_DELIMITER, &str); 110 if (token == NULL) { 111 fprintf(stderr, " Mode value is invalid\n"); 112 goto error; 113 } 114 115 ret = parse_cman_mode_str(token, &mode); 116 if (ret) { 117 fprintf(stderr, "mode string parse error\n"); 118 goto error; 119 } 120 121 /* Third token: minimum threshold */ 122 token = strtok_r(str, PARSE_DELIMITER, &str); 123 if (token == NULL) { 124 fprintf(stderr, "Minimum threshold parse error\n"); 125 goto error; 126 } 127 128 ret = parse_uint(&min_th, token); 129 if (ret != 0 || min_th > UINT8_MAX) { 130 fprintf(stderr, "Minimum threshold is invalid\n"); 131 goto error; 132 } 133 134 /* Fourth token: maximum threshold */ 135 token = strtok_r(str, PARSE_DELIMITER, &str); 136 if (token == NULL) { 137 fprintf(stderr, "Maximum threshold parse error\n"); 138 goto error; 139 } 140 141 ret = parse_uint(&max_th, token); 142 if (ret != 0 || max_th > UINT8_MAX) { 143 fprintf(stderr, "Maximum threshold is invalid\n"); 144 goto error; 145 } 146 147 /* Fifth token: probability inversion */ 148 token = strtok_r(str, PARSE_DELIMITER, &str); 149 if (token == NULL) { 150 fprintf(stderr, "Maximum probability inversion parse error\n"); 151 goto error; 152 } 153 154 ret = parse_uint(&maxp_inv, token); 155 if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) { 156 fprintf(stderr, "Maximum probability inversion is invalid\n"); 157 goto error; 158 } 159 160 memset(&info, 0, sizeof(struct rte_eth_cman_info)); 161 ret = rte_eth_cman_info_get(port_id, &info); 162 if (ret) { 163 fprintf(stderr, "Congestion management capa get error\n"); 164 goto error; 165 } 166 167 if (!(info.objs_supported & obj)) { 168 fprintf(stderr, "Object type is not supported by driver\n"); 169 goto error; 170 } 171 172 if (!(info.modes_supported & mode)) { 173 fprintf(stderr, "Mode is not supported by driver\n"); 174 goto error; 175 } 176 177 cfg->obj = obj; 178 cfg->mode = mode; 179 cfg->mode_param.red.min_th = min_th; 180 cfg->mode_param.red.max_th = max_th; 181 cfg->mode_param.red.maxp_inv = maxp_inv; 182 183 return 0; 184 185 error: 186 return -EINVAL; 187 } 188 189 /* *** Show Port Congestion Management Capabilities *** */ 190 struct cmd_show_port_cman_capa_result { 191 cmdline_fixed_string_t show; 192 cmdline_fixed_string_t port; 193 cmdline_fixed_string_t cman; 194 cmdline_fixed_string_t capa; 195 uint16_t port_id; 196 }; 197 198 static cmdline_parse_token_string_t cmd_show_port_cman_capa_show = 199 TOKEN_STRING_INITIALIZER( 200 struct cmd_show_port_cman_capa_result, show, "show"); 201 202 static cmdline_parse_token_string_t cmd_show_port_cman_capa_port = 203 TOKEN_STRING_INITIALIZER( 204 struct cmd_show_port_cman_capa_result, port, "port"); 205 206 static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman = 207 TOKEN_STRING_INITIALIZER( 208 struct cmd_show_port_cman_capa_result, cman, "cman"); 209 210 static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa = 211 TOKEN_STRING_INITIALIZER( 212 struct cmd_show_port_cman_capa_result, capa, "capa"); 213 214 static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id = 215 TOKEN_NUM_INITIALIZER( 216 struct cmd_show_port_cman_capa_result, port_id, RTE_UINT16); 217 218 static void cmd_show_port_cman_capa_parsed(void *parsed_result, 219 __rte_unused struct cmdline *cl, 220 __rte_unused void *data) 221 { 222 struct cmd_show_port_cman_capa_result *res = parsed_result; 223 uint16_t port_id = res->port_id; 224 struct rte_eth_cman_info info; 225 int ret; 226 227 memset(&info, 0, sizeof(struct rte_eth_cman_info)); 228 ret = rte_eth_cman_info_get(port_id, &info); 229 if (ret) 230 return; 231 232 printf("\n**** Port Congestion Management Capabilities ****\n\n"); 233 printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported); 234 printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported); 235 } 236 237 cmdline_parse_inst_t cmd_show_port_cman_capa = { 238 .f = cmd_show_port_cman_capa_parsed, 239 .data = NULL, 240 .help_str = "show port cman capa <port_id>", 241 .tokens = { 242 (void *)&cmd_show_port_cman_capa_show, 243 (void *)&cmd_show_port_cman_capa_port, 244 (void *)&cmd_show_port_cman_capa_cman, 245 (void *)&cmd_show_port_cman_capa_capa, 246 (void *)&cmd_show_port_cman_capa_port_id, 247 NULL, 248 }, 249 }; 250 251 /* *** Show Port Congestion Management configuration *** */ 252 struct cmd_show_port_cman_cfg_result { 253 cmdline_fixed_string_t show; 254 cmdline_fixed_string_t port; 255 cmdline_fixed_string_t cman; 256 cmdline_fixed_string_t cfg; 257 uint16_t port_id; 258 }; 259 260 static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show = 261 TOKEN_STRING_INITIALIZER( 262 struct cmd_show_port_cman_cfg_result, show, "show"); 263 264 static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port = 265 TOKEN_STRING_INITIALIZER( 266 struct cmd_show_port_cman_cfg_result, port, "port"); 267 268 static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman = 269 TOKEN_STRING_INITIALIZER( 270 struct cmd_show_port_cman_cfg_result, cman, "cman"); 271 272 static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg = 273 TOKEN_STRING_INITIALIZER( 274 struct cmd_show_port_cman_cfg_result, cfg, "config"); 275 276 static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id = 277 TOKEN_NUM_INITIALIZER( 278 struct cmd_show_port_cman_cfg_result, port_id, RTE_UINT16); 279 280 static void cmd_show_port_cman_cfg_parsed(void *parsed_result, 281 __rte_unused struct cmdline *cl, 282 __rte_unused void *data) 283 { 284 struct cmd_show_port_cman_cfg_result *res = parsed_result; 285 uint16_t port_id = res->port_id; 286 struct rte_eth_cman_config cfg; 287 int ret; 288 289 memset(&cfg, 0, sizeof(struct rte_eth_cman_config)); 290 ret = rte_eth_cman_config_get(port_id, &cfg); 291 if (ret) 292 return; 293 294 printf("\n**** Port Congestion Management Configuration ****\n\n"); 295 printf("cman object 0x%" PRIx32 "\n", cfg.obj); 296 printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue); 297 printf("cman mode 0x%" PRIx32 "\n", cfg.mode); 298 printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th); 299 printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th); 300 printf("cman RED Prob inversion %" PRIx16 "\n", 301 cfg.mode_param.red.maxp_inv); 302 } 303 304 cmdline_parse_inst_t cmd_show_port_cman_config = { 305 .f = cmd_show_port_cman_cfg_parsed, 306 .data = NULL, 307 .help_str = "show port cman config <port_id>", 308 .tokens = { 309 (void *)&cmd_show_port_cman_cfg_show, 310 (void *)&cmd_show_port_cman_cfg_port, 311 (void *)&cmd_show_port_cman_cfg_cman, 312 (void *)&cmd_show_port_cman_cfg_cfg, 313 (void *)&cmd_show_port_cman_cfg_port_id, 314 NULL, 315 }, 316 }; 317 318 /* *** Set Port Congestion Management configuration *** */ 319 struct cmd_set_port_cman_cfg_result { 320 cmdline_fixed_string_t set; 321 cmdline_fixed_string_t port; 322 cmdline_fixed_string_t cman; 323 cmdline_fixed_string_t cfg; 324 uint16_t port_id; 325 uint16_t qid; 326 cmdline_multi_string_t params; 327 }; 328 329 static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set = 330 TOKEN_STRING_INITIALIZER( 331 struct cmd_set_port_cman_cfg_result, set, "set"); 332 333 static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port = 334 TOKEN_STRING_INITIALIZER( 335 struct cmd_set_port_cman_cfg_result, port, "port"); 336 337 static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman = 338 TOKEN_STRING_INITIALIZER( 339 struct cmd_set_port_cman_cfg_result, cman, "cman"); 340 341 static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg = 342 TOKEN_STRING_INITIALIZER( 343 struct cmd_set_port_cman_cfg_result, cfg, "config"); 344 345 static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id = 346 TOKEN_NUM_INITIALIZER( 347 struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16); 348 349 static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid = 350 TOKEN_NUM_INITIALIZER( 351 struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16); 352 353 static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params = 354 TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result, 355 params, TOKEN_STRING_MULTI); 356 357 static void cmd_set_port_cman_cfg_parsed(void *parsed_result, 358 __rte_unused struct cmdline *cl, 359 __rte_unused void *data) 360 { 361 struct cmd_set_port_cman_cfg_result *res = parsed_result; 362 uint16_t port_id = res->port_id; 363 struct rte_eth_cman_config cfg; 364 int ret; 365 366 ret = parse_cman_params_str(port_id, res->params, &cfg); 367 if (ret) { 368 fprintf(stderr, "params string parse error\n"); 369 return; 370 } 371 372 cfg.obj_param.rx_queue = res->qid; 373 rte_eth_cman_config_set(port_id, &cfg); 374 } 375 376 cmdline_parse_inst_t cmd_set_port_cman_config = { 377 .f = cmd_set_port_cman_cfg_parsed, 378 .data = NULL, 379 .help_str = "set port cman config <port_id> <queue_id> " 380 "default | [obj <queue|queue_mempool> mode red " 381 "<min_thresh> <max_thresh> <prob_inv>]", 382 .tokens = { 383 (void *)&cmd_set_port_cman_cfg_set, 384 (void *)&cmd_set_port_cman_cfg_port, 385 (void *)&cmd_set_port_cman_cfg_cman, 386 (void *)&cmd_set_port_cman_cfg_cfg, 387 (void *)&cmd_set_port_cman_cfg_port_id, 388 (void *)&cmd_set_port_cman_cfg_qid, 389 (void *)&cmd_set_port_cman_cfg_params, 390 NULL, 391 }, 392 }; 393