xref: /dpdk/app/test-pmd/cmdline_cman.c (revision 40aec5241ebd8fce06ff2c2ecca528a36001062b)
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
parse_uint(uint64_t * value,const char * str)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
parse_cman_obj_str(char * str,uint64_t * obj)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
parse_cman_mode_str(char * str,uint64_t * mode)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
parse_cman_params_str(uint16_t port_id,char * str,struct rte_eth_cman_config * cfg)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 
cmd_show_port_cman_capa_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)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 
cmd_show_port_cman_cfg_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)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 
cmd_set_port_cman_cfg_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)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