All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] app/testpmd: support congestion management CLIs
@ 2022-09-19 12:41 skori
  2022-09-19 12:41 ` [PATCH 2/3] common/cnxk: add congestion management ROC APIs skori
  2022-09-19 12:41 ` [PATCH 3/3] net/cnxk: support congestion management ops skori
  0 siblings, 2 replies; 17+ messages in thread
From: skori @ 2022-09-19 12:41 UTC (permalink / raw)
  To: Aman Singh, Yuying Zhang; +Cc: dev, Sunil Kumar Kori

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management CLIs.

Depends-on: patch-24710 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 app/test-pmd/cmdline.c                      |  15 +
 app/test-pmd/cmdline_cman.c                 | 390 ++++++++++++++++++++
 app/test-pmd/cmdline_cman.h                 |  12 +
 app/test-pmd/meson.build                    |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
 5 files changed, 444 insertions(+)
 create mode 100644 app/test-pmd/cmdline_cman.c
 create mode 100644 app/test-pmd/cmdline_cman.h

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 51321de9ed..ce278eadb0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -60,6 +60,7 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include "testpmd.h"
+#include "cmdline_cman.h"
 #include "cmdline_mtr.h"
 #include "cmdline_tm.h"
 #include "bpf_cmd.h"
@@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) fec_mode auto|off|rs|baser\n"
 			"    set fec mode for a specific port\n\n"
 
+			"show port cman capa (port_id)\n"
+			"    Show congestion management capabilities\n\n"
+
+			"show port cman config (port_id)\n"
+			"    Show congestion management configuration\n\n"
+
+			"set port cman config (port_id) (queue_id) default | "
+			"[obj (queue|queue_mempool) mode red (min_thresh) "
+			"(max_thresh) (prob_inv)]\n"
+			"    Set congestion management configuration\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_capability,
 	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
 	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
+	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
 	NULL,
 };
 
diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
new file mode 100644
index 0000000000..344759189d
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.c
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+
+#include <rte_ethdev.h>
+
+#include "testpmd.h"
+
+#define PARSE_DELIMITER				" \f\n\r\t\v"
+
+static int
+parse_uint(uint64_t *value, const char *str)
+{
+	char *next = NULL;
+	uint64_t n;
+
+	errno = 0;
+	/* Parse number string */
+	n = strtol(str, &next, 10);
+	if (errno != 0 || str == next || *next != '\0')
+		return -1;
+
+	*value = n;
+
+	return 0;
+}
+
+static int
+parse_cman_obj_str(char *str, uint64_t *obj)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "queue") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	else if (strcasecmp(token, "queue_mempool") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_mode_str(char *str, uint64_t *mode)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "red") == 0)
+		*mode = RTE_CMAN_RED;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_params_str(uint16_t port_id, char *str,
+		      struct rte_eth_cman_config *cfg)
+{
+	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
+	struct rte_eth_cman_info info;
+	char *token;
+	int ret;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (!strcasecmp(token, "default")) {
+		ret = rte_eth_cman_config_init(port_id, cfg);
+		if (ret) {
+			fprintf(stderr, "error in default initialization\n");
+			return ret;
+		}
+		return 0;
+	}
+
+	/* First token: obj name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Object param parse error\n");
+		goto error;
+	}
+
+	ret = parse_cman_obj_str(token, &obj);
+	if (ret) {
+		fprintf(stderr, "Object value is invalid\n");
+		goto error;
+	}
+
+	/* Second token: mode name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode param is invalid\n");
+		goto error;
+	}
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode value is invalid\n");
+		goto error;
+	}
+
+	ret = parse_cman_mode_str(token, &mode);
+	if (ret) {
+		fprintf(stderr, "mode string parse error\n");
+		goto error;
+	}
+
+	/* Third token: minimum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Minimum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&min_th, token);
+	if (ret != 0 || min_th > UINT8_MAX) {
+		fprintf(stderr, "Minimum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fourth token: maximum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&max_th, token);
+	if (ret != 0 || max_th > UINT8_MAX) {
+		fprintf(stderr, "Maximum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fifth token: probability inversion */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum probability inversion parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&maxp_inv, token);
+	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
+		fprintf(stderr, "Maximum probability inversion is invalid\n");
+		goto error;
+	}
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret) {
+		fprintf(stderr, "Congestion management capa get error\n");
+		goto error;
+	}
+
+	if (!(info.objs_supported & obj)) {
+		fprintf(stderr, "Object type is not supported by driver\n");
+		goto error;
+	}
+
+	if (!(info.modes_supported & mode)) {
+		fprintf(stderr, "Mode is not supported by driver\n");
+		goto error;
+	}
+
+	cfg->obj = obj;
+	cfg->mode = mode;
+	cfg->mode_param.red.min_th = min_th;
+	cfg->mode_param.red.max_th = max_th;
+	cfg->mode_param.red.maxp_inv = maxp_inv;
+
+	return 0;
+
+error:
+	return -EINVAL;
+}
+
+/* *** Show Port Congestion Management Capabilities *** */
+struct cmd_show_port_cman_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t capa;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, capa, "capa");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_capa_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_capa_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_info info;
+	int ret;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Capabilities   ****\n\n");
+	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
+	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_capa = {
+	.f = cmd_show_port_cman_capa_parsed,
+	.data = NULL,
+	.help_str = "show port cman capa <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_capa_show,
+		(void *)&cmd_show_port_cman_capa_port,
+		(void *)&cmd_show_port_cman_capa_cman,
+		(void *)&cmd_show_port_cman_capa_capa,
+		(void *)&cmd_show_port_cman_capa_port_id,
+		NULL,
+	},
+};
+
+/* *** Show Port Congestion Management configuration *** */
+struct cmd_show_port_cman_cfg_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
+	ret = rte_eth_cman_config_get(port_id, &cfg);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Configuration   ****\n\n");
+	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
+	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
+	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
+	printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th);
+	printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th);
+	printf("cman RED Prob inversion %" PRIx16 "\n",
+		cfg.mode_param.red.maxp_inv);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_config = {
+	.f = cmd_show_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "show port cman config <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_cfg_show,
+		(void *)&cmd_show_port_cman_cfg_port,
+		(void *)&cmd_show_port_cman_cfg_cman,
+		(void *)&cmd_show_port_cman_cfg_cfg,
+		(void *)&cmd_show_port_cman_cfg_port_id,
+		NULL,
+	},
+};
+
+/* *** Set Port Congestion Management configuration *** */
+struct cmd_set_port_cman_cfg_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+	uint16_t qid;
+	cmdline_multi_string_t params;
+};
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, set, "set");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
+		params, TOKEN_STRING_MULTI);
+
+static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_set_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	ret = parse_cman_params_str(port_id, res->params, &cfg);
+	if (ret) {
+		fprintf(stderr, "params string parse error\n");
+		return;
+	}
+
+	cfg.obj_param.rx_queue = res->qid;
+	rte_eth_cman_config_set(port_id, &cfg);
+}
+
+cmdline_parse_inst_t cmd_set_port_cman_config = {
+	.f = cmd_set_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "set port cman config <port_id> <queue_id> "
+		    "default | [obj <queue|queue_mempool> mode red "
+		    "<min_thresh> <max_thresh> <prob_inv>]",
+	.tokens = {
+		(void *)&cmd_set_port_cman_cfg_set,
+		(void *)&cmd_set_port_cman_cfg_port,
+		(void *)&cmd_set_port_cman_cfg_cman,
+		(void *)&cmd_set_port_cman_cfg_cfg,
+		(void *)&cmd_set_port_cman_cfg_port_id,
+		(void *)&cmd_set_port_cman_cfg_qid,
+		(void *)&cmd_set_port_cman_cfg_params,
+		NULL,
+	},
+};
diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
new file mode 100644
index 0000000000..bd6c99ce35
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#ifndef _CMDLINE_CMAN_H_
+#define _CMDLINE_CMAN_H_
+
+extern cmdline_parse_inst_t cmd_show_port_cman_capa;
+extern cmdline_parse_inst_t cmd_show_port_cman_config;
+extern cmdline_parse_inst_t cmd_set_port_cman_config;
+
+#endif /* _CMDLINE_CMAN_H_ */
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 74399178dd..c03d9dfebb 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
 sources = files(
         '5tswap.c',
         'cmdline.c',
+        'cmdline_cman.c',
         'cmdline_flow.c',
         'cmdline_mtr.c',
         'cmdline_tm.c',
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index d3075bf87d..b9c7b468af 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports.
    testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3 pattern is 2 / end actions mark id 1 / queue index 0 / end
    Flow rule #0 created
 
+Congestion Management
+---------------------
+
+Get capabilities
+~~~~~~~~~~~~~~~~
+
+Retrieve congestion management capabilities supported by driver for given port.
+Below example command retrieves capabilities for port 0::
+
+   testpmd> show port cman capa 0
+
+Get configuration
+~~~~~~~~~~~~~~~~~
+Retrieve congestion management configuration for given port. Below example
+command retrieves configuration for port 0::
+
+   testpmd> show port cman config 0
+
+Set configuration
+~~~~~~~~~~~~~~~~~
+Configures congestion management settings on given queue or mempool associated
+with queue. Below example command configures RED as congestion management algo
+for port 0 and queue 0::
+
+   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
+
 Driver specific commands
 ------------------------
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/3] common/cnxk: add congestion management ROC APIs
  2022-09-19 12:41 [PATCH 1/3] app/testpmd: support congestion management CLIs skori
@ 2022-09-19 12:41 ` skori
  2022-09-19 12:41 ` [PATCH 3/3] net/cnxk: support congestion management ops skori
  1 sibling, 0 replies; 17+ messages in thread
From: skori @ 2022-09-19 12:41 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Ray Kinsella
  Cc: dev

From: Sunil Kumar Kori <skori@marvell.com>

Add congestion management RoC APIs.

Depends-on: patch-24710 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 drivers/common/cnxk/roc_nix.h       |   5 ++
 drivers/common/cnxk/roc_nix_queue.c | 106 ++++++++++++++++++++++++++++
 drivers/common/cnxk/version.map     |   1 +
 3 files changed, 112 insertions(+)

diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 5c2a869eba..34cb2c717c 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -315,6 +315,10 @@ struct roc_nix_rq {
 	/* Average SPB aura level drop threshold for RED */
 	uint8_t spb_red_drop;
 	/* Average SPB aura level pass threshold for RED */
+	uint8_t xqe_red_pass;
+	/* Average xqe level drop threshold for RED */
+	uint8_t xqe_red_drop;
+	/* Average xqe level pass threshold for RED */
 	uint8_t spb_red_pass;
 	/* LPB aura drop enable */
 	bool lpb_drop_ena;
@@ -869,6 +873,7 @@ int __roc_api roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
 			      bool ena);
 int __roc_api roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
 				bool ena);
+int __roc_api roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq);
 int __roc_api roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable);
 int __roc_api roc_nix_rq_is_sso_enable(struct roc_nix *roc_nix, uint32_t qid);
 int __roc_api roc_nix_rq_fini(struct roc_nix_rq *rq);
diff --git a/drivers/common/cnxk/roc_nix_queue.c b/drivers/common/cnxk/roc_nix_queue.c
index 405d9a8274..368f1a52f7 100644
--- a/drivers/common/cnxk/roc_nix_queue.c
+++ b/drivers/common/cnxk/roc_nix_queue.c
@@ -235,6 +235,46 @@ nix_rq_aura_buf_type_update(struct roc_nix_rq *rq, bool set)
 	return 0;
 }
 
+static int
+nix_rq_cn9k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
+{
+	struct mbox *mbox = dev->mbox;
+	struct nix_aq_enq_req *aq;
+
+	aq = mbox_alloc_msg_nix_aq_enq(mbox);
+	if (!aq)
+		return -ENOSPC;
+
+	aq->qidx = rq->qid;
+	aq->ctype = NIX_AQ_CTYPE_RQ;
+	aq->op = NIX_AQ_INSTOP_WRITE;
+
+	if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
+		aq->rq.lpb_pool_pass = rq->red_pass;
+		aq->rq.lpb_pool_drop = rq->red_drop;
+		aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
+		aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
+
+	}
+
+	if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
+		aq->rq.spb_pool_pass = rq->spb_red_pass;
+		aq->rq.spb_pool_drop = rq->spb_red_drop;
+		aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
+		aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
+
+	}
+
+	if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
+		aq->rq.xqe_pass = rq->xqe_red_pass;
+		aq->rq.xqe_drop = rq->xqe_red_drop;
+		aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
+		aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
+	}
+
+	return mbox_process(mbox);
+}
+
 int
 nix_rq_cn9k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints,
 		bool cfg, bool ena)
@@ -529,6 +569,46 @@ nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg,
 	return 0;
 }
 
+static int
+nix_rq_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
+{
+	struct nix_cn10k_aq_enq_req *aq;
+	struct mbox *mbox = dev->mbox;
+
+	aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+	if (!aq)
+		return -ENOSPC;
+
+	aq->qidx = rq->qid;
+	aq->ctype = NIX_AQ_CTYPE_RQ;
+	aq->op = NIX_AQ_INSTOP_WRITE;
+
+	if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
+		aq->rq.lpb_pool_pass = rq->red_pass;
+		aq->rq.lpb_pool_drop = rq->red_drop;
+		aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
+		aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
+
+	}
+
+	if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
+		aq->rq.spb_pool_pass = rq->spb_red_pass;
+		aq->rq.spb_pool_drop = rq->spb_red_drop;
+		aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
+		aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
+
+	}
+
+	if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
+		aq->rq.xqe_pass = rq->xqe_red_pass;
+		aq->rq.xqe_drop = rq->xqe_red_drop;
+		aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
+		aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
+	}
+
+	return mbox_process(mbox);
+}
+
 int
 roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
 {
@@ -616,6 +696,32 @@ roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
 	return nix_tel_node_add_rq(rq);
 }
 
+int
+roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq)
+{
+	bool is_cn9k = roc_model_is_cn9k();
+	struct nix *nix;
+	struct dev *dev;
+	int rc;
+
+	if (roc_nix == NULL || rq == NULL)
+		return NIX_ERR_PARAM;
+
+	nix = roc_nix_to_nix_priv(roc_nix);
+
+	if (rq->qid >= nix->nb_rx_queues)
+		return NIX_ERR_QUEUE_INVALID_RANGE;
+
+	dev = &nix->dev;
+
+	if (is_cn9k)
+		rc = nix_rq_cn9k_cman_cfg(dev, rq);
+	else
+		rc = nix_rq_cman_cfg(dev, rq);
+
+	return rc;
+}
+
 int
 roc_nix_rq_fini(struct roc_nix_rq *rq)
 {
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 276fec3660..e935f17c28 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -228,6 +228,7 @@ INTERNAL {
 	roc_nix_reassembly_configure;
 	roc_nix_register_cq_irqs;
 	roc_nix_register_queue_irqs;
+	roc_nix_rq_cman_config;
 	roc_nix_rq_dump;
 	roc_nix_rq_ena_dis;
 	roc_nix_rq_fini;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/3] net/cnxk: support congestion management ops
  2022-09-19 12:41 [PATCH 1/3] app/testpmd: support congestion management CLIs skori
  2022-09-19 12:41 ` [PATCH 2/3] common/cnxk: add congestion management ROC APIs skori
@ 2022-09-19 12:41 ` skori
  2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
  1 sibling, 1 reply; 17+ messages in thread
From: skori @ 2022-09-19 12:41 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao; +Cc: dev

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management.

Depends-on: patch-24710 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 doc/guides/nics/features/cnxk.ini   |   1 +
 drivers/net/cnxk/cnxk_ethdev.c      |   4 +
 drivers/net/cnxk/cnxk_ethdev.h      |  12 +++
 drivers/net/cnxk/cnxk_ethdev_cman.c | 140 ++++++++++++++++++++++++++++
 drivers/net/cnxk/meson.build        |   1 +
 5 files changed, 158 insertions(+)
 create mode 100644 drivers/net/cnxk/cnxk_ethdev_cman.c

diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini
index 1876fe86c7..bbb90e9527 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -41,6 +41,7 @@ Rx descriptor status = Y
 Tx descriptor status = Y
 Basic stats          = Y
 Stats per queue      = Y
+Congestion management = Y
 Extended stats       = Y
 FW version           = Y
 Module EEPROM dump   = Y
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 48170147a4..2d46938d68 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1678,6 +1678,10 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.tm_ops_get = cnxk_nix_tm_ops_get,
 	.mtr_ops_get = cnxk_nix_mtr_ops_get,
 	.eth_dev_priv_dump  = cnxk_nix_eth_dev_priv_dump,
+	.cman_info_get = cnxk_nix_cman_info_get,
+	.cman_config_init = cnxk_nix_cman_config_init,
+	.cman_config_set = cnxk_nix_cman_config_set,
+	.cman_config_get = cnxk_nix_cman_config_get,
 };
 
 static int
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index c09e9bff8e..f884a532e1 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -417,6 +417,9 @@ struct cnxk_eth_dev {
 	struct cnxk_mtr_policy mtr_policy;
 	struct cnxk_mtr mtr;
 
+	/* Congestion Management */
+	struct rte_eth_cman_config cman_cfg;
+
 	/* Rx burst for cleanup(Only Primary) */
 	eth_rx_burst_t rx_pkt_burst_no_offload;
 
@@ -649,6 +652,15 @@ cnxk_eth_sec_sess_get_by_sess(struct cnxk_eth_dev *dev,
 int cnxk_nix_inl_meta_pool_cb(uint64_t *aura_handle, uint32_t buf_sz, uint32_t nb_bufs,
 			      bool destroy);
 
+/* Congestion Management */
+int cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info);
+
+int cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_set(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_get(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
 /* Other private functions */
 int nix_recalc_mtu(struct rte_eth_dev *eth_dev);
 int nix_mtr_validate(struct rte_eth_dev *dev, uint32_t id);
diff --git a/drivers/net/cnxk/cnxk_ethdev_cman.c b/drivers/net/cnxk/cnxk_ethdev_cman.c
new file mode 100644
index 0000000000..5f019cd721
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_ethdev_cman.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include "cnxk_ethdev.h"
+
+#define CNXK_NIX_CMAN_RED_MIN_THRESH 75
+#define CNXK_NIX_CMAN_RED_MAX_THRESH 95
+
+int
+cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info)
+{
+	RTE_SET_USED(dev);
+
+	info->modes_supported = RTE_CMAN_RED;
+	info->objs_supported = RTE_ETH_CMAN_OBJ_RX_QUEUE | RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config)
+{
+	RTE_SET_USED(dev);
+
+	memset(config, 0, sizeof(struct rte_eth_cman_config));
+
+	config->obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	config->mode = RTE_CMAN_RED;
+	config->mode_param.red.min_th = CNXK_NIX_CMAN_RED_MIN_THRESH;
+	config->mode_param.red.max_th = CNXK_NIX_CMAN_RED_MAX_THRESH;
+	return 0;
+}
+
+static int
+nix_cman_config_validate(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct rte_eth_cman_info info;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	cnxk_nix_cman_info_get(eth_dev, &info);
+
+	if (!(config->obj & info.objs_supported)) {
+		plt_err("Invalid object");
+		return -EINVAL;
+	}
+
+	if (!(config->mode & info.modes_supported)) {
+		plt_err("Invalid mode");
+		return -EINVAL;
+	}
+
+	if (config->obj_param.rx_queue >= dev->nb_rxq) {
+		plt_err("Invalid queue ID. Queue = %u", config->obj_param.rx_queue);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.min_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED minimum threshold. min_th = %u",
+			config->mode_param.red.min_th);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.max_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED maximum threshold. max_th = %u",
+			config->mode_param.red.max_th);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_set(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	uint8_t drop, pass, shift;
+	uint8_t min_th, max_th;
+	struct roc_nix_cq *cq;
+	struct roc_nix_rq *rq;
+	bool is_mempool;
+	uint64_t buf_cnt;
+	int rc;
+
+	rc = nix_cman_config_validate(eth_dev, config);
+	if (rc)
+		return rc;
+
+	cq = &dev->cqs[config->obj_param.rx_queue];
+	rq = &dev->rqs[config->obj_param.rx_queue];
+	is_mempool = config->obj & RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL ? true : false;
+	min_th = config->mode_param.red.min_th;
+	max_th = config->mode_param.red.max_th;
+
+	if (is_mempool) {
+		buf_cnt = roc_npa_aura_op_limit_get(rq->aura_handle);
+		shift = plt_log2_u32(buf_cnt);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+		drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+		rq->red_pass = pass;
+		rq->red_drop = drop;
+
+		if (rq->spb_ena) {
+			buf_cnt = roc_npa_aura_op_limit_get(rq->spb_aura_handle);
+			shift = plt_log2_u32(buf_cnt);
+			shift = shift < 8 ? 0 : shift - 8;
+			pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+			drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+			rq->spb_red_pass = pass;
+			rq->spb_red_drop = drop;
+		}
+	} else {
+		shift = plt_log2_u32(cq->nb_desc);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = 256 - ((cq->nb_desc * min_th / 100) >> shift);
+		drop = 256 - ((cq->nb_desc * max_th / 100) >> shift);
+
+		rq->xqe_red_pass = pass;
+		rq->xqe_red_drop = drop;
+	}
+
+	rc = roc_nix_rq_cman_config(nix, rq);
+	if (rc)
+		return rc;
+
+	memcpy(&dev->cman_cfg, config, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_get(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	memcpy(config, &dev->cman_cfg, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index f347e98fce..9253e8d0ab 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -10,6 +10,7 @@ endif
 
 sources = files(
         'cnxk_ethdev.c',
+        'cnxk_ethdev_cman.c',
         'cnxk_ethdev_devargs.c',
         'cnxk_ethdev_mtr.c',
         'cnxk_ethdev_ops.c',
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 1/3] app/testpmd: support congestion management CLIs
  2022-09-19 12:41 ` [PATCH 3/3] net/cnxk: support congestion management ops skori
@ 2022-09-29  9:54   ` skori
  2022-09-29  9:54     ` [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs skori
                       ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: skori @ 2022-09-29  9:54 UTC (permalink / raw)
  To: Aman Singh, Yuying Zhang; +Cc: dev, Sunil Kumar Kori

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management CLIs.

Depends-on: patch-24902 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
v1..v2:
 - Rebase on top of the dpdk-next-net-mrvl/for-next-net

 app/test-pmd/cmdline.c                      |  15 +
 app/test-pmd/cmdline_cman.c                 | 390 ++++++++++++++++++++
 app/test-pmd/cmdline_cman.h                 |  12 +
 app/test-pmd/meson.build                    |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
 5 files changed, 444 insertions(+)
 create mode 100644 app/test-pmd/cmdline_cman.c
 create mode 100644 app/test-pmd/cmdline_cman.h

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 51321de9ed..ce278eadb0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -60,6 +60,7 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include "testpmd.h"
+#include "cmdline_cman.h"
 #include "cmdline_mtr.h"
 #include "cmdline_tm.h"
 #include "bpf_cmd.h"
@@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) fec_mode auto|off|rs|baser\n"
 			"    set fec mode for a specific port\n\n"
 
+			"show port cman capa (port_id)\n"
+			"    Show congestion management capabilities\n\n"
+
+			"show port cman config (port_id)\n"
+			"    Show congestion management configuration\n\n"
+
+			"set port cman config (port_id) (queue_id) default | "
+			"[obj (queue|queue_mempool) mode red (min_thresh) "
+			"(max_thresh) (prob_inv)]\n"
+			"    Set congestion management configuration\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_capability,
 	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
 	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
+	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
 	NULL,
 };
 
diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
new file mode 100644
index 0000000000..344759189d
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.c
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+
+#include <rte_ethdev.h>
+
+#include "testpmd.h"
+
+#define PARSE_DELIMITER				" \f\n\r\t\v"
+
+static int
+parse_uint(uint64_t *value, const char *str)
+{
+	char *next = NULL;
+	uint64_t n;
+
+	errno = 0;
+	/* Parse number string */
+	n = strtol(str, &next, 10);
+	if (errno != 0 || str == next || *next != '\0')
+		return -1;
+
+	*value = n;
+
+	return 0;
+}
+
+static int
+parse_cman_obj_str(char *str, uint64_t *obj)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "queue") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	else if (strcasecmp(token, "queue_mempool") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_mode_str(char *str, uint64_t *mode)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "red") == 0)
+		*mode = RTE_CMAN_RED;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_params_str(uint16_t port_id, char *str,
+		      struct rte_eth_cman_config *cfg)
+{
+	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
+	struct rte_eth_cman_info info;
+	char *token;
+	int ret;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (!strcasecmp(token, "default")) {
+		ret = rte_eth_cman_config_init(port_id, cfg);
+		if (ret) {
+			fprintf(stderr, "error in default initialization\n");
+			return ret;
+		}
+		return 0;
+	}
+
+	/* First token: obj name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Object param parse error\n");
+		goto error;
+	}
+
+	ret = parse_cman_obj_str(token, &obj);
+	if (ret) {
+		fprintf(stderr, "Object value is invalid\n");
+		goto error;
+	}
+
+	/* Second token: mode name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode param is invalid\n");
+		goto error;
+	}
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode value is invalid\n");
+		goto error;
+	}
+
+	ret = parse_cman_mode_str(token, &mode);
+	if (ret) {
+		fprintf(stderr, "mode string parse error\n");
+		goto error;
+	}
+
+	/* Third token: minimum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Minimum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&min_th, token);
+	if (ret != 0 || min_th > UINT8_MAX) {
+		fprintf(stderr, "Minimum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fourth token: maximum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&max_th, token);
+	if (ret != 0 || max_th > UINT8_MAX) {
+		fprintf(stderr, "Maximum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fifth token: probability inversion */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum probability inversion parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&maxp_inv, token);
+	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
+		fprintf(stderr, "Maximum probability inversion is invalid\n");
+		goto error;
+	}
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret) {
+		fprintf(stderr, "Congestion management capa get error\n");
+		goto error;
+	}
+
+	if (!(info.objs_supported & obj)) {
+		fprintf(stderr, "Object type is not supported by driver\n");
+		goto error;
+	}
+
+	if (!(info.modes_supported & mode)) {
+		fprintf(stderr, "Mode is not supported by driver\n");
+		goto error;
+	}
+
+	cfg->obj = obj;
+	cfg->mode = mode;
+	cfg->mode_param.red.min_th = min_th;
+	cfg->mode_param.red.max_th = max_th;
+	cfg->mode_param.red.maxp_inv = maxp_inv;
+
+	return 0;
+
+error:
+	return -EINVAL;
+}
+
+/* *** Show Port Congestion Management Capabilities *** */
+struct cmd_show_port_cman_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t capa;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, capa, "capa");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_capa_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_capa_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_info info;
+	int ret;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Capabilities   ****\n\n");
+	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
+	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_capa = {
+	.f = cmd_show_port_cman_capa_parsed,
+	.data = NULL,
+	.help_str = "show port cman capa <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_capa_show,
+		(void *)&cmd_show_port_cman_capa_port,
+		(void *)&cmd_show_port_cman_capa_cman,
+		(void *)&cmd_show_port_cman_capa_capa,
+		(void *)&cmd_show_port_cman_capa_port_id,
+		NULL,
+	},
+};
+
+/* *** Show Port Congestion Management configuration *** */
+struct cmd_show_port_cman_cfg_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
+	ret = rte_eth_cman_config_get(port_id, &cfg);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Configuration   ****\n\n");
+	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
+	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
+	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
+	printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th);
+	printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th);
+	printf("cman RED Prob inversion %" PRIx16 "\n",
+		cfg.mode_param.red.maxp_inv);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_config = {
+	.f = cmd_show_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "show port cman config <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_cfg_show,
+		(void *)&cmd_show_port_cman_cfg_port,
+		(void *)&cmd_show_port_cman_cfg_cman,
+		(void *)&cmd_show_port_cman_cfg_cfg,
+		(void *)&cmd_show_port_cman_cfg_port_id,
+		NULL,
+	},
+};
+
+/* *** Set Port Congestion Management configuration *** */
+struct cmd_set_port_cman_cfg_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+	uint16_t qid;
+	cmdline_multi_string_t params;
+};
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, set, "set");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
+		params, TOKEN_STRING_MULTI);
+
+static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_set_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	ret = parse_cman_params_str(port_id, res->params, &cfg);
+	if (ret) {
+		fprintf(stderr, "params string parse error\n");
+		return;
+	}
+
+	cfg.obj_param.rx_queue = res->qid;
+	rte_eth_cman_config_set(port_id, &cfg);
+}
+
+cmdline_parse_inst_t cmd_set_port_cman_config = {
+	.f = cmd_set_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "set port cman config <port_id> <queue_id> "
+		    "default | [obj <queue|queue_mempool> mode red "
+		    "<min_thresh> <max_thresh> <prob_inv>]",
+	.tokens = {
+		(void *)&cmd_set_port_cman_cfg_set,
+		(void *)&cmd_set_port_cman_cfg_port,
+		(void *)&cmd_set_port_cman_cfg_cman,
+		(void *)&cmd_set_port_cman_cfg_cfg,
+		(void *)&cmd_set_port_cman_cfg_port_id,
+		(void *)&cmd_set_port_cman_cfg_qid,
+		(void *)&cmd_set_port_cman_cfg_params,
+		NULL,
+	},
+};
diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
new file mode 100644
index 0000000000..bd6c99ce35
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#ifndef _CMDLINE_CMAN_H_
+#define _CMDLINE_CMAN_H_
+
+extern cmdline_parse_inst_t cmd_show_port_cman_capa;
+extern cmdline_parse_inst_t cmd_show_port_cman_config;
+extern cmdline_parse_inst_t cmd_set_port_cman_config;
+
+#endif /* _CMDLINE_CMAN_H_ */
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 74399178dd..c03d9dfebb 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
 sources = files(
         '5tswap.c',
         'cmdline.c',
+        'cmdline_cman.c',
         'cmdline_flow.c',
         'cmdline_mtr.c',
         'cmdline_tm.c',
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index d3075bf87d..b9c7b468af 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports.
    testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3 pattern is 2 / end actions mark id 1 / queue index 0 / end
    Flow rule #0 created
 
+Congestion Management
+---------------------
+
+Get capabilities
+~~~~~~~~~~~~~~~~
+
+Retrieve congestion management capabilities supported by driver for given port.
+Below example command retrieves capabilities for port 0::
+
+   testpmd> show port cman capa 0
+
+Get configuration
+~~~~~~~~~~~~~~~~~
+Retrieve congestion management configuration for given port. Below example
+command retrieves configuration for port 0::
+
+   testpmd> show port cman config 0
+
+Set configuration
+~~~~~~~~~~~~~~~~~
+Configures congestion management settings on given queue or mempool associated
+with queue. Below example command configures RED as congestion management algo
+for port 0 and queue 0::
+
+   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
+
 Driver specific commands
 ------------------------
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs
  2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
@ 2022-09-29  9:54     ` skori
  2022-10-11  6:27       ` Sunil Kumar Kori
  2022-09-29  9:54     ` [PATCH v2 3/3] net/cnxk: support congestion management ops skori
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: skori @ 2022-09-29  9:54 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Ray Kinsella
  Cc: dev

From: Sunil Kumar Kori <skori@marvell.com>

Add congestion management RoC APIs.

Depends-on: patch-24902 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
v1..v2:
 - Rebase on top of the dpdk-next-net-mrvl/for-next-net

 drivers/common/cnxk/roc_nix.h       |   5 ++
 drivers/common/cnxk/roc_nix_queue.c | 106 ++++++++++++++++++++++++++++
 drivers/common/cnxk/version.map     |   1 +
 3 files changed, 112 insertions(+)

diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 5c2a869eba..34cb2c717c 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -315,6 +315,10 @@ struct roc_nix_rq {
 	/* Average SPB aura level drop threshold for RED */
 	uint8_t spb_red_drop;
 	/* Average SPB aura level pass threshold for RED */
+	uint8_t xqe_red_pass;
+	/* Average xqe level drop threshold for RED */
+	uint8_t xqe_red_drop;
+	/* Average xqe level pass threshold for RED */
 	uint8_t spb_red_pass;
 	/* LPB aura drop enable */
 	bool lpb_drop_ena;
@@ -869,6 +873,7 @@ int __roc_api roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
 			      bool ena);
 int __roc_api roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
 				bool ena);
+int __roc_api roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq);
 int __roc_api roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable);
 int __roc_api roc_nix_rq_is_sso_enable(struct roc_nix *roc_nix, uint32_t qid);
 int __roc_api roc_nix_rq_fini(struct roc_nix_rq *rq);
diff --git a/drivers/common/cnxk/roc_nix_queue.c b/drivers/common/cnxk/roc_nix_queue.c
index 405d9a8274..368f1a52f7 100644
--- a/drivers/common/cnxk/roc_nix_queue.c
+++ b/drivers/common/cnxk/roc_nix_queue.c
@@ -235,6 +235,46 @@ nix_rq_aura_buf_type_update(struct roc_nix_rq *rq, bool set)
 	return 0;
 }
 
+static int
+nix_rq_cn9k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
+{
+	struct mbox *mbox = dev->mbox;
+	struct nix_aq_enq_req *aq;
+
+	aq = mbox_alloc_msg_nix_aq_enq(mbox);
+	if (!aq)
+		return -ENOSPC;
+
+	aq->qidx = rq->qid;
+	aq->ctype = NIX_AQ_CTYPE_RQ;
+	aq->op = NIX_AQ_INSTOP_WRITE;
+
+	if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
+		aq->rq.lpb_pool_pass = rq->red_pass;
+		aq->rq.lpb_pool_drop = rq->red_drop;
+		aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
+		aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
+
+	}
+
+	if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
+		aq->rq.spb_pool_pass = rq->spb_red_pass;
+		aq->rq.spb_pool_drop = rq->spb_red_drop;
+		aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
+		aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
+
+	}
+
+	if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
+		aq->rq.xqe_pass = rq->xqe_red_pass;
+		aq->rq.xqe_drop = rq->xqe_red_drop;
+		aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
+		aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
+	}
+
+	return mbox_process(mbox);
+}
+
 int
 nix_rq_cn9k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints,
 		bool cfg, bool ena)
@@ -529,6 +569,46 @@ nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg,
 	return 0;
 }
 
+static int
+nix_rq_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
+{
+	struct nix_cn10k_aq_enq_req *aq;
+	struct mbox *mbox = dev->mbox;
+
+	aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+	if (!aq)
+		return -ENOSPC;
+
+	aq->qidx = rq->qid;
+	aq->ctype = NIX_AQ_CTYPE_RQ;
+	aq->op = NIX_AQ_INSTOP_WRITE;
+
+	if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
+		aq->rq.lpb_pool_pass = rq->red_pass;
+		aq->rq.lpb_pool_drop = rq->red_drop;
+		aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
+		aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
+
+	}
+
+	if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
+		aq->rq.spb_pool_pass = rq->spb_red_pass;
+		aq->rq.spb_pool_drop = rq->spb_red_drop;
+		aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
+		aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
+
+	}
+
+	if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
+		aq->rq.xqe_pass = rq->xqe_red_pass;
+		aq->rq.xqe_drop = rq->xqe_red_drop;
+		aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
+		aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
+	}
+
+	return mbox_process(mbox);
+}
+
 int
 roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
 {
@@ -616,6 +696,32 @@ roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
 	return nix_tel_node_add_rq(rq);
 }
 
+int
+roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq)
+{
+	bool is_cn9k = roc_model_is_cn9k();
+	struct nix *nix;
+	struct dev *dev;
+	int rc;
+
+	if (roc_nix == NULL || rq == NULL)
+		return NIX_ERR_PARAM;
+
+	nix = roc_nix_to_nix_priv(roc_nix);
+
+	if (rq->qid >= nix->nb_rx_queues)
+		return NIX_ERR_QUEUE_INVALID_RANGE;
+
+	dev = &nix->dev;
+
+	if (is_cn9k)
+		rc = nix_rq_cn9k_cman_cfg(dev, rq);
+	else
+		rc = nix_rq_cman_cfg(dev, rq);
+
+	return rc;
+}
+
 int
 roc_nix_rq_fini(struct roc_nix_rq *rq)
 {
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 276fec3660..e935f17c28 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -228,6 +228,7 @@ INTERNAL {
 	roc_nix_reassembly_configure;
 	roc_nix_register_cq_irqs;
 	roc_nix_register_queue_irqs;
+	roc_nix_rq_cman_config;
 	roc_nix_rq_dump;
 	roc_nix_rq_ena_dis;
 	roc_nix_rq_fini;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/3] net/cnxk: support congestion management ops
  2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
  2022-09-29  9:54     ` [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs skori
@ 2022-09-29  9:54     ` skori
  2022-10-11  6:29       ` Sunil Kumar Kori
  2022-10-12  9:01     ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs Sunil Kumar Kori
  2022-11-29  8:04     ` [PATCH v3 1/1] " skori
  3 siblings, 1 reply; 17+ messages in thread
From: skori @ 2022-09-29  9:54 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao; +Cc: dev

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management.

Depends-on: patch-24902 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
v1..v2:
 - Rebase on top of the dpdk-next-net-mrvl/for-next-net
 - Aligned with congestion management v3 spec

 doc/guides/nics/features/cnxk.ini      |   1 +
 doc/guides/rel_notes/release_22_11.rst |   4 +
 drivers/net/cnxk/cnxk_ethdev.c         |   4 +
 drivers/net/cnxk/cnxk_ethdev.h         |  12 +++
 drivers/net/cnxk/cnxk_ethdev_cman.c    | 140 +++++++++++++++++++++++++
 drivers/net/cnxk/meson.build           |   1 +
 6 files changed, 162 insertions(+)
 create mode 100644 drivers/net/cnxk/cnxk_ethdev_cman.c

diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini
index 1876fe86c7..bbb90e9527 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -41,6 +41,7 @@ Rx descriptor status = Y
 Tx descriptor status = Y
 Basic stats          = Y
 Stats per queue      = Y
+Congestion management = Y
 Extended stats       = Y
 FW version           = Y
 Module EEPROM dump   = Y
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 2e076ba2ad..18206587d8 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -59,6 +59,10 @@ New Features
 
   * Added support to set device link down/up.
 
+* **Added Random Early Discard(RED) based congestion management for CN9K & CN10K.**
+
+  * Added support to set/get congestion management configuration.
+  * Added support to get congestion management capabilities.
 
 Removed Items
 -------------
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 48170147a4..2d46938d68 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1678,6 +1678,10 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.tm_ops_get = cnxk_nix_tm_ops_get,
 	.mtr_ops_get = cnxk_nix_mtr_ops_get,
 	.eth_dev_priv_dump  = cnxk_nix_eth_dev_priv_dump,
+	.cman_info_get = cnxk_nix_cman_info_get,
+	.cman_config_init = cnxk_nix_cman_config_init,
+	.cman_config_set = cnxk_nix_cman_config_set,
+	.cman_config_get = cnxk_nix_cman_config_get,
 };
 
 static int
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index c09e9bff8e..fc72ae917c 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -417,6 +417,9 @@ struct cnxk_eth_dev {
 	struct cnxk_mtr_policy mtr_policy;
 	struct cnxk_mtr mtr;
 
+	/* Congestion Management */
+	struct rte_eth_cman_config cman_cfg;
+
 	/* Rx burst for cleanup(Only Primary) */
 	eth_rx_burst_t rx_pkt_burst_no_offload;
 
@@ -649,6 +652,15 @@ cnxk_eth_sec_sess_get_by_sess(struct cnxk_eth_dev *dev,
 int cnxk_nix_inl_meta_pool_cb(uint64_t *aura_handle, uint32_t buf_sz, uint32_t nb_bufs,
 			      bool destroy);
 
+/* Congestion Management */
+int cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info);
+
+int cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_set(struct rte_eth_dev *dev, const struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_get(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
 /* Other private functions */
 int nix_recalc_mtu(struct rte_eth_dev *eth_dev);
 int nix_mtr_validate(struct rte_eth_dev *dev, uint32_t id);
diff --git a/drivers/net/cnxk/cnxk_ethdev_cman.c b/drivers/net/cnxk/cnxk_ethdev_cman.c
new file mode 100644
index 0000000000..d5e647c64d
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_ethdev_cman.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include "cnxk_ethdev.h"
+
+#define CNXK_NIX_CMAN_RED_MIN_THRESH 75
+#define CNXK_NIX_CMAN_RED_MAX_THRESH 95
+
+int
+cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info)
+{
+	RTE_SET_USED(dev);
+
+	info->modes_supported = RTE_CMAN_RED;
+	info->objs_supported = RTE_ETH_CMAN_OBJ_RX_QUEUE | RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config)
+{
+	RTE_SET_USED(dev);
+
+	memset(config, 0, sizeof(struct rte_eth_cman_config));
+
+	config->obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	config->mode = RTE_CMAN_RED;
+	config->mode_param.red.min_th = CNXK_NIX_CMAN_RED_MIN_THRESH;
+	config->mode_param.red.max_th = CNXK_NIX_CMAN_RED_MAX_THRESH;
+	return 0;
+}
+
+static int
+nix_cman_config_validate(struct rte_eth_dev *eth_dev, const struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct rte_eth_cman_info info;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	cnxk_nix_cman_info_get(eth_dev, &info);
+
+	if (!(config->obj & info.objs_supported)) {
+		plt_err("Invalid object");
+		return -EINVAL;
+	}
+
+	if (!(config->mode & info.modes_supported)) {
+		plt_err("Invalid mode");
+		return -EINVAL;
+	}
+
+	if (config->obj_param.rx_queue >= dev->nb_rxq) {
+		plt_err("Invalid queue ID. Queue = %u", config->obj_param.rx_queue);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.min_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED minimum threshold. min_th = %u",
+			config->mode_param.red.min_th);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.max_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED maximum threshold. max_th = %u",
+			config->mode_param.red.max_th);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_set(struct rte_eth_dev *eth_dev, const struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	uint8_t drop, pass, shift;
+	uint8_t min_th, max_th;
+	struct roc_nix_cq *cq;
+	struct roc_nix_rq *rq;
+	bool is_mempool;
+	uint64_t buf_cnt;
+	int rc;
+
+	rc = nix_cman_config_validate(eth_dev, config);
+	if (rc)
+		return rc;
+
+	cq = &dev->cqs[config->obj_param.rx_queue];
+	rq = &dev->rqs[config->obj_param.rx_queue];
+	is_mempool = config->obj & RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL ? true : false;
+	min_th = config->mode_param.red.min_th;
+	max_th = config->mode_param.red.max_th;
+
+	if (is_mempool) {
+		buf_cnt = roc_npa_aura_op_limit_get(rq->aura_handle);
+		shift = plt_log2_u32(buf_cnt);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+		drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+		rq->red_pass = pass;
+		rq->red_drop = drop;
+
+		if (rq->spb_ena) {
+			buf_cnt = roc_npa_aura_op_limit_get(rq->spb_aura_handle);
+			shift = plt_log2_u32(buf_cnt);
+			shift = shift < 8 ? 0 : shift - 8;
+			pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+			drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+			rq->spb_red_pass = pass;
+			rq->spb_red_drop = drop;
+		}
+	} else {
+		shift = plt_log2_u32(cq->nb_desc);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = 256 - ((cq->nb_desc * min_th / 100) >> shift);
+		drop = 256 - ((cq->nb_desc * max_th / 100) >> shift);
+
+		rq->xqe_red_pass = pass;
+		rq->xqe_red_drop = drop;
+	}
+
+	rc = roc_nix_rq_cman_config(nix, rq);
+	if (rc)
+		return rc;
+
+	memcpy(&dev->cman_cfg, config, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_get(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	memcpy(config, &dev->cman_cfg, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index f347e98fce..9253e8d0ab 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -10,6 +10,7 @@ endif
 
 sources = files(
         'cnxk_ethdev.c',
+        'cnxk_ethdev_cman.c',
         'cnxk_ethdev_devargs.c',
         'cnxk_ethdev_mtr.c',
         'cnxk_ethdev_ops.c',
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* RE: [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs
  2022-09-29  9:54     ` [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs skori
@ 2022-10-11  6:27       ` Sunil Kumar Kori
  0 siblings, 0 replies; 17+ messages in thread
From: Sunil Kumar Kori @ 2022-10-11  6:27 UTC (permalink / raw)
  To: Sunil Kumar Kori, Nithin Kumar Dabilpuram,
	Kiran Kumar Kokkilagadda, Satha Koteswara Rao Kottidi,
	Ray Kinsella
  Cc: dev

Please look into the changes. 

Regards
Sunil Kumar Kori

> -----Original Message-----
> From: skori@marvell.com <skori@marvell.com>
> Sent: Thursday, September 29, 2022 3:25 PM
> To: Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; Kiran Kumar
> Kokkilagadda <kirankumark@marvell.com>; Sunil Kumar Kori
> <skori@marvell.com>; Satha Koteswara Rao Kottidi
> <skoteshwar@marvell.com>; Ray Kinsella <mdr@ashroe.eu>
> Cc: dev@dpdk.org
> Subject: [PATCH v2 2/3] common/cnxk: add congestion management ROC
> APIs
> 
> From: Sunil Kumar Kori <skori@marvell.com>
> 
> Add congestion management RoC APIs.
> 
> Depends-on: patch-24902 ("ethdev: support congestion management")
> 
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
> v1..v2:
>  - Rebase on top of the dpdk-next-net-mrvl/for-next-net
> 
>  drivers/common/cnxk/roc_nix.h       |   5 ++
>  drivers/common/cnxk/roc_nix_queue.c | 106
> ++++++++++++++++++++++++++++
>  drivers/common/cnxk/version.map     |   1 +
>  3 files changed, 112 insertions(+)
> 

[snip]

> --
> 2.25.1



^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH v2 3/3] net/cnxk: support congestion management ops
  2022-09-29  9:54     ` [PATCH v2 3/3] net/cnxk: support congestion management ops skori
@ 2022-10-11  6:29       ` Sunil Kumar Kori
  2022-10-12  6:43         ` Jerin Jacob
  0 siblings, 1 reply; 17+ messages in thread
From: Sunil Kumar Kori @ 2022-10-11  6:29 UTC (permalink / raw)
  To: Sunil Kumar Kori, Nithin Kumar Dabilpuram,
	Kiran Kumar Kokkilagadda, Satha Koteswara Rao Kottidi
  Cc: dev

Please look into these changes and provide feedback.

Regards
Sunil Kumar Kori

> -----Original Message-----
> From: skori@marvell.com <skori@marvell.com>
> Sent: Thursday, September 29, 2022 3:25 PM
> To: Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; Kiran Kumar
> Kokkilagadda <kirankumark@marvell.com>; Sunil Kumar Kori
> <skori@marvell.com>; Satha Koteswara Rao Kottidi
> <skoteshwar@marvell.com>
> Cc: dev@dpdk.org
> Subject: [PATCH v2 3/3] net/cnxk: support congestion management ops
> 
> From: Sunil Kumar Kori <skori@marvell.com>
> 
> Support congestion management.
> 
> Depends-on: patch-24902 ("ethdev: support congestion management")
> 
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
> v1..v2:
>  - Rebase on top of the dpdk-next-net-mrvl/for-next-net
>  - Aligned with congestion management v3 spec
> 
>  doc/guides/nics/features/cnxk.ini      |   1 +
>  doc/guides/rel_notes/release_22_11.rst |   4 +
>  drivers/net/cnxk/cnxk_ethdev.c         |   4 +
>  drivers/net/cnxk/cnxk_ethdev.h         |  12 +++
>  drivers/net/cnxk/cnxk_ethdev_cman.c    | 140 +++++++++++++++++++++++++
>  drivers/net/cnxk/meson.build           |   1 +
>  6 files changed, 162 insertions(+)
>  create mode 100644 drivers/net/cnxk/cnxk_ethdev_cman.c
> 
> 

[snip]

> --
> 2.25.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/3] net/cnxk: support congestion management ops
  2022-10-11  6:29       ` Sunil Kumar Kori
@ 2022-10-12  6:43         ` Jerin Jacob
  0 siblings, 0 replies; 17+ messages in thread
From: Jerin Jacob @ 2022-10-12  6:43 UTC (permalink / raw)
  To: Sunil Kumar Kori
  Cc: Nithin Kumar Dabilpuram, Kiran Kumar Kokkilagadda,
	Satha Koteswara Rao Kottidi, dev

On Tue, Oct 11, 2022 at 11:59 AM Sunil Kumar Kori <skori@marvell.com> wrote:
>
> Please look into these changes and provide feedback.
>
> Regards
> Sunil Kumar Kori
>
> > -----Original Message-----
> > From: skori@marvell.com <skori@marvell.com>
> > Sent: Thursday, September 29, 2022 3:25 PM
> > To: Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; Kiran Kumar
> > Kokkilagadda <kirankumark@marvell.com>; Sunil Kumar Kori
> > <skori@marvell.com>; Satha Koteswara Rao Kottidi
> > <skoteshwar@marvell.com>
> > Cc: dev@dpdk.org
> > Subject: [PATCH v2 3/3] net/cnxk: support congestion management ops
> >
> > From: Sunil Kumar Kori <skori@marvell.com>
> >
> > Support congestion management.
> >
> > Depends-on: patch-24902 ("ethdev: support congestion management")
> >
> > Signed-off-by: Sunil Kumar Kori <skori@marvell.com>

Merged https://patches.dpdk.org/project/dpdk/patch/20220929095455.2173071-2-skori@marvell.com/
and https://patches.dpdk.org/project/dpdk/patch/20220929095455.2173071-3-skori@marvell.com/
patches.

Fixed the doc update as
diff --git a/doc/guides/rel_notes/release_22_11.rst
b/doc/guides/rel_notes/release_22_11.rst
index 2da8bc9661..e9ac96ff4d 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -139,6 +139,7 @@ New Features
 * **Updated Marvell cnxk driver.**

   * Added support for flow action REPRESENTED_PORT.
+  * Added support for congestion management.

Series(2/3 and 3/3) applied to dpdk-next-net-mrvl/for-next-net. Thanks.



> > ---
> > v1..v2:
> >  - Rebase on top of the dpdk-next-net-mrvl/for-next-net
> >  - Aligned with congestion management v3 spec
> >
> >  doc/guides/nics/features/cnxk.ini      |   1 +
> >  doc/guides/rel_notes/release_22_11.rst |   4 +
> >  drivers/net/cnxk/cnxk_ethdev.c         |   4 +
> >  drivers/net/cnxk/cnxk_ethdev.h         |  12 +++
> >  drivers/net/cnxk/cnxk_ethdev_cman.c    | 140 +++++++++++++++++++++++++
> >  drivers/net/cnxk/meson.build           |   1 +
> >  6 files changed, 162 insertions(+)
> >  create mode 100644 drivers/net/cnxk/cnxk_ethdev_cman.c
> >
> >
>
> [snip]
>
> > --
> > 2.25.1
>

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* RE: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
  2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
  2022-09-29  9:54     ` [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs skori
  2022-09-29  9:54     ` [PATCH v2 3/3] net/cnxk: support congestion management ops skori
@ 2022-10-12  9:01     ` Sunil Kumar Kori
  2022-11-06 10:08       ` Andrew Rybchenko
  2022-11-29  8:04     ` [PATCH v3 1/1] " skori
  3 siblings, 1 reply; 17+ messages in thread
From: Sunil Kumar Kori @ 2022-10-12  9:01 UTC (permalink / raw)
  To: Sunil Kumar Kori, Aman Singh, Yuying Zhang; +Cc: dev

Please review the following changes and provide feedback. 

Regards
Sunil Kumar Kori

> -----Original Message-----
> From: skori@marvell.com <skori@marvell.com>
> Sent: Thursday, September 29, 2022 3:25 PM
> To: Aman Singh <aman.deep.singh@intel.com>; Yuying Zhang
> <yuying.zhang@intel.com>
> Cc: dev@dpdk.org; Sunil Kumar Kori <skori@marvell.com>
> Subject: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
> 
> From: Sunil Kumar Kori <skori@marvell.com>
> 
> Support congestion management CLIs.
> 
> Depends-on: patch-24902 ("ethdev: support congestion management")
> 
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
> v1..v2:
>  - Rebase on top of the dpdk-next-net-mrvl/for-next-net
> 
>  app/test-pmd/cmdline.c                      |  15 +
>  app/test-pmd/cmdline_cman.c                 | 390 ++++++++++++++++++++
>  app/test-pmd/cmdline_cman.h                 |  12 +
>  app/test-pmd/meson.build                    |   1 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
>  5 files changed, 444 insertions(+)
>  create mode 100644 app/test-pmd/cmdline_cman.c  create mode 100644
> app/test-pmd/cmdline_cman.h
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 51321de9ed..ce278eadb0 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -60,6 +60,7 @@
>  #include <rte_pmd_bnxt.h>
>  #endif
>  #include "testpmd.h"
> +#include "cmdline_cman.h"
>  #include "cmdline_mtr.h"
>  #include "cmdline_tm.h"
>  #include "bpf_cmd.h"
> @@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void
> *parsed_result,
>  			"set port (port_id) fec_mode auto|off|rs|baser\n"
>  			"    set fec mode for a specific port\n\n"
> 
> +			"show port cman capa (port_id)\n"
> +			"    Show congestion management capabilities\n\n"
> +
> +			"show port cman config (port_id)\n"
> +			"    Show congestion management configuration\n\n"
> +
> +			"set port cman config (port_id) (queue_id) default | "
> +			"[obj (queue|queue_mempool) mode red
> (min_thresh) "
> +			"(max_thresh) (prob_inv)]\n"
> +			"    Set congestion management configuration\n\n"
> +
>  			, list_pkt_forwarding_modes()
>  		);
>  	}
> @@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_show_capability,
>  	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
>  	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
> +	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
> +	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
> +	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
>  	NULL,
>  };
> 
> diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
> new file mode 100644 index 0000000000..344759189d
> --- /dev/null
> +++ b/app/test-pmd/cmdline_cman.c
> @@ -0,0 +1,390 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2022 Marvell International Ltd.
> + */
> +
> +#include <cmdline_parse.h>
> +#include <cmdline_parse_num.h>
> +#include <cmdline_parse_string.h>
> +
> +#include <rte_ethdev.h>
> +
> +#include "testpmd.h"
> +
> +#define PARSE_DELIMITER				" \f\n\r\t\v"
> +
> +static int
> +parse_uint(uint64_t *value, const char *str) {
> +	char *next = NULL;
> +	uint64_t n;
> +
> +	errno = 0;
> +	/* Parse number string */
> +	n = strtol(str, &next, 10);
> +	if (errno != 0 || str == next || *next != '\0')
> +		return -1;
> +
> +	*value = n;
> +
> +	return 0;
> +}
> +
> +static int
> +parse_cman_obj_str(char *str, uint64_t *obj) {
> +	char *token;
> +
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL)
> +		return 0;
> +
> +	if (strcasecmp(token, "queue") == 0)
> +		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
> +	else if (strcasecmp(token, "queue_mempool") == 0)
> +		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
> +	else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int
> +parse_cman_mode_str(char *str, uint64_t *mode) {
> +	char *token;
> +
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL)
> +		return 0;
> +
> +	if (strcasecmp(token, "red") == 0)
> +		*mode = RTE_CMAN_RED;
> +	else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int
> +parse_cman_params_str(uint16_t port_id, char *str,
> +		      struct rte_eth_cman_config *cfg) {
> +	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
> +	struct rte_eth_cman_info info;
> +	char *token;
> +	int ret;
> +
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (!strcasecmp(token, "default")) {
> +		ret = rte_eth_cman_config_init(port_id, cfg);
> +		if (ret) {
> +			fprintf(stderr, "error in default initialization\n");
> +			return ret;
> +		}
> +		return 0;
> +	}
> +
> +	/* First token: obj name */
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, "Object param parse error\n");
> +		goto error;
> +	}
> +
> +	ret = parse_cman_obj_str(token, &obj);
> +	if (ret) {
> +		fprintf(stderr, "Object value is invalid\n");
> +		goto error;
> +	}
> +
> +	/* Second token: mode name */
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, " Mode param is invalid\n");
> +		goto error;
> +	}
> +
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, " Mode value is invalid\n");
> +		goto error;
> +	}
> +
> +	ret = parse_cman_mode_str(token, &mode);
> +	if (ret) {
> +		fprintf(stderr, "mode string parse error\n");
> +		goto error;
> +	}
> +
> +	/* Third token: minimum threshold */
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, "Minimum threshold parse error\n");
> +		goto error;
> +	}
> +
> +	ret = parse_uint(&min_th, token);
> +	if (ret != 0 || min_th > UINT8_MAX) {
> +		fprintf(stderr, "Minimum threshold is invalid\n");
> +		goto error;
> +	}
> +
> +	/* Fourth token: maximum threshold */
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, "Maximum threshold parse error\n");
> +		goto error;
> +	}
> +
> +	ret = parse_uint(&max_th, token);
> +	if (ret != 0 || max_th > UINT8_MAX) {
> +		fprintf(stderr, "Maximum threshold is invalid\n");
> +		goto error;
> +	}
> +
> +	/* Fifth token: probability inversion */
> +	token = strtok_r(str, PARSE_DELIMITER, &str);
> +	if (token == NULL) {
> +		fprintf(stderr, "Maximum probability inversion parse
> error\n");
> +		goto error;
> +	}
> +
> +	ret = parse_uint(&maxp_inv, token);
> +	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
> +		fprintf(stderr, "Maximum probability inversion is invalid\n");
> +		goto error;
> +	}
> +
> +	memset(&info, 0, sizeof(struct rte_eth_cman_info));
> +	ret = rte_eth_cman_info_get(port_id, &info);
> +	if (ret) {
> +		fprintf(stderr, "Congestion management capa get error\n");
> +		goto error;
> +	}
> +
> +	if (!(info.objs_supported & obj)) {
> +		fprintf(stderr, "Object type is not supported by driver\n");
> +		goto error;
> +	}
> +
> +	if (!(info.modes_supported & mode)) {
> +		fprintf(stderr, "Mode is not supported by driver\n");
> +		goto error;
> +	}
> +
> +	cfg->obj = obj;
> +	cfg->mode = mode;
> +	cfg->mode_param.red.min_th = min_th;
> +	cfg->mode_param.red.max_th = max_th;
> +	cfg->mode_param.red.maxp_inv = maxp_inv;
> +
> +	return 0;
> +
> +error:
> +	return -EINVAL;
> +}
> +
> +/* *** Show Port Congestion Management Capabilities *** */ struct
> +cmd_show_port_cman_capa_result {
> +	cmdline_fixed_string_t show;
> +	cmdline_fixed_string_t port;
> +	cmdline_fixed_string_t cman;
> +	cmdline_fixed_string_t capa;
> +	uint16_t port_id;
> +};
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_capa_result, show, "show");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_capa_result, port, "port");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_capa_result, cman, "cman");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_capa_result, capa, "capa");
> +
> +static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
> +	TOKEN_NUM_INITIALIZER(
> +		struct cmd_show_port_cman_capa_result, port_id,
> RTE_UINT16);
> +
> +static void cmd_show_port_cman_capa_parsed(void *parsed_result,
> +	__rte_unused struct cmdline *cl,
> +	__rte_unused void *data)
> +{
> +	struct cmd_show_port_cman_capa_result *res = parsed_result;
> +	uint16_t port_id = res->port_id;
> +	struct rte_eth_cman_info info;
> +	int ret;
> +
> +	memset(&info, 0, sizeof(struct rte_eth_cman_info));
> +	ret = rte_eth_cman_info_get(port_id, &info);
> +	if (ret)
> +		return;
> +
> +	printf("\n****   Port Congestion Management Capabilities
> ****\n\n");
> +	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
> +	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported); }
> +
> +cmdline_parse_inst_t cmd_show_port_cman_capa = {
> +	.f = cmd_show_port_cman_capa_parsed,
> +	.data = NULL,
> +	.help_str = "show port cman capa <port_id>",
> +	.tokens = {
> +		(void *)&cmd_show_port_cman_capa_show,
> +		(void *)&cmd_show_port_cman_capa_port,
> +		(void *)&cmd_show_port_cman_capa_cman,
> +		(void *)&cmd_show_port_cman_capa_capa,
> +		(void *)&cmd_show_port_cman_capa_port_id,
> +		NULL,
> +	},
> +};
> +
> +/* *** Show Port Congestion Management configuration *** */ struct
> +cmd_show_port_cman_cfg_result {
> +	cmdline_fixed_string_t show;
> +	cmdline_fixed_string_t port;
> +	cmdline_fixed_string_t cman;
> +	cmdline_fixed_string_t cfg;
> +	uint16_t port_id;
> +};
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_cfg_result, show, "show");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_cfg_result, port, "port");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_cfg_result, cman, "cman");
> +
> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_show_port_cman_cfg_result, cfg, "config");
> +
> +static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
> +	TOKEN_NUM_INITIALIZER(
> +		struct cmd_show_port_cman_cfg_result, port_id,
> RTE_UINT16);
> +
> +static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
> +	__rte_unused struct cmdline *cl,
> +	__rte_unused void *data)
> +{
> +	struct cmd_show_port_cman_cfg_result *res = parsed_result;
> +	uint16_t port_id = res->port_id;
> +	struct rte_eth_cman_config cfg;
> +	int ret;
> +
> +	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
> +	ret = rte_eth_cman_config_get(port_id, &cfg);
> +	if (ret)
> +		return;
> +
> +	printf("\n****   Port Congestion Management Configuration
> ****\n\n");
> +	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
> +	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
> +	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
> +	printf("cman RED min thresh %" PRIx8 "\n",
> cfg.mode_param.red.min_th);
> +	printf("cman RED max thresh %" PRIx8 "\n",
> cfg.mode_param.red.max_th);
> +	printf("cman RED Prob inversion %" PRIx16 "\n",
> +		cfg.mode_param.red.maxp_inv);
> +}
> +
> +cmdline_parse_inst_t cmd_show_port_cman_config = {
> +	.f = cmd_show_port_cman_cfg_parsed,
> +	.data = NULL,
> +	.help_str = "show port cman config <port_id>",
> +	.tokens = {
> +		(void *)&cmd_show_port_cman_cfg_show,
> +		(void *)&cmd_show_port_cman_cfg_port,
> +		(void *)&cmd_show_port_cman_cfg_cman,
> +		(void *)&cmd_show_port_cman_cfg_cfg,
> +		(void *)&cmd_show_port_cman_cfg_port_id,
> +		NULL,
> +	},
> +};
> +
> +/* *** Set Port Congestion Management configuration *** */ struct
> +cmd_set_port_cman_cfg_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t port;
> +	cmdline_fixed_string_t cman;
> +	cmdline_fixed_string_t cfg;
> +	uint16_t port_id;
> +	uint16_t qid;
> +	cmdline_multi_string_t params;
> +};
> +
> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, set, "set");
> +
> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, port, "port");
> +
> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, cman, "cman");
> +
> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
> +	TOKEN_STRING_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, cfg, "config");
> +
> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
> +	TOKEN_NUM_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
> +
> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
> +	TOKEN_NUM_INITIALIZER(
> +		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
> +
> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
> +		params, TOKEN_STRING_MULTI);
> +
> +static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
> +	__rte_unused struct cmdline *cl,
> +	__rte_unused void *data)
> +{
> +	struct cmd_set_port_cman_cfg_result *res = parsed_result;
> +	uint16_t port_id = res->port_id;
> +	struct rte_eth_cman_config cfg;
> +	int ret;
> +
> +	ret = parse_cman_params_str(port_id, res->params, &cfg);
> +	if (ret) {
> +		fprintf(stderr, "params string parse error\n");
> +		return;
> +	}
> +
> +	cfg.obj_param.rx_queue = res->qid;
> +	rte_eth_cman_config_set(port_id, &cfg); }
> +
> +cmdline_parse_inst_t cmd_set_port_cman_config = {
> +	.f = cmd_set_port_cman_cfg_parsed,
> +	.data = NULL,
> +	.help_str = "set port cman config <port_id> <queue_id> "
> +		    "default | [obj <queue|queue_mempool> mode red "
> +		    "<min_thresh> <max_thresh> <prob_inv>]",
> +	.tokens = {
> +		(void *)&cmd_set_port_cman_cfg_set,
> +		(void *)&cmd_set_port_cman_cfg_port,
> +		(void *)&cmd_set_port_cman_cfg_cman,
> +		(void *)&cmd_set_port_cman_cfg_cfg,
> +		(void *)&cmd_set_port_cman_cfg_port_id,
> +		(void *)&cmd_set_port_cman_cfg_qid,
> +		(void *)&cmd_set_port_cman_cfg_params,
> +		NULL,
> +	},
> +};
> diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
> new file mode 100644 index 0000000000..bd6c99ce35
> --- /dev/null
> +++ b/app/test-pmd/cmdline_cman.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2022 Marvell International Ltd.
> + */
> +
> +#ifndef _CMDLINE_CMAN_H_
> +#define _CMDLINE_CMAN_H_
> +
> +extern cmdline_parse_inst_t cmd_show_port_cman_capa; extern
> +cmdline_parse_inst_t cmd_show_port_cman_config; extern
> +cmdline_parse_inst_t cmd_set_port_cman_config;
> +
> +#endif /* _CMDLINE_CMAN_H_ */
> diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index
> 74399178dd..c03d9dfebb 100644
> --- a/app/test-pmd/meson.build
> +++ b/app/test-pmd/meson.build
> @@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
>  sources = files(
>          '5tswap.c',
>          'cmdline.c',
> +        'cmdline_cman.c',
>          'cmdline_flow.c',
>          'cmdline_mtr.c',
>          'cmdline_tm.c',
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index d3075bf87d..b9c7b468af 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports.
>     testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3
> pattern is 2 / end actions mark id 1 / queue index 0 / end
>     Flow rule #0 created
> 
> +Congestion Management
> +---------------------
> +
> +Get capabilities
> +~~~~~~~~~~~~~~~~
> +
> +Retrieve congestion management capabilities supported by driver for given
> port.
> +Below example command retrieves capabilities for port 0::
> +
> +   testpmd> show port cman capa 0
> +
> +Get configuration
> +~~~~~~~~~~~~~~~~~
> +Retrieve congestion management configuration for given port. Below
> +example command retrieves configuration for port 0::
> +
> +   testpmd> show port cman config 0
> +
> +Set configuration
> +~~~~~~~~~~~~~~~~~
> +Configures congestion management settings on given queue or mempool
> +associated with queue. Below example command configures RED as
> +congestion management algo for port 0 and queue 0::
> +
> +   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
> +
>  Driver specific commands
>  ------------------------
> 
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
  2022-10-12  9:01     ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs Sunil Kumar Kori
@ 2022-11-06 10:08       ` Andrew Rybchenko
  2022-11-07  7:12         ` Singh, Aman Deep
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Rybchenko @ 2022-11-06 10:08 UTC (permalink / raw)
  To: Aman Singh, Yuying Zhang; +Cc: dev, Sunil Kumar Kori

@Aman, @Yuying, please, help to review the patch.

On 10/12/22 12:01, Sunil Kumar Kori wrote:
> Please review the following changes and provide feedback.
> 
> Regards
> Sunil Kumar Kori
> 
>> -----Original Message-----
>> From: skori@marvell.com <skori@marvell.com>
>> Sent: Thursday, September 29, 2022 3:25 PM
>> To: Aman Singh <aman.deep.singh@intel.com>; Yuying Zhang
>> <yuying.zhang@intel.com>
>> Cc: dev@dpdk.org; Sunil Kumar Kori <skori@marvell.com>
>> Subject: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
>>
>> From: Sunil Kumar Kori <skori@marvell.com>
>>
>> Support congestion management CLIs.
>>
>> Depends-on: patch-24902 ("ethdev: support congestion management")
>>
>> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
>> ---
>> v1..v2:
>>   - Rebase on top of the dpdk-next-net-mrvl/for-next-net
>>
>>   app/test-pmd/cmdline.c                      |  15 +
>>   app/test-pmd/cmdline_cman.c                 | 390 ++++++++++++++++++++
>>   app/test-pmd/cmdline_cman.h                 |  12 +
>>   app/test-pmd/meson.build                    |   1 +
>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
>>   5 files changed, 444 insertions(+)
>>   create mode 100644 app/test-pmd/cmdline_cman.c  create mode 100644
>> app/test-pmd/cmdline_cman.h
>>
>> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
>> 51321de9ed..ce278eadb0 100644
>> --- a/app/test-pmd/cmdline.c
>> +++ b/app/test-pmd/cmdline.c
>> @@ -60,6 +60,7 @@
>>   #include <rte_pmd_bnxt.h>
>>   #endif
>>   #include "testpmd.h"
>> +#include "cmdline_cman.h"
>>   #include "cmdline_mtr.h"
>>   #include "cmdline_tm.h"
>>   #include "bpf_cmd.h"
>> @@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void
>> *parsed_result,
>>   			"set port (port_id) fec_mode auto|off|rs|baser\n"
>>   			"    set fec mode for a specific port\n\n"
>>
>> +			"show port cman capa (port_id)\n"
>> +			"    Show congestion management capabilities\n\n"
>> +
>> +			"show port cman config (port_id)\n"
>> +			"    Show congestion management configuration\n\n"
>> +
>> +			"set port cman config (port_id) (queue_id) default | "
>> +			"[obj (queue|queue_mempool) mode red
>> (min_thresh) "
>> +			"(max_thresh) (prob_inv)]\n"
>> +			"    Set congestion management configuration\n\n"
>> +
>>   			, list_pkt_forwarding_modes()
>>   		);
>>   	}
>> @@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
>>   	(cmdline_parse_inst_t *)&cmd_show_capability,
>>   	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
>>   	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
>> +	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
>> +	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
>> +	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
>>   	NULL,
>>   };
>>
>> diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
>> new file mode 100644 index 0000000000..344759189d
>> --- /dev/null
>> +++ b/app/test-pmd/cmdline_cman.c
>> @@ -0,0 +1,390 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(C) 2022 Marvell International Ltd.
>> + */
>> +
>> +#include <cmdline_parse.h>
>> +#include <cmdline_parse_num.h>
>> +#include <cmdline_parse_string.h>
>> +
>> +#include <rte_ethdev.h>
>> +
>> +#include "testpmd.h"
>> +
>> +#define PARSE_DELIMITER				" \f\n\r\t\v"
>> +
>> +static int
>> +parse_uint(uint64_t *value, const char *str) {
>> +	char *next = NULL;
>> +	uint64_t n;
>> +
>> +	errno = 0;
>> +	/* Parse number string */
>> +	n = strtol(str, &next, 10);
>> +	if (errno != 0 || str == next || *next != '\0')
>> +		return -1;
>> +
>> +	*value = n;
>> +
>> +	return 0;
>> +}
>> +
>> +static int
>> +parse_cman_obj_str(char *str, uint64_t *obj) {
>> +	char *token;
>> +
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL)
>> +		return 0;
>> +
>> +	if (strcasecmp(token, "queue") == 0)
>> +		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
>> +	else if (strcasecmp(token, "queue_mempool") == 0)
>> +		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
>> +	else
>> +		return -1;
>> +
>> +	return 0;
>> +}
>> +
>> +static int
>> +parse_cman_mode_str(char *str, uint64_t *mode) {
>> +	char *token;
>> +
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL)
>> +		return 0;
>> +
>> +	if (strcasecmp(token, "red") == 0)
>> +		*mode = RTE_CMAN_RED;
>> +	else
>> +		return -1;
>> +
>> +	return 0;
>> +}
>> +
>> +static int
>> +parse_cman_params_str(uint16_t port_id, char *str,
>> +		      struct rte_eth_cman_config *cfg) {
>> +	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
>> +	struct rte_eth_cman_info info;
>> +	char *token;
>> +	int ret;
>> +
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (!strcasecmp(token, "default")) {
>> +		ret = rte_eth_cman_config_init(port_id, cfg);
>> +		if (ret) {
>> +			fprintf(stderr, "error in default initialization\n");
>> +			return ret;
>> +		}
>> +		return 0;
>> +	}
>> +
>> +	/* First token: obj name */
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, "Object param parse error\n");
>> +		goto error;
>> +	}
>> +
>> +	ret = parse_cman_obj_str(token, &obj);
>> +	if (ret) {
>> +		fprintf(stderr, "Object value is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	/* Second token: mode name */
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, " Mode param is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, " Mode value is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	ret = parse_cman_mode_str(token, &mode);
>> +	if (ret) {
>> +		fprintf(stderr, "mode string parse error\n");
>> +		goto error;
>> +	}
>> +
>> +	/* Third token: minimum threshold */
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, "Minimum threshold parse error\n");
>> +		goto error;
>> +	}
>> +
>> +	ret = parse_uint(&min_th, token);
>> +	if (ret != 0 || min_th > UINT8_MAX) {
>> +		fprintf(stderr, "Minimum threshold is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	/* Fourth token: maximum threshold */
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, "Maximum threshold parse error\n");
>> +		goto error;
>> +	}
>> +
>> +	ret = parse_uint(&max_th, token);
>> +	if (ret != 0 || max_th > UINT8_MAX) {
>> +		fprintf(stderr, "Maximum threshold is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	/* Fifth token: probability inversion */
>> +	token = strtok_r(str, PARSE_DELIMITER, &str);
>> +	if (token == NULL) {
>> +		fprintf(stderr, "Maximum probability inversion parse
>> error\n");
>> +		goto error;
>> +	}
>> +
>> +	ret = parse_uint(&maxp_inv, token);
>> +	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
>> +		fprintf(stderr, "Maximum probability inversion is invalid\n");
>> +		goto error;
>> +	}
>> +
>> +	memset(&info, 0, sizeof(struct rte_eth_cman_info));
>> +	ret = rte_eth_cman_info_get(port_id, &info);
>> +	if (ret) {
>> +		fprintf(stderr, "Congestion management capa get error\n");
>> +		goto error;
>> +	}
>> +
>> +	if (!(info.objs_supported & obj)) {
>> +		fprintf(stderr, "Object type is not supported by driver\n");
>> +		goto error;
>> +	}
>> +
>> +	if (!(info.modes_supported & mode)) {
>> +		fprintf(stderr, "Mode is not supported by driver\n");
>> +		goto error;
>> +	}
>> +
>> +	cfg->obj = obj;
>> +	cfg->mode = mode;
>> +	cfg->mode_param.red.min_th = min_th;
>> +	cfg->mode_param.red.max_th = max_th;
>> +	cfg->mode_param.red.maxp_inv = maxp_inv;
>> +
>> +	return 0;
>> +
>> +error:
>> +	return -EINVAL;
>> +}
>> +
>> +/* *** Show Port Congestion Management Capabilities *** */ struct
>> +cmd_show_port_cman_capa_result {
>> +	cmdline_fixed_string_t show;
>> +	cmdline_fixed_string_t port;
>> +	cmdline_fixed_string_t cman;
>> +	cmdline_fixed_string_t capa;
>> +	uint16_t port_id;
>> +};
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_capa_result, show, "show");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_capa_result, port, "port");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_capa_result, cman, "cman");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_capa_result, capa, "capa");
>> +
>> +static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
>> +	TOKEN_NUM_INITIALIZER(
>> +		struct cmd_show_port_cman_capa_result, port_id,
>> RTE_UINT16);
>> +
>> +static void cmd_show_port_cman_capa_parsed(void *parsed_result,
>> +	__rte_unused struct cmdline *cl,
>> +	__rte_unused void *data)
>> +{
>> +	struct cmd_show_port_cman_capa_result *res = parsed_result;
>> +	uint16_t port_id = res->port_id;
>> +	struct rte_eth_cman_info info;
>> +	int ret;
>> +
>> +	memset(&info, 0, sizeof(struct rte_eth_cman_info));
>> +	ret = rte_eth_cman_info_get(port_id, &info);
>> +	if (ret)
>> +		return;
>> +
>> +	printf("\n****   Port Congestion Management Capabilities
>> ****\n\n");
>> +	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
>> +	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported); }
>> +
>> +cmdline_parse_inst_t cmd_show_port_cman_capa = {
>> +	.f = cmd_show_port_cman_capa_parsed,
>> +	.data = NULL,
>> +	.help_str = "show port cman capa <port_id>",
>> +	.tokens = {
>> +		(void *)&cmd_show_port_cman_capa_show,
>> +		(void *)&cmd_show_port_cman_capa_port,
>> +		(void *)&cmd_show_port_cman_capa_cman,
>> +		(void *)&cmd_show_port_cman_capa_capa,
>> +		(void *)&cmd_show_port_cman_capa_port_id,
>> +		NULL,
>> +	},
>> +};
>> +
>> +/* *** Show Port Congestion Management configuration *** */ struct
>> +cmd_show_port_cman_cfg_result {
>> +	cmdline_fixed_string_t show;
>> +	cmdline_fixed_string_t port;
>> +	cmdline_fixed_string_t cman;
>> +	cmdline_fixed_string_t cfg;
>> +	uint16_t port_id;
>> +};
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_cfg_result, show, "show");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_cfg_result, port, "port");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_cfg_result, cman, "cman");
>> +
>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_show_port_cman_cfg_result, cfg, "config");
>> +
>> +static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
>> +	TOKEN_NUM_INITIALIZER(
>> +		struct cmd_show_port_cman_cfg_result, port_id,
>> RTE_UINT16);
>> +
>> +static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
>> +	__rte_unused struct cmdline *cl,
>> +	__rte_unused void *data)
>> +{
>> +	struct cmd_show_port_cman_cfg_result *res = parsed_result;
>> +	uint16_t port_id = res->port_id;
>> +	struct rte_eth_cman_config cfg;
>> +	int ret;
>> +
>> +	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
>> +	ret = rte_eth_cman_config_get(port_id, &cfg);
>> +	if (ret)
>> +		return;
>> +
>> +	printf("\n****   Port Congestion Management Configuration
>> ****\n\n");
>> +	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
>> +	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
>> +	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
>> +	printf("cman RED min thresh %" PRIx8 "\n",
>> cfg.mode_param.red.min_th);
>> +	printf("cman RED max thresh %" PRIx8 "\n",
>> cfg.mode_param.red.max_th);
>> +	printf("cman RED Prob inversion %" PRIx16 "\n",
>> +		cfg.mode_param.red.maxp_inv);
>> +}
>> +
>> +cmdline_parse_inst_t cmd_show_port_cman_config = {
>> +	.f = cmd_show_port_cman_cfg_parsed,
>> +	.data = NULL,
>> +	.help_str = "show port cman config <port_id>",
>> +	.tokens = {
>> +		(void *)&cmd_show_port_cman_cfg_show,
>> +		(void *)&cmd_show_port_cman_cfg_port,
>> +		(void *)&cmd_show_port_cman_cfg_cman,
>> +		(void *)&cmd_show_port_cman_cfg_cfg,
>> +		(void *)&cmd_show_port_cman_cfg_port_id,
>> +		NULL,
>> +	},
>> +};
>> +
>> +/* *** Set Port Congestion Management configuration *** */ struct
>> +cmd_set_port_cman_cfg_result {
>> +	cmdline_fixed_string_t set;
>> +	cmdline_fixed_string_t port;
>> +	cmdline_fixed_string_t cman;
>> +	cmdline_fixed_string_t cfg;
>> +	uint16_t port_id;
>> +	uint16_t qid;
>> +	cmdline_multi_string_t params;
>> +};
>> +
>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, set, "set");
>> +
>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, port, "port");
>> +
>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, cman, "cman");
>> +
>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
>> +	TOKEN_STRING_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, cfg, "config");
>> +
>> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
>> +	TOKEN_NUM_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
>> +
>> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
>> +	TOKEN_NUM_INITIALIZER(
>> +		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
>> +
>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
>> +	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
>> +		params, TOKEN_STRING_MULTI);
>> +
>> +static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
>> +	__rte_unused struct cmdline *cl,
>> +	__rte_unused void *data)
>> +{
>> +	struct cmd_set_port_cman_cfg_result *res = parsed_result;
>> +	uint16_t port_id = res->port_id;
>> +	struct rte_eth_cman_config cfg;
>> +	int ret;
>> +
>> +	ret = parse_cman_params_str(port_id, res->params, &cfg);
>> +	if (ret) {
>> +		fprintf(stderr, "params string parse error\n");
>> +		return;
>> +	}
>> +
>> +	cfg.obj_param.rx_queue = res->qid;
>> +	rte_eth_cman_config_set(port_id, &cfg); }
>> +
>> +cmdline_parse_inst_t cmd_set_port_cman_config = {
>> +	.f = cmd_set_port_cman_cfg_parsed,
>> +	.data = NULL,
>> +	.help_str = "set port cman config <port_id> <queue_id> "
>> +		    "default | [obj <queue|queue_mempool> mode red "
>> +		    "<min_thresh> <max_thresh> <prob_inv>]",
>> +	.tokens = {
>> +		(void *)&cmd_set_port_cman_cfg_set,
>> +		(void *)&cmd_set_port_cman_cfg_port,
>> +		(void *)&cmd_set_port_cman_cfg_cman,
>> +		(void *)&cmd_set_port_cman_cfg_cfg,
>> +		(void *)&cmd_set_port_cman_cfg_port_id,
>> +		(void *)&cmd_set_port_cman_cfg_qid,
>> +		(void *)&cmd_set_port_cman_cfg_params,
>> +		NULL,
>> +	},
>> +};
>> diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
>> new file mode 100644 index 0000000000..bd6c99ce35
>> --- /dev/null
>> +++ b/app/test-pmd/cmdline_cman.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(C) 2022 Marvell International Ltd.
>> + */
>> +
>> +#ifndef _CMDLINE_CMAN_H_
>> +#define _CMDLINE_CMAN_H_
>> +
>> +extern cmdline_parse_inst_t cmd_show_port_cman_capa; extern
>> +cmdline_parse_inst_t cmd_show_port_cman_config; extern
>> +cmdline_parse_inst_t cmd_set_port_cman_config;
>> +
>> +#endif /* _CMDLINE_CMAN_H_ */
>> diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index
>> 74399178dd..c03d9dfebb 100644
>> --- a/app/test-pmd/meson.build
>> +++ b/app/test-pmd/meson.build
>> @@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
>>   sources = files(
>>           '5tswap.c',
>>           'cmdline.c',
>> +        'cmdline_cman.c',
>>           'cmdline_flow.c',
>>           'cmdline_mtr.c',
>>           'cmdline_tm.c',
>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> index d3075bf87d..b9c7b468af 100644
>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> @@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports.
>>      testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3
>> pattern is 2 / end actions mark id 1 / queue index 0 / end
>>      Flow rule #0 created
>>
>> +Congestion Management
>> +---------------------
>> +
>> +Get capabilities
>> +~~~~~~~~~~~~~~~~
>> +
>> +Retrieve congestion management capabilities supported by driver for given
>> port.
>> +Below example command retrieves capabilities for port 0::
>> +
>> +   testpmd> show port cman capa 0
>> +
>> +Get configuration
>> +~~~~~~~~~~~~~~~~~
>> +Retrieve congestion management configuration for given port. Below
>> +example command retrieves configuration for port 0::
>> +
>> +   testpmd> show port cman config 0
>> +
>> +Set configuration
>> +~~~~~~~~~~~~~~~~~
>> +Configures congestion management settings on given queue or mempool
>> +associated with queue. Below example command configures RED as
>> +congestion management algo for port 0 and queue 0::
>> +
>> +   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
>> +
>>   Driver specific commands
>>   ------------------------
>>
>> --
>> 2.25.1
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
  2022-11-06 10:08       ` Andrew Rybchenko
@ 2022-11-07  7:12         ` Singh, Aman Deep
  2022-11-29  7:54           ` [EXT] " Sunil Kumar Kori
  0 siblings, 1 reply; 17+ messages in thread
From: Singh, Aman Deep @ 2022-11-07  7:12 UTC (permalink / raw)
  To: Andrew Rybchenko, Yuying Zhang, Cristian Dumitrescu; +Cc: dev, Sunil Kumar Kori

These newly added files for Congestion Management look in-line to 
Traffic Metering part,
would like @Cristian to also have a look.

Regards
Aman

On 11/6/2022 3:38 PM, Andrew Rybchenko wrote:
> @Aman, @Yuying, please, help to review the patch.
>
> On 10/12/22 12:01, Sunil Kumar Kori wrote:
>> Please review the following changes and provide feedback.
>>
>> Regards
>> Sunil Kumar Kori
>>
>>> -----Original Message-----
>>> From: skori@marvell.com <skori@marvell.com>
>>> Sent: Thursday, September 29, 2022 3:25 PM
>>> To: Aman Singh <aman.deep.singh@intel.com>; Yuying Zhang
>>> <yuying.zhang@intel.com>
>>> Cc: dev@dpdk.org; Sunil Kumar Kori <skori@marvell.com>
>>> Subject: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
>>>
>>> From: Sunil Kumar Kori <skori@marvell.com>
>>>
>>> Support congestion management CLIs.
>>>
>>> Depends-on: patch-24902 ("ethdev: support congestion management")
>>>
>>> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: Aman Singh <aman.deep.singh@intel.com>
>>> ---
>>> v1..v2:
>>>   - Rebase on top of the dpdk-next-net-mrvl/for-next-net
>>>
>>>   app/test-pmd/cmdline.c                      |  15 +
>>>   app/test-pmd/cmdline_cman.c                 | 390 
>>> ++++++++++++++++++++
>>>   app/test-pmd/cmdline_cman.h                 |  12 +
>>>   app/test-pmd/meson.build                    |   1 +
>>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
>>>   5 files changed, 444 insertions(+)
>>>   create mode 100644 app/test-pmd/cmdline_cman.c  create mode 100644
>>> app/test-pmd/cmdline_cman.h
>>>
>>> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
>>> 51321de9ed..ce278eadb0 100644
>>> --- a/app/test-pmd/cmdline.c
>>> +++ b/app/test-pmd/cmdline.c
>>> @@ -60,6 +60,7 @@
>>>   #include <rte_pmd_bnxt.h>
>>>   #endif
>>>   #include "testpmd.h"
>>> +#include "cmdline_cman.h"
>>>   #include "cmdline_mtr.h"
>>>   #include "cmdline_tm.h"
>>>   #include "bpf_cmd.h"
>>> @@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void
>>> *parsed_result,
>>>               "set port (port_id) fec_mode auto|off|rs|baser\n"
>>>               "    set fec mode for a specific port\n\n"
>>>
>>> +            "show port cman capa (port_id)\n"
>>> +            "    Show congestion management capabilities\n\n"
>>> +
>>> +            "show port cman config (port_id)\n"
>>> +            "    Show congestion management configuration\n\n"
>>> +
>>> +            "set port cman config (port_id) (queue_id) default | "
>>> +            "[obj (queue|queue_mempool) mode red
>>> (min_thresh) "
>>> +            "(max_thresh) (prob_inv)]\n"
>>> +            "    Set congestion management configuration\n\n"
>>> +
>>>               , list_pkt_forwarding_modes()
>>>           );
>>>       }
>>> @@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
>>>       (cmdline_parse_inst_t *)&cmd_show_capability,
>>>       (cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
>>>       (cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
>>> +    (cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
>>> +    (cmdline_parse_inst_t *)&cmd_show_port_cman_config,
>>> +    (cmdline_parse_inst_t *)&cmd_set_port_cman_config,
>>>       NULL,
>>>   };
>>>
>>> diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
>>> new file mode 100644 index 0000000000..344759189d
>>> --- /dev/null
>>> +++ b/app/test-pmd/cmdline_cman.c
>>> @@ -0,0 +1,390 @@
>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>> + * Copyright(C) 2022 Marvell International Ltd.
>>> + */
>>> +
>>> +#include <cmdline_parse.h>
>>> +#include <cmdline_parse_num.h>
>>> +#include <cmdline_parse_string.h>
>>> +
>>> +#include <rte_ethdev.h>
>>> +
>>> +#include "testpmd.h"
>>> +
>>> +#define PARSE_DELIMITER                " \f\n\r\t\v"
>>> +
>>> +static int
>>> +parse_uint(uint64_t *value, const char *str) {
>>> +    char *next = NULL;
>>> +    uint64_t n;
>>> +
>>> +    errno = 0;
>>> +    /* Parse number string */
>>> +    n = strtol(str, &next, 10);
>>> +    if (errno != 0 || str == next || *next != '\0')
>>> +        return -1;
>>> +
>>> +    *value = n;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int
>>> +parse_cman_obj_str(char *str, uint64_t *obj) {
>>> +    char *token;
>>> +
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL)
>>> +        return 0;
>>> +
>>> +    if (strcasecmp(token, "queue") == 0)
>>> +        *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
>>> +    else if (strcasecmp(token, "queue_mempool") == 0)
>>> +        *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
>>> +    else
>>> +        return -1;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int
>>> +parse_cman_mode_str(char *str, uint64_t *mode) {
>>> +    char *token;
>>> +
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL)
>>> +        return 0;
>>> +
>>> +    if (strcasecmp(token, "red") == 0)
>>> +        *mode = RTE_CMAN_RED;
>>> +    else
>>> +        return -1;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int
>>> +parse_cman_params_str(uint16_t port_id, char *str,
>>> +              struct rte_eth_cman_config *cfg) {
>>> +    uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
>>> +    struct rte_eth_cman_info info;
>>> +    char *token;
>>> +    int ret;
>>> +
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (!strcasecmp(token, "default")) {
>>> +        ret = rte_eth_cman_config_init(port_id, cfg);
>>> +        if (ret) {
>>> +            fprintf(stderr, "error in default initialization\n");
>>> +            return ret;
>>> +        }
>>> +        return 0;
>>> +    }
>>> +
>>> +    /* First token: obj name */
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, "Object param parse error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    ret = parse_cman_obj_str(token, &obj);
>>> +    if (ret) {
>>> +        fprintf(stderr, "Object value is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    /* Second token: mode name */
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, " Mode param is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, " Mode value is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    ret = parse_cman_mode_str(token, &mode);
>>> +    if (ret) {
>>> +        fprintf(stderr, "mode string parse error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    /* Third token: minimum threshold */
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, "Minimum threshold parse error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    ret = parse_uint(&min_th, token);
>>> +    if (ret != 0 || min_th > UINT8_MAX) {
>>> +        fprintf(stderr, "Minimum threshold is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    /* Fourth token: maximum threshold */
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, "Maximum threshold parse error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    ret = parse_uint(&max_th, token);
>>> +    if (ret != 0 || max_th > UINT8_MAX) {
>>> +        fprintf(stderr, "Maximum threshold is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    /* Fifth token: probability inversion */
>>> +    token = strtok_r(str, PARSE_DELIMITER, &str);
>>> +    if (token == NULL) {
>>> +        fprintf(stderr, "Maximum probability inversion parse
>>> error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    ret = parse_uint(&maxp_inv, token);
>>> +    if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
>>> +        fprintf(stderr, "Maximum probability inversion is invalid\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    memset(&info, 0, sizeof(struct rte_eth_cman_info));
>>> +    ret = rte_eth_cman_info_get(port_id, &info);
>>> +    if (ret) {
>>> +        fprintf(stderr, "Congestion management capa get error\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    if (!(info.objs_supported & obj)) {
>>> +        fprintf(stderr, "Object type is not supported by driver\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    if (!(info.modes_supported & mode)) {
>>> +        fprintf(stderr, "Mode is not supported by driver\n");
>>> +        goto error;
>>> +    }
>>> +
>>> +    cfg->obj = obj;
>>> +    cfg->mode = mode;
>>> +    cfg->mode_param.red.min_th = min_th;
>>> +    cfg->mode_param.red.max_th = max_th;
>>> +    cfg->mode_param.red.maxp_inv = maxp_inv;
>>> +
>>> +    return 0;
>>> +
>>> +error:
>>> +    return -EINVAL;
>>> +}
>>> +
>>> +/* *** Show Port Congestion Management Capabilities *** */ struct
>>> +cmd_show_port_cman_capa_result {
>>> +    cmdline_fixed_string_t show;
>>> +    cmdline_fixed_string_t port;
>>> +    cmdline_fixed_string_t cman;
>>> +    cmdline_fixed_string_t capa;
>>> +    uint16_t port_id;
>>> +};
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_capa_result, show, "show");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_capa_result, port, "port");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_capa_result, cman, "cman");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_capa_result, capa, "capa");
>>> +
>>> +static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
>>> +    TOKEN_NUM_INITIALIZER(
>>> +        struct cmd_show_port_cman_capa_result, port_id,
>>> RTE_UINT16);
>>> +
>>> +static void cmd_show_port_cman_capa_parsed(void *parsed_result,
>>> +    __rte_unused struct cmdline *cl,
>>> +    __rte_unused void *data)
>>> +{
>>> +    struct cmd_show_port_cman_capa_result *res = parsed_result;
>>> +    uint16_t port_id = res->port_id;
>>> +    struct rte_eth_cman_info info;
>>> +    int ret;
>>> +
>>> +    memset(&info, 0, sizeof(struct rte_eth_cman_info));
>>> +    ret = rte_eth_cman_info_get(port_id, &info);
>>> +    if (ret)
>>> +        return;
>>> +
>>> +    printf("\n****   Port Congestion Management Capabilities
>>> ****\n\n");
>>> +    printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
>>> +    printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported); }
>>> +
>>> +cmdline_parse_inst_t cmd_show_port_cman_capa = {
>>> +    .f = cmd_show_port_cman_capa_parsed,
>>> +    .data = NULL,
>>> +    .help_str = "show port cman capa <port_id>",
>>> +    .tokens = {
>>> +        (void *)&cmd_show_port_cman_capa_show,
>>> +        (void *)&cmd_show_port_cman_capa_port,
>>> +        (void *)&cmd_show_port_cman_capa_cman,
>>> +        (void *)&cmd_show_port_cman_capa_capa,
>>> +        (void *)&cmd_show_port_cman_capa_port_id,
>>> +        NULL,
>>> +    },
>>> +};
>>> +
>>> +/* *** Show Port Congestion Management configuration *** */ struct
>>> +cmd_show_port_cman_cfg_result {
>>> +    cmdline_fixed_string_t show;
>>> +    cmdline_fixed_string_t port;
>>> +    cmdline_fixed_string_t cman;
>>> +    cmdline_fixed_string_t cfg;
>>> +    uint16_t port_id;
>>> +};
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_cfg_result, show, "show");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_cfg_result, port, "port");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_cfg_result, cman, "cman");
>>> +
>>> +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_show_port_cman_cfg_result, cfg, "config");
>>> +
>>> +static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
>>> +    TOKEN_NUM_INITIALIZER(
>>> +        struct cmd_show_port_cman_cfg_result, port_id,
>>> RTE_UINT16);
>>> +
>>> +static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
>>> +    __rte_unused struct cmdline *cl,
>>> +    __rte_unused void *data)
>>> +{
>>> +    struct cmd_show_port_cman_cfg_result *res = parsed_result;
>>> +    uint16_t port_id = res->port_id;
>>> +    struct rte_eth_cman_config cfg;
>>> +    int ret;
>>> +
>>> +    memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
>>> +    ret = rte_eth_cman_config_get(port_id, &cfg);
>>> +    if (ret)
>>> +        return;
>>> +
>>> +    printf("\n****   Port Congestion Management Configuration
>>> ****\n\n");
>>> +    printf("cman object 0x%" PRIx32 "\n", cfg.obj);
>>> +    printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
>>> +    printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
>>> +    printf("cman RED min thresh %" PRIx8 "\n",
>>> cfg.mode_param.red.min_th);
>>> +    printf("cman RED max thresh %" PRIx8 "\n",
>>> cfg.mode_param.red.max_th);
>>> +    printf("cman RED Prob inversion %" PRIx16 "\n",
>>> +        cfg.mode_param.red.maxp_inv);
>>> +}
>>> +
>>> +cmdline_parse_inst_t cmd_show_port_cman_config = {
>>> +    .f = cmd_show_port_cman_cfg_parsed,
>>> +    .data = NULL,
>>> +    .help_str = "show port cman config <port_id>",
>>> +    .tokens = {
>>> +        (void *)&cmd_show_port_cman_cfg_show,
>>> +        (void *)&cmd_show_port_cman_cfg_port,
>>> +        (void *)&cmd_show_port_cman_cfg_cman,
>>> +        (void *)&cmd_show_port_cman_cfg_cfg,
>>> +        (void *)&cmd_show_port_cman_cfg_port_id,
>>> +        NULL,
>>> +    },
>>> +};
>>> +
>>> +/* *** Set Port Congestion Management configuration *** */ struct
>>> +cmd_set_port_cman_cfg_result {
>>> +    cmdline_fixed_string_t set;
>>> +    cmdline_fixed_string_t port;
>>> +    cmdline_fixed_string_t cman;
>>> +    cmdline_fixed_string_t cfg;
>>> +    uint16_t port_id;
>>> +    uint16_t qid;
>>> +    cmdline_multi_string_t params;
>>> +};
>>> +
>>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, set, "set");
>>> +
>>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, port, "port");
>>> +
>>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, cman, "cman");
>>> +
>>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
>>> +    TOKEN_STRING_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, cfg, "config");
>>> +
>>> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
>>> +    TOKEN_NUM_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
>>> +
>>> +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
>>> +    TOKEN_NUM_INITIALIZER(
>>> +        struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
>>> +
>>> +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
>>> +    TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
>>> +        params, TOKEN_STRING_MULTI);
>>> +
>>> +static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
>>> +    __rte_unused struct cmdline *cl,
>>> +    __rte_unused void *data)
>>> +{
>>> +    struct cmd_set_port_cman_cfg_result *res = parsed_result;
>>> +    uint16_t port_id = res->port_id;
>>> +    struct rte_eth_cman_config cfg;
>>> +    int ret;
>>> +
>>> +    ret = parse_cman_params_str(port_id, res->params, &cfg);
>>> +    if (ret) {
>>> +        fprintf(stderr, "params string parse error\n");
>>> +        return;
>>> +    }
>>> +
>>> +    cfg.obj_param.rx_queue = res->qid;
>>> +    rte_eth_cman_config_set(port_id, &cfg); }
>>> +
>>> +cmdline_parse_inst_t cmd_set_port_cman_config = {
>>> +    .f = cmd_set_port_cman_cfg_parsed,
>>> +    .data = NULL,
>>> +    .help_str = "set port cman config <port_id> <queue_id> "
>>> +            "default | [obj <queue|queue_mempool> mode red "
>>> +            "<min_thresh> <max_thresh> <prob_inv>]",
>>> +    .tokens = {
>>> +        (void *)&cmd_set_port_cman_cfg_set,
>>> +        (void *)&cmd_set_port_cman_cfg_port,
>>> +        (void *)&cmd_set_port_cman_cfg_cman,
>>> +        (void *)&cmd_set_port_cman_cfg_cfg,
>>> +        (void *)&cmd_set_port_cman_cfg_port_id,
>>> +        (void *)&cmd_set_port_cman_cfg_qid,
>>> +        (void *)&cmd_set_port_cman_cfg_params,
>>> +        NULL,
>>> +    },
>>> +};
>>> diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
>>> new file mode 100644 index 0000000000..bd6c99ce35
>>> --- /dev/null
>>> +++ b/app/test-pmd/cmdline_cman.h
>>> @@ -0,0 +1,12 @@
>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>> + * Copyright(C) 2022 Marvell International Ltd.
>>> + */
>>> +
>>> +#ifndef _CMDLINE_CMAN_H_
>>> +#define _CMDLINE_CMAN_H_
>>> +
>>> +extern cmdline_parse_inst_t cmd_show_port_cman_capa; extern
>>> +cmdline_parse_inst_t cmd_show_port_cman_config; extern
>>> +cmdline_parse_inst_t cmd_set_port_cman_config;
>>> +
>>> +#endif /* _CMDLINE_CMAN_H_ */
>>> diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index
>>> 74399178dd..c03d9dfebb 100644
>>> --- a/app/test-pmd/meson.build
>>> +++ b/app/test-pmd/meson.build
>>> @@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
>>>   sources = files(
>>>           '5tswap.c',
>>>           'cmdline.c',
>>> +        'cmdline_cman.c',
>>>           'cmdline_flow.c',
>>>           'cmdline_mtr.c',
>>>           'cmdline_tm.c',
>>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>> index d3075bf87d..b9c7b468af 100644
>>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>> @@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports.
>>>      testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex 
>>> item is 3
>>> pattern is 2 / end actions mark id 1 / queue index 0 / end
>>>      Flow rule #0 created
>>>
>>> +Congestion Management
>>> +---------------------
>>> +
>>> +Get capabilities
>>> +~~~~~~~~~~~~~~~~
>>> +
>>> +Retrieve congestion management capabilities supported by driver for 
>>> given
>>> port.
>>> +Below example command retrieves capabilities for port 0::
>>> +
>>> +   testpmd> show port cman capa 0
>>> +
>>> +Get configuration
>>> +~~~~~~~~~~~~~~~~~
>>> +Retrieve congestion management configuration for given port. Below
>>> +example command retrieves configuration for port 0::
>>> +
>>> +   testpmd> show port cman config 0
>>> +
>>> +Set configuration
>>> +~~~~~~~~~~~~~~~~~
>>> +Configures congestion management settings on given queue or mempool
>>> +associated with queue. Below example command configures RED as
>>> +congestion management algo for port 0 and queue 0::
>>> +
>>> +   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
>>> +
Rather than adding this section at the end can we put it near TM section 4.9
>>>   Driver specific commands
>>>   ------------------------
>>>
>>> -- 
>>> 2.25.1
>>
>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [EXT] Re: [PATCH v2 1/3] app/testpmd: support congestion management CLIs
  2022-11-07  7:12         ` Singh, Aman Deep
@ 2022-11-29  7:54           ` Sunil Kumar Kori
  0 siblings, 0 replies; 17+ messages in thread
From: Sunil Kumar Kori @ 2022-11-29  7:54 UTC (permalink / raw)
  To: Singh, Aman Deep, Andrew Rybchenko, Yuying Zhang, Cristian Dumitrescu; +Cc: dev

> -----Original Message-----
> From: Singh, Aman Deep <aman.deep.singh@intel.com>
> Sent: Monday, November 7, 2022 12:42 PM
> To: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Yuying Zhang
> <yuying.zhang@intel.com>; Cristian Dumitrescu
> <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org; Sunil Kumar Kori <skori@marvell.com>
> Subject: [EXT] Re: [PATCH v2 1/3] app/testpmd: support congestion
> management CLIs
> 
> External Email
> 
> ----------------------------------------------------------------------
> These newly added files for Congestion Management look in-line to Traffic
> Metering part, would like @Cristian to also have a look.
> 
> Regards
> Aman
> 
> On 11/6/2022 3:38 PM, Andrew Rybchenko wrote:
> > @Aman, @Yuying, please, help to review the patch.
> >
> > On 10/12/22 12:01, Sunil Kumar Kori wrote:
> >> Please review the following changes and provide feedback.
> >>
> >> Regards
> >> Sunil Kumar Kori
> >>
> >>> -----Original Message-----
> >>> From: skori@marvell.com <skori@marvell.com>
> >>> Sent: Thursday, September 29, 2022 3:25 PM
> >>> To: Aman Singh <aman.deep.singh@intel.com>; Yuying Zhang
> >>> <yuying.zhang@intel.com>
> >>> Cc: dev@dpdk.org; Sunil Kumar Kori <skori@marvell.com>
> >>> Subject: [PATCH v2 1/3] app/testpmd: support congestion management
> >>> CLIs
> >>>
> >>> From: Sunil Kumar Kori <skori@marvell.com>
> >>>
> >>> Support congestion management CLIs.
> >>>
> >>> Depends-on: patch-24902 ("ethdev: support congestion management")
> >>>
> >>> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> Acked-by: Aman Singh <aman.deep.singh@intel.com>
> >>> ---
> >>> v1..v2:
> >>>   - Rebase on top of the dpdk-next-net-mrvl/for-next-net
> >>>
> >>>   app/test-pmd/cmdline.c                      |  15 +
> >>>   app/test-pmd/cmdline_cman.c                 | 390
> >>> ++++++++++++++++++++
> >>>   app/test-pmd/cmdline_cman.h                 |  12 +
> >>>   app/test-pmd/meson.build                    |   1 +
> >>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
> >>>   5 files changed, 444 insertions(+)
> >>>   create mode 100644 app/test-pmd/cmdline_cman.c  create mode
> 100644

[snipped]

> >>>
> >>> +Congestion Management
> >>> +---------------------
> >>> +
> >>> +Get capabilities
> >>> +~~~~~~~~~~~~~~~~
> >>> +
> >>> +Retrieve congestion management capabilities supported by driver for
> >>> given
> >>> port.
> >>> +Below example command retrieves capabilities for port 0::
> >>> +
> >>> +   testpmd> show port cman capa 0
> >>> +
> >>> +Get configuration
> >>> +~~~~~~~~~~~~~~~~~
> >>> +Retrieve congestion management configuration for given port. Below
> >>> +example command retrieves configuration for port 0::
> >>> +
> >>> +   testpmd> show port cman config 0
> >>> +
> >>> +Set configuration
> >>> +~~~~~~~~~~~~~~~~~
> >>> +Configures congestion management settings on given queue or
> mempool
> >>> +associated with queue. Below example command configures RED as
> >>> +congestion management algo for port 0 and queue 0::
> >>> +
> >>> +   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
> >>> +
> Rather than adding this section at the end can we put it near TM section 4.9

Ack. But I believe keeping it after section 4.10 is okay. 

> >>>   Driver specific commands
> >>>   ------------------------
> >>>
> >>> --
> >>> 2.25.1
> >>
> >


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 1/1] app/testpmd: support congestion management CLIs
  2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
                       ` (2 preceding siblings ...)
  2022-10-12  9:01     ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs Sunil Kumar Kori
@ 2022-11-29  8:04     ` skori
  2022-12-02  7:56       ` [PATCH v4 " skori
  3 siblings, 1 reply; 17+ messages in thread
From: skori @ 2022-11-29  8:04 UTC (permalink / raw)
  To: Aman Singh, Yuying Zhang; +Cc: dev, Sunil Kumar Kori

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management CLIs.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: Aman Singh <aman.deep.singh@intel.com>
---
v2..v3:
 - Move Congestion management document section near TM section
 - Rebase on top of the dpdk/main
v1..v2:
 - Rebase on top of the dpdk-next-net-mrvl/for-next-net

 app/test-pmd/cmdline.c                      |  15 +
 app/test-pmd/cmdline_cman.c                 | 390 ++++++++++++++++++++
 app/test-pmd/cmdline_cman.h                 |  12 +
 app/test-pmd/meson.build                    |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
 5 files changed, 444 insertions(+)
 create mode 100644 app/test-pmd/cmdline_cman.c
 create mode 100644 app/test-pmd/cmdline_cman.h

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b32dc8bfd4..cb8c174020 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -61,6 +61,7 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include "testpmd.h"
+#include "cmdline_cman.h"
 #include "cmdline_mtr.h"
 #include "cmdline_tm.h"
 #include "bpf_cmd.h"
@@ -610,6 +611,17 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) fec_mode auto|off|rs|baser\n"
 			"    set fec mode for a specific port\n\n"
 
+			"show port cman capa (port_id)\n"
+			"    Show congestion management capabilities\n\n"
+
+			"show port cman config (port_id)\n"
+			"    Show congestion management configuration\n\n"
+
+			"set port cman config (port_id) (queue_id) default | "
+			"[obj (queue|queue_mempool) mode red (min_thresh) "
+			"(max_thresh) (prob_inv)]\n"
+			"    Set congestion management configuration\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12851,6 +12863,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_capability,
 	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
 	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
+	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
 	NULL,
 };
 
diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
new file mode 100644
index 0000000000..344759189d
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.c
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+
+#include <rte_ethdev.h>
+
+#include "testpmd.h"
+
+#define PARSE_DELIMITER				" \f\n\r\t\v"
+
+static int
+parse_uint(uint64_t *value, const char *str)
+{
+	char *next = NULL;
+	uint64_t n;
+
+	errno = 0;
+	/* Parse number string */
+	n = strtol(str, &next, 10);
+	if (errno != 0 || str == next || *next != '\0')
+		return -1;
+
+	*value = n;
+
+	return 0;
+}
+
+static int
+parse_cman_obj_str(char *str, uint64_t *obj)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "queue") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	else if (strcasecmp(token, "queue_mempool") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_mode_str(char *str, uint64_t *mode)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "red") == 0)
+		*mode = RTE_CMAN_RED;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_params_str(uint16_t port_id, char *str,
+		      struct rte_eth_cman_config *cfg)
+{
+	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
+	struct rte_eth_cman_info info;
+	char *token;
+	int ret;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (!strcasecmp(token, "default")) {
+		ret = rte_eth_cman_config_init(port_id, cfg);
+		if (ret) {
+			fprintf(stderr, "error in default initialization\n");
+			return ret;
+		}
+		return 0;
+	}
+
+	/* First token: obj name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Object param parse error\n");
+		goto error;
+	}
+
+	ret = parse_cman_obj_str(token, &obj);
+	if (ret) {
+		fprintf(stderr, "Object value is invalid\n");
+		goto error;
+	}
+
+	/* Second token: mode name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode param is invalid\n");
+		goto error;
+	}
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode value is invalid\n");
+		goto error;
+	}
+
+	ret = parse_cman_mode_str(token, &mode);
+	if (ret) {
+		fprintf(stderr, "mode string parse error\n");
+		goto error;
+	}
+
+	/* Third token: minimum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Minimum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&min_th, token);
+	if (ret != 0 || min_th > UINT8_MAX) {
+		fprintf(stderr, "Minimum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fourth token: maximum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&max_th, token);
+	if (ret != 0 || max_th > UINT8_MAX) {
+		fprintf(stderr, "Maximum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fifth token: probability inversion */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum probability inversion parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&maxp_inv, token);
+	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
+		fprintf(stderr, "Maximum probability inversion is invalid\n");
+		goto error;
+	}
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret) {
+		fprintf(stderr, "Congestion management capa get error\n");
+		goto error;
+	}
+
+	if (!(info.objs_supported & obj)) {
+		fprintf(stderr, "Object type is not supported by driver\n");
+		goto error;
+	}
+
+	if (!(info.modes_supported & mode)) {
+		fprintf(stderr, "Mode is not supported by driver\n");
+		goto error;
+	}
+
+	cfg->obj = obj;
+	cfg->mode = mode;
+	cfg->mode_param.red.min_th = min_th;
+	cfg->mode_param.red.max_th = max_th;
+	cfg->mode_param.red.maxp_inv = maxp_inv;
+
+	return 0;
+
+error:
+	return -EINVAL;
+}
+
+/* *** Show Port Congestion Management Capabilities *** */
+struct cmd_show_port_cman_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t capa;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, capa, "capa");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_capa_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_capa_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_info info;
+	int ret;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Capabilities   ****\n\n");
+	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
+	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_capa = {
+	.f = cmd_show_port_cman_capa_parsed,
+	.data = NULL,
+	.help_str = "show port cman capa <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_capa_show,
+		(void *)&cmd_show_port_cman_capa_port,
+		(void *)&cmd_show_port_cman_capa_cman,
+		(void *)&cmd_show_port_cman_capa_capa,
+		(void *)&cmd_show_port_cman_capa_port_id,
+		NULL,
+	},
+};
+
+/* *** Show Port Congestion Management configuration *** */
+struct cmd_show_port_cman_cfg_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
+	ret = rte_eth_cman_config_get(port_id, &cfg);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Configuration   ****\n\n");
+	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
+	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
+	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
+	printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th);
+	printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th);
+	printf("cman RED Prob inversion %" PRIx16 "\n",
+		cfg.mode_param.red.maxp_inv);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_config = {
+	.f = cmd_show_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "show port cman config <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_cfg_show,
+		(void *)&cmd_show_port_cman_cfg_port,
+		(void *)&cmd_show_port_cman_cfg_cman,
+		(void *)&cmd_show_port_cman_cfg_cfg,
+		(void *)&cmd_show_port_cman_cfg_port_id,
+		NULL,
+	},
+};
+
+/* *** Set Port Congestion Management configuration *** */
+struct cmd_set_port_cman_cfg_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+	uint16_t qid;
+	cmdline_multi_string_t params;
+};
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, set, "set");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
+		params, TOKEN_STRING_MULTI);
+
+static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_set_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	ret = parse_cman_params_str(port_id, res->params, &cfg);
+	if (ret) {
+		fprintf(stderr, "params string parse error\n");
+		return;
+	}
+
+	cfg.obj_param.rx_queue = res->qid;
+	rte_eth_cman_config_set(port_id, &cfg);
+}
+
+cmdline_parse_inst_t cmd_set_port_cman_config = {
+	.f = cmd_set_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "set port cman config <port_id> <queue_id> "
+		    "default | [obj <queue|queue_mempool> mode red "
+		    "<min_thresh> <max_thresh> <prob_inv>]",
+	.tokens = {
+		(void *)&cmd_set_port_cman_cfg_set,
+		(void *)&cmd_set_port_cman_cfg_port,
+		(void *)&cmd_set_port_cman_cfg_cman,
+		(void *)&cmd_set_port_cman_cfg_cfg,
+		(void *)&cmd_set_port_cman_cfg_port_id,
+		(void *)&cmd_set_port_cman_cfg_qid,
+		(void *)&cmd_set_port_cman_cfg_params,
+		NULL,
+	},
+};
diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
new file mode 100644
index 0000000000..bd6c99ce35
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#ifndef _CMDLINE_CMAN_H_
+#define _CMDLINE_CMAN_H_
+
+extern cmdline_parse_inst_t cmd_show_port_cman_capa;
+extern cmdline_parse_inst_t cmd_show_port_cman_config;
+extern cmdline_parse_inst_t cmd_set_port_cman_config;
+
+#endif /* _CMDLINE_CMAN_H_ */
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 8488efc138..d2e3f60892 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
 sources = files(
         '5tswap.c',
         'cmdline.c',
+        'cmdline_cman.c',
         'cmdline_flow.c',
         'cmdline_mtr.c',
         'cmdline_tm.c',
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 0037506a79..03663866ac 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2843,6 +2843,32 @@ where:
 * ``red`` enable 1, disable 0 marking IP ecn for yellow marked packets with ecn of 2'b01  or 2'b10
   to ecn of 2'b11 when IP is caring TCP or SCTP
 
+Congestion Management
+---------------------
+
+Get capabilities
+~~~~~~~~~~~~~~~~
+
+Retrieve congestion management capabilities supported by driver for given port.
+Below example command retrieves capabilities for port 0::
+
+   testpmd> show port cman capa 0
+
+Get configuration
+~~~~~~~~~~~~~~~~~
+Retrieve congestion management configuration for given port. Below example
+command retrieves configuration for port 0::
+
+   testpmd> show port cman config 0
+
+Set configuration
+~~~~~~~~~~~~~~~~~
+Configures congestion management settings on given queue or mempool associated
+with queue. Below example command configures RED as congestion management algo
+for port 0 and queue 0::
+
+   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
+
 Filter Functions
 ----------------
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v4 1/1] app/testpmd: support congestion management CLIs
  2022-11-29  8:04     ` [PATCH v3 1/1] " skori
@ 2022-12-02  7:56       ` skori
  2022-12-07 14:19         ` Ferruh Yigit
  0 siblings, 1 reply; 17+ messages in thread
From: skori @ 2022-12-02  7:56 UTC (permalink / raw)
  To: Aman Singh, Yuying Zhang; +Cc: dev, Sunil Kumar Kori

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management CLIs.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: Aman Singh <aman.deep.singh@intel.com>
---
v3..v4:
 - Fix build error
v2..v3:
 - Move Congestion management document section near TM section
 - Rebase on top of the dpdk/main
v1..v2:
 - Rebase on top of the dpdk-next-net-mrvl/for-next-net

 app/test-pmd/cmdline.c                      |  15 +
 app/test-pmd/cmdline_cman.c                 | 392 ++++++++++++++++++++
 app/test-pmd/cmdline_cman.h                 |  12 +
 app/test-pmd/meson.build                    |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  26 ++
 5 files changed, 446 insertions(+)
 create mode 100644 app/test-pmd/cmdline_cman.c
 create mode 100644 app/test-pmd/cmdline_cman.h

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b32dc8bfd4..cb8c174020 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -61,6 +61,7 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include "testpmd.h"
+#include "cmdline_cman.h"
 #include "cmdline_mtr.h"
 #include "cmdline_tm.h"
 #include "bpf_cmd.h"
@@ -610,6 +611,17 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) fec_mode auto|off|rs|baser\n"
 			"    set fec mode for a specific port\n\n"
 
+			"show port cman capa (port_id)\n"
+			"    Show congestion management capabilities\n\n"
+
+			"show port cman config (port_id)\n"
+			"    Show congestion management configuration\n\n"
+
+			"set port cman config (port_id) (queue_id) default | "
+			"[obj (queue|queue_mempool) mode red (min_thresh) "
+			"(max_thresh) (prob_inv)]\n"
+			"    Set congestion management configuration\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12851,6 +12863,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_capability,
 	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
 	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
+	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
+	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
 	NULL,
 };
 
diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c
new file mode 100644
index 0000000000..1a34172f1f
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.c
@@ -0,0 +1,392 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include <stdlib.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+
+#include <rte_ethdev.h>
+
+#include "testpmd.h"
+
+#define PARSE_DELIMITER				" \f\n\r\t\v"
+
+static int
+parse_uint(uint64_t *value, const char *str)
+{
+	char *next = NULL;
+	uint64_t n;
+
+	errno = 0;
+	/* Parse number string */
+	n = strtol(str, &next, 10);
+	if (errno != 0 || str == next || *next != '\0')
+		return -1;
+
+	*value = n;
+
+	return 0;
+}
+
+static int
+parse_cman_obj_str(char *str, uint64_t *obj)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "queue") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	else if (strcasecmp(token, "queue_mempool") == 0)
+		*obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_mode_str(char *str, uint64_t *mode)
+{
+	char *token;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL)
+		return 0;
+
+	if (strcasecmp(token, "red") == 0)
+		*mode = RTE_CMAN_RED;
+	else
+		return -1;
+
+	return 0;
+}
+
+static int
+parse_cman_params_str(uint16_t port_id, char *str,
+		      struct rte_eth_cman_config *cfg)
+{
+	uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0;
+	struct rte_eth_cman_info info;
+	char *token;
+	int ret;
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (!strcasecmp(token, "default")) {
+		ret = rte_eth_cman_config_init(port_id, cfg);
+		if (ret) {
+			fprintf(stderr, "error in default initialization\n");
+			return ret;
+		}
+		return 0;
+	}
+
+	/* First token: obj name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Object param parse error\n");
+		goto error;
+	}
+
+	ret = parse_cman_obj_str(token, &obj);
+	if (ret) {
+		fprintf(stderr, "Object value is invalid\n");
+		goto error;
+	}
+
+	/* Second token: mode name */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode param is invalid\n");
+		goto error;
+	}
+
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, " Mode value is invalid\n");
+		goto error;
+	}
+
+	ret = parse_cman_mode_str(token, &mode);
+	if (ret) {
+		fprintf(stderr, "mode string parse error\n");
+		goto error;
+	}
+
+	/* Third token: minimum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Minimum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&min_th, token);
+	if (ret != 0 || min_th > UINT8_MAX) {
+		fprintf(stderr, "Minimum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fourth token: maximum threshold */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum threshold parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&max_th, token);
+	if (ret != 0 || max_th > UINT8_MAX) {
+		fprintf(stderr, "Maximum threshold is invalid\n");
+		goto error;
+	}
+
+	/* Fifth token: probability inversion */
+	token = strtok_r(str, PARSE_DELIMITER, &str);
+	if (token == NULL) {
+		fprintf(stderr, "Maximum probability inversion parse error\n");
+		goto error;
+	}
+
+	ret = parse_uint(&maxp_inv, token);
+	if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) {
+		fprintf(stderr, "Maximum probability inversion is invalid\n");
+		goto error;
+	}
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret) {
+		fprintf(stderr, "Congestion management capa get error\n");
+		goto error;
+	}
+
+	if (!(info.objs_supported & obj)) {
+		fprintf(stderr, "Object type is not supported by driver\n");
+		goto error;
+	}
+
+	if (!(info.modes_supported & mode)) {
+		fprintf(stderr, "Mode is not supported by driver\n");
+		goto error;
+	}
+
+	cfg->obj = obj;
+	cfg->mode = mode;
+	cfg->mode_param.red.min_th = min_th;
+	cfg->mode_param.red.max_th = max_th;
+	cfg->mode_param.red.maxp_inv = maxp_inv;
+
+	return 0;
+
+error:
+	return -EINVAL;
+}
+
+/* *** Show Port Congestion Management Capabilities *** */
+struct cmd_show_port_cman_capa_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t capa;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, capa, "capa");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_capa_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_capa_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_capa_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_info info;
+	int ret;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	ret = rte_eth_cman_info_get(port_id, &info);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Capabilities   ****\n\n");
+	printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported);
+	printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_capa = {
+	.f = cmd_show_port_cman_capa_parsed,
+	.data = NULL,
+	.help_str = "show port cman capa <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_capa_show,
+		(void *)&cmd_show_port_cman_capa_port,
+		(void *)&cmd_show_port_cman_capa_cman,
+		(void *)&cmd_show_port_cman_capa_capa,
+		(void *)&cmd_show_port_cman_capa_port_id,
+		NULL,
+	},
+};
+
+/* *** Show Port Congestion Management configuration *** */
+struct cmd_show_port_cman_cfg_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+};
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, show, "show");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_show_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static void cmd_show_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_show_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	memset(&cfg, 0, sizeof(struct rte_eth_cman_config));
+	ret = rte_eth_cman_config_get(port_id, &cfg);
+	if (ret)
+		return;
+
+	printf("\n****   Port Congestion Management Configuration   ****\n\n");
+	printf("cman object 0x%" PRIx32 "\n", cfg.obj);
+	printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue);
+	printf("cman mode 0x%" PRIx32 "\n", cfg.mode);
+	printf("cman RED min thresh %" PRIx8 "\n", cfg.mode_param.red.min_th);
+	printf("cman RED max thresh %" PRIx8 "\n", cfg.mode_param.red.max_th);
+	printf("cman RED Prob inversion %" PRIx16 "\n",
+		cfg.mode_param.red.maxp_inv);
+}
+
+cmdline_parse_inst_t cmd_show_port_cman_config = {
+	.f = cmd_show_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "show port cman config <port_id>",
+	.tokens = {
+		(void *)&cmd_show_port_cman_cfg_show,
+		(void *)&cmd_show_port_cman_cfg_port,
+		(void *)&cmd_show_port_cman_cfg_cman,
+		(void *)&cmd_show_port_cman_cfg_cfg,
+		(void *)&cmd_show_port_cman_cfg_port_id,
+		NULL,
+	},
+};
+
+/* *** Set Port Congestion Management configuration *** */
+struct cmd_set_port_cman_cfg_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t cman;
+	cmdline_fixed_string_t cfg;
+	uint16_t port_id;
+	uint16_t qid;
+	cmdline_multi_string_t params;
+};
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, set, "set");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port, "port");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cman, "cman");
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg =
+	TOKEN_STRING_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, cfg, "config");
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16);
+
+static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid =
+	TOKEN_NUM_INITIALIZER(
+		struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16);
+
+static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result,
+		params, TOKEN_STRING_MULTI);
+
+static void cmd_set_port_cman_cfg_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_set_port_cman_cfg_result *res = parsed_result;
+	uint16_t port_id = res->port_id;
+	struct rte_eth_cman_config cfg;
+	int ret;
+
+	ret = parse_cman_params_str(port_id, res->params, &cfg);
+	if (ret) {
+		fprintf(stderr, "params string parse error\n");
+		return;
+	}
+
+	cfg.obj_param.rx_queue = res->qid;
+	rte_eth_cman_config_set(port_id, &cfg);
+}
+
+cmdline_parse_inst_t cmd_set_port_cman_config = {
+	.f = cmd_set_port_cman_cfg_parsed,
+	.data = NULL,
+	.help_str = "set port cman config <port_id> <queue_id> "
+		    "default | [obj <queue|queue_mempool> mode red "
+		    "<min_thresh> <max_thresh> <prob_inv>]",
+	.tokens = {
+		(void *)&cmd_set_port_cman_cfg_set,
+		(void *)&cmd_set_port_cman_cfg_port,
+		(void *)&cmd_set_port_cman_cfg_cman,
+		(void *)&cmd_set_port_cman_cfg_cfg,
+		(void *)&cmd_set_port_cman_cfg_port_id,
+		(void *)&cmd_set_port_cman_cfg_qid,
+		(void *)&cmd_set_port_cman_cfg_params,
+		NULL,
+	},
+};
diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h
new file mode 100644
index 0000000000..bd6c99ce35
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#ifndef _CMDLINE_CMAN_H_
+#define _CMDLINE_CMAN_H_
+
+extern cmdline_parse_inst_t cmd_show_port_cman_capa;
+extern cmdline_parse_inst_t cmd_show_port_cman_config;
+extern cmdline_parse_inst_t cmd_set_port_cman_config;
+
+#endif /* _CMDLINE_CMAN_H_ */
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 8488efc138..d2e3f60892 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations'
 sources = files(
         '5tswap.c',
         'cmdline.c',
+        'cmdline_cman.c',
         'cmdline_flow.c',
         'cmdline_mtr.c',
         'cmdline_tm.c',
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 0037506a79..03663866ac 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2843,6 +2843,32 @@ where:
 * ``red`` enable 1, disable 0 marking IP ecn for yellow marked packets with ecn of 2'b01  or 2'b10
   to ecn of 2'b11 when IP is caring TCP or SCTP
 
+Congestion Management
+---------------------
+
+Get capabilities
+~~~~~~~~~~~~~~~~
+
+Retrieve congestion management capabilities supported by driver for given port.
+Below example command retrieves capabilities for port 0::
+
+   testpmd> show port cman capa 0
+
+Get configuration
+~~~~~~~~~~~~~~~~~
+Retrieve congestion management configuration for given port. Below example
+command retrieves configuration for port 0::
+
+   testpmd> show port cman config 0
+
+Set configuration
+~~~~~~~~~~~~~~~~~
+Configures congestion management settings on given queue or mempool associated
+with queue. Below example command configures RED as congestion management algo
+for port 0 and queue 0::
+
+   testpmd> set port cman config 0 0 obj queue mode red 10 100 1
+
 Filter Functions
 ----------------
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v4 1/1] app/testpmd: support congestion management CLIs
  2022-12-02  7:56       ` [PATCH v4 " skori
@ 2022-12-07 14:19         ` Ferruh Yigit
  0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2022-12-07 14:19 UTC (permalink / raw)
  To: skori, Aman Singh, Yuying Zhang; +Cc: dev

On 12/2/2022 7:56 AM, skori@marvell.com wrote:
> From: Sunil Kumar Kori <skori@marvell.com>
> 
> Support congestion management CLIs.
> 
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> Acked-by: Aman Singh <aman.deep.singh@intel.com>

Acked-by: Ferruh Yigit <ferruh.yigit@amd.com>

Applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 3/3] net/cnxk: support congestion management ops
  2022-09-19 12:28 [PATCH 1/3] " skori
@ 2022-09-19 12:28 ` skori
  0 siblings, 0 replies; 17+ messages in thread
From: skori @ 2022-09-19 12:28 UTC (permalink / raw)
  To: Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao; +Cc: dev

From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management.

Depends-on: patch-24710 ("ethdev: support congestion management")

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Change-Id: Ic655574a1b9bb34baa177848b8148a29a87fe8cf
---
 doc/guides/nics/features/cnxk.ini   |   1 +
 drivers/net/cnxk/cnxk_ethdev.c      |   4 +
 drivers/net/cnxk/cnxk_ethdev.h      |  12 +++
 drivers/net/cnxk/cnxk_ethdev_cman.c | 140 ++++++++++++++++++++++++++++
 drivers/net/cnxk/meson.build        |   1 +
 5 files changed, 158 insertions(+)
 create mode 100644 drivers/net/cnxk/cnxk_ethdev_cman.c

diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini
index 1876fe86c7..bbb90e9527 100644
--- a/doc/guides/nics/features/cnxk.ini
+++ b/doc/guides/nics/features/cnxk.ini
@@ -41,6 +41,7 @@ Rx descriptor status = Y
 Tx descriptor status = Y
 Basic stats          = Y
 Stats per queue      = Y
+Congestion management = Y
 Extended stats       = Y
 FW version           = Y
 Module EEPROM dump   = Y
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 48170147a4..2d46938d68 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1678,6 +1678,10 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.tm_ops_get = cnxk_nix_tm_ops_get,
 	.mtr_ops_get = cnxk_nix_mtr_ops_get,
 	.eth_dev_priv_dump  = cnxk_nix_eth_dev_priv_dump,
+	.cman_info_get = cnxk_nix_cman_info_get,
+	.cman_config_init = cnxk_nix_cman_config_init,
+	.cman_config_set = cnxk_nix_cman_config_set,
+	.cman_config_get = cnxk_nix_cman_config_get,
 };
 
 static int
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index c09e9bff8e..f884a532e1 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -417,6 +417,9 @@ struct cnxk_eth_dev {
 	struct cnxk_mtr_policy mtr_policy;
 	struct cnxk_mtr mtr;
 
+	/* Congestion Management */
+	struct rte_eth_cman_config cman_cfg;
+
 	/* Rx burst for cleanup(Only Primary) */
 	eth_rx_burst_t rx_pkt_burst_no_offload;
 
@@ -649,6 +652,15 @@ cnxk_eth_sec_sess_get_by_sess(struct cnxk_eth_dev *dev,
 int cnxk_nix_inl_meta_pool_cb(uint64_t *aura_handle, uint32_t buf_sz, uint32_t nb_bufs,
 			      bool destroy);
 
+/* Congestion Management */
+int cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info);
+
+int cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_set(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
+int cnxk_nix_cman_config_get(struct rte_eth_dev *dev, struct rte_eth_cman_config *config);
+
 /* Other private functions */
 int nix_recalc_mtu(struct rte_eth_dev *eth_dev);
 int nix_mtr_validate(struct rte_eth_dev *dev, uint32_t id);
diff --git a/drivers/net/cnxk/cnxk_ethdev_cman.c b/drivers/net/cnxk/cnxk_ethdev_cman.c
new file mode 100644
index 0000000000..5f019cd721
--- /dev/null
+++ b/drivers/net/cnxk/cnxk_ethdev_cman.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include "cnxk_ethdev.h"
+
+#define CNXK_NIX_CMAN_RED_MIN_THRESH 75
+#define CNXK_NIX_CMAN_RED_MAX_THRESH 95
+
+int
+cnxk_nix_cman_info_get(struct rte_eth_dev *dev, struct rte_eth_cman_info *info)
+{
+	RTE_SET_USED(dev);
+
+	info->modes_supported = RTE_CMAN_RED;
+	info->objs_supported = RTE_ETH_CMAN_OBJ_RX_QUEUE | RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL;
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_init(struct rte_eth_dev *dev, struct rte_eth_cman_config *config)
+{
+	RTE_SET_USED(dev);
+
+	memset(config, 0, sizeof(struct rte_eth_cman_config));
+
+	config->obj = RTE_ETH_CMAN_OBJ_RX_QUEUE;
+	config->mode = RTE_CMAN_RED;
+	config->mode_param.red.min_th = CNXK_NIX_CMAN_RED_MIN_THRESH;
+	config->mode_param.red.max_th = CNXK_NIX_CMAN_RED_MAX_THRESH;
+	return 0;
+}
+
+static int
+nix_cman_config_validate(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct rte_eth_cman_info info;
+
+	memset(&info, 0, sizeof(struct rte_eth_cman_info));
+	cnxk_nix_cman_info_get(eth_dev, &info);
+
+	if (!(config->obj & info.objs_supported)) {
+		plt_err("Invalid object");
+		return -EINVAL;
+	}
+
+	if (!(config->mode & info.modes_supported)) {
+		plt_err("Invalid mode");
+		return -EINVAL;
+	}
+
+	if (config->obj_param.rx_queue >= dev->nb_rxq) {
+		plt_err("Invalid queue ID. Queue = %u", config->obj_param.rx_queue);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.min_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED minimum threshold. min_th = %u",
+			config->mode_param.red.min_th);
+		return -EINVAL;
+	}
+
+	if (config->mode_param.red.max_th > CNXK_NIX_CMAN_RED_MAX_THRESH) {
+		plt_err("Invalid RED maximum threshold. max_th = %u",
+			config->mode_param.red.max_th);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_set(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	uint8_t drop, pass, shift;
+	uint8_t min_th, max_th;
+	struct roc_nix_cq *cq;
+	struct roc_nix_rq *rq;
+	bool is_mempool;
+	uint64_t buf_cnt;
+	int rc;
+
+	rc = nix_cman_config_validate(eth_dev, config);
+	if (rc)
+		return rc;
+
+	cq = &dev->cqs[config->obj_param.rx_queue];
+	rq = &dev->rqs[config->obj_param.rx_queue];
+	is_mempool = config->obj & RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL ? true : false;
+	min_th = config->mode_param.red.min_th;
+	max_th = config->mode_param.red.max_th;
+
+	if (is_mempool) {
+		buf_cnt = roc_npa_aura_op_limit_get(rq->aura_handle);
+		shift = plt_log2_u32(buf_cnt);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+		drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+		rq->red_pass = pass;
+		rq->red_drop = drop;
+
+		if (rq->spb_ena) {
+			buf_cnt = roc_npa_aura_op_limit_get(rq->spb_aura_handle);
+			shift = plt_log2_u32(buf_cnt);
+			shift = shift < 8 ? 0 : shift - 8;
+			pass = (buf_cnt >> shift) - ((buf_cnt * min_th / 100) >> shift);
+			drop = (buf_cnt >> shift) - ((buf_cnt * max_th / 100) >> shift);
+			rq->spb_red_pass = pass;
+			rq->spb_red_drop = drop;
+		}
+	} else {
+		shift = plt_log2_u32(cq->nb_desc);
+		shift = shift < 8 ? 0 : shift - 8;
+		pass = 256 - ((cq->nb_desc * min_th / 100) >> shift);
+		drop = 256 - ((cq->nb_desc * max_th / 100) >> shift);
+
+		rq->xqe_red_pass = pass;
+		rq->xqe_red_drop = drop;
+	}
+
+	rc = roc_nix_rq_cman_config(nix, rq);
+	if (rc)
+		return rc;
+
+	memcpy(&dev->cman_cfg, config, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
+
+int
+cnxk_nix_cman_config_get(struct rte_eth_dev *eth_dev, struct rte_eth_cman_config *config)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+	memcpy(config, &dev->cman_cfg, sizeof(struct rte_eth_cman_config));
+	return 0;
+}
diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build
index f347e98fce..9253e8d0ab 100644
--- a/drivers/net/cnxk/meson.build
+++ b/drivers/net/cnxk/meson.build
@@ -10,6 +10,7 @@ endif
 
 sources = files(
         'cnxk_ethdev.c',
+        'cnxk_ethdev_cman.c',
         'cnxk_ethdev_devargs.c',
         'cnxk_ethdev_mtr.c',
         'cnxk_ethdev_ops.c',
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2022-12-07 14:19 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-19 12:41 [PATCH 1/3] app/testpmd: support congestion management CLIs skori
2022-09-19 12:41 ` [PATCH 2/3] common/cnxk: add congestion management ROC APIs skori
2022-09-19 12:41 ` [PATCH 3/3] net/cnxk: support congestion management ops skori
2022-09-29  9:54   ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs skori
2022-09-29  9:54     ` [PATCH v2 2/3] common/cnxk: add congestion management ROC APIs skori
2022-10-11  6:27       ` Sunil Kumar Kori
2022-09-29  9:54     ` [PATCH v2 3/3] net/cnxk: support congestion management ops skori
2022-10-11  6:29       ` Sunil Kumar Kori
2022-10-12  6:43         ` Jerin Jacob
2022-10-12  9:01     ` [PATCH v2 1/3] app/testpmd: support congestion management CLIs Sunil Kumar Kori
2022-11-06 10:08       ` Andrew Rybchenko
2022-11-07  7:12         ` Singh, Aman Deep
2022-11-29  7:54           ` [EXT] " Sunil Kumar Kori
2022-11-29  8:04     ` [PATCH v3 1/1] " skori
2022-12-02  7:56       ` [PATCH v4 " skori
2022-12-07 14:19         ` Ferruh Yigit
  -- strict thread matches above, loose matches on Subject: below --
2022-09-19 12:28 [PATCH 1/3] " skori
2022-09-19 12:28 ` [PATCH 3/3] net/cnxk: support congestion management ops skori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.