Branch data Line data Source code
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 : 0 : parse_uint(uint64_t *value, const char *str)
19 : : {
20 : 0 : char *next = NULL;
21 : : uint64_t n;
22 : :
23 : 0 : errno = 0;
24 : : /* Parse number string */
25 : 0 : n = strtol(str, &next, 10);
26 : 0 : if (errno != 0 || str == next || *next != '\0')
27 : : return -1;
28 : :
29 : 0 : *value = n;
30 : :
31 : 0 : return 0;
32 : : }
33 : :
34 : : static int
35 : 0 : parse_cman_obj_str(char *str, uint64_t *obj)
36 : : {
37 : : char *token;
38 : :
39 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
40 : 0 : if (token == NULL)
41 : : return 0;
42 : :
43 : 0 : if (strcasecmp(token, "queue") == 0)
44 : 0 : *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
45 : 0 : else if (strcasecmp(token, "queue_mempool") == 0)
46 : 0 : *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
47 : : else
48 : : return -1;
49 : :
50 : : return 0;
51 : : }
52 : :
53 : : static int
54 : 0 : parse_cman_mode_str(char *str, uint64_t *mode)
55 : : {
56 : : char *token;
57 : :
58 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
59 : 0 : if (token == NULL)
60 : : return 0;
61 : :
62 : 0 : if (strcasecmp(token, "red") == 0)
63 : 0 : *mode = RTE_CMAN_RED;
64 : : else
65 : : return -1;
66 : :
67 : 0 : return 0;
68 : : }
69 : :
70 : : static int
71 : 0 : parse_cman_params_str(uint16_t port_id, char *str,
72 : : struct rte_eth_cman_config *cfg)
73 : : {
74 : 0 : 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 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
80 : 0 : if (!strcasecmp(token, "default")) {
81 : 0 : ret = rte_eth_cman_config_init(port_id, cfg);
82 : 0 : if (ret) {
83 : 0 : fprintf(stderr, "error in default initialization\n");
84 : 0 : return ret;
85 : : }
86 : : return 0;
87 : : }
88 : :
89 : : /* First token: obj name */
90 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
91 : 0 : if (token == NULL) {
92 : 0 : fprintf(stderr, "Object param parse error\n");
93 : 0 : goto error;
94 : : }
95 : :
96 : 0 : ret = parse_cman_obj_str(token, &obj);
97 : 0 : if (ret) {
98 : 0 : fprintf(stderr, "Object value is invalid\n");
99 : 0 : goto error;
100 : : }
101 : :
102 : : /* Second token: mode name */
103 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
104 : 0 : if (token == NULL) {
105 : 0 : fprintf(stderr, " Mode param is invalid\n");
106 : 0 : goto error;
107 : : }
108 : :
109 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
110 : 0 : if (token == NULL) {
111 : 0 : fprintf(stderr, " Mode value is invalid\n");
112 : 0 : goto error;
113 : : }
114 : :
115 : 0 : ret = parse_cman_mode_str(token, &mode);
116 : 0 : if (ret) {
117 : 0 : fprintf(stderr, "mode string parse error\n");
118 : 0 : goto error;
119 : : }
120 : :
121 : : /* Third token: minimum threshold */
122 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
123 : 0 : if (token == NULL) {
124 : 0 : fprintf(stderr, "Minimum threshold parse error\n");
125 : 0 : goto error;
126 : : }
127 : :
128 : 0 : ret = parse_uint(&min_th, token);
129 : 0 : if (ret != 0 || min_th > UINT8_MAX) {
130 : 0 : fprintf(stderr, "Minimum threshold is invalid\n");
131 : 0 : goto error;
132 : : }
133 : :
134 : : /* Fourth token: maximum threshold */
135 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
136 : 0 : if (token == NULL) {
137 : 0 : fprintf(stderr, "Maximum threshold parse error\n");
138 : 0 : goto error;
139 : : }
140 : :
141 : 0 : ret = parse_uint(&max_th, token);
142 : 0 : if (ret != 0 || max_th > UINT8_MAX) {
143 : 0 : fprintf(stderr, "Maximum threshold is invalid\n");
144 : 0 : goto error;
145 : : }
146 : :
147 : : /* Fifth token: probability inversion */
148 : 0 : token = strtok_r(str, PARSE_DELIMITER, &str);
149 : 0 : if (token == NULL) {
150 : 0 : fprintf(stderr, "Maximum probability inversion parse error\n");
151 : 0 : goto error;
152 : : }
153 : :
154 : 0 : ret = parse_uint(&maxp_inv, token);
155 : 0 : if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
156 : 0 : fprintf(stderr, "Maximum probability inversion is invalid\n");
157 : 0 : goto error;
158 : : }
159 : :
160 : : memset(&info, 0, sizeof(struct rte_eth_cman_info));
161 : 0 : ret = rte_eth_cman_info_get(port_id, &info);
162 : 0 : if (ret) {
163 : 0 : fprintf(stderr, "Congestion management capa get error\n");
164 : 0 : goto error;
165 : : }
166 : :
167 : 0 : if (!(info.objs_supported & obj)) {
168 : 0 : fprintf(stderr, "Object type is not supported by driver\n");
169 : 0 : goto error;
170 : : }
171 : :
172 : 0 : if (!(info.modes_supported & mode)) {
173 : 0 : fprintf(stderr, "Mode is not supported by driver\n");
174 : 0 : goto error;
175 : : }
176 : :
177 : 0 : cfg->obj = obj;
178 : 0 : cfg->mode = mode;
179 : 0 : cfg->mode_param.red.min_th = min_th;
180 : 0 : cfg->mode_param.red.max_th = max_th;
181 : 0 : cfg->mode_param.red.maxp_inv = maxp_inv;
182 : :
183 : 0 : 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 : 0 : 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 : 0 : 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 : 0 : ret = rte_eth_cman_info_get(port_id, &info);
229 : 0 : if (ret)
230 : 0 : return;
231 : :
232 : : printf("\n**** Port Congestion Management Capabilities ****\n\n");
233 : 0 : printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
234 : 0 : 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 : 0 : 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 : 0 : 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 : 0 : ret = rte_eth_cman_config_get(port_id, &cfg);
291 : 0 : if (ret)
292 : 0 : return;
293 : :
294 : : printf("\n**** Port Congestion Management Configuration ****\n\n");
295 : 0 : printf("cman object 0x%" PRIx32 "\n", cfg.obj);
296 : 0 : printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
297 : 0 : printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
298 : 0 : printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th);
299 : 0 : printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th);
300 : 0 : printf("cman RED Prob inversion %" PRIx16 "\n",
301 : 0 : 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 : 0 : 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 : 0 : uint16_t port_id = res->port_id;
363 : : struct rte_eth_cman_config cfg;
364 : : int ret;
365 : :
366 : 0 : ret = parse_cman_params_str(port_id, res->params, &cfg);
367 : 0 : if (ret) {
368 : 0 : fprintf(stderr, "params string parse error\n");
369 : 0 : return;
370 : : }
371 : :
372 : 0 : cfg.obj_param.rx_queue = res->qid;
373 : 0 : 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 : : };
|