DPDK patches and discussions
 help / color / mirror / Atom feed
From: <skoteshwar@marvell.com>
To: Nithin Dabilpuram <ndabilpuram@marvell.com>,
	Kiran Kumar K <kirankumark@marvell.com>,
	Sunil Kumar Kori <skori@marvell.com>,
	Satha Rao <skoteshwar@marvell.com>
Cc: <dev@dpdk.org>
Subject: [dpdk-dev] [PATCH v2 8/8] net/cnxk: tm shaper and node operations
Date: Sat, 18 Sep 2021 10:31:58 -0400	[thread overview]
Message-ID: <1631975519-30924-9-git-send-email-skoteshwar@marvell.com> (raw)
In-Reply-To: <1631975519-30924-1-git-send-email-skoteshwar@marvell.com>

From: Satha Rao <skoteshwar@marvell.com>

Implemented TM node, shaper profile, hierarchy_commit and
statistic operations.

Signed-off-by: Satha Rao <skoteshwar@marvell.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/cnxk/cnxk_tm.c             | 353 +++++++++++++++++++++++++++++++++
 drivers/net/cnxk/cnxk_tm.h             |   5 +
 3 files changed, 359 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index df4ffc3..36b1f65 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -85,6 +85,7 @@ New Features
 * **Updated Marvell cnxk ethdev driver.**
 
   * Added rte_flow support for dual VLAN insert and strip actions
+  * Added rte_tm support
 
 * **Added multi-process support for testpmd.**
 
diff --git a/drivers/net/cnxk/cnxk_tm.c b/drivers/net/cnxk/cnxk_tm.c
index 87fd8be..9015a45 100644
--- a/drivers/net/cnxk/cnxk_tm.c
+++ b/drivers/net/cnxk/cnxk_tm.c
@@ -259,11 +259,364 @@
 	return 0;
 }
 
+static int
+cnxk_nix_tm_shaper_profile_add(struct rte_eth_dev *eth_dev, uint32_t id,
+			       struct rte_tm_shaper_params *params,
+			       struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct cnxk_nix_tm_shaper_profile *profile;
+	struct roc_nix *nix = &dev->nix;
+	int rc;
+
+	if (roc_nix_tm_shaper_profile_get(nix, id)) {
+		error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;
+		error->message = "shaper profile ID exist";
+		return -EINVAL;
+	}
+
+	profile = rte_zmalloc("cnxk_nix_tm_shaper_profile",
+			      sizeof(struct cnxk_nix_tm_shaper_profile), 0);
+	if (!profile)
+		return -ENOMEM;
+	profile->profile.id = id;
+	profile->profile.commit_rate = params->committed.rate;
+	profile->profile.peak_rate = params->peak.rate;
+	profile->profile.commit_sz = params->committed.size;
+	profile->profile.peak_sz = params->peak.size;
+	/* If Byte mode, then convert to bps */
+	if (!params->packet_mode) {
+		profile->profile.commit_rate *= 8;
+		profile->profile.peak_rate *= 8;
+		profile->profile.commit_sz *= 8;
+		profile->profile.peak_sz *= 8;
+	}
+	profile->profile.pkt_len_adj = params->pkt_length_adjust;
+	profile->profile.pkt_mode = params->packet_mode;
+	profile->profile.free_fn = rte_free;
+	rte_memcpy(&profile->params, params,
+		   sizeof(struct rte_tm_shaper_params));
+
+	rc = roc_nix_tm_shaper_profile_add(nix, &profile->profile);
+
+	/* fill error information based on return value */
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	}
+
+	return rc;
+}
+
+static int
+cnxk_nix_tm_shaper_profile_delete(struct rte_eth_dev *eth_dev,
+				  uint32_t profile_id,
+				  struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	int rc;
+
+	rc = roc_nix_tm_shaper_profile_delete(nix, profile_id);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	}
+
+	return rc;
+}
+
+static int
+cnxk_nix_tm_node_add(struct rte_eth_dev *eth_dev, uint32_t node_id,
+		     uint32_t parent_node_id, uint32_t priority,
+		     uint32_t weight, uint32_t lvl,
+		     struct rte_tm_node_params *params,
+		     struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix_tm_shaper_profile *profile;
+	struct roc_nix_tm_node *parent_node;
+	struct roc_nix *nix = &dev->nix;
+	struct cnxk_nix_tm_node *node;
+	int rc;
+
+	/* we don't support dynamic updates */
+	if (roc_nix_tm_is_user_hierarchy_enabled(nix)) {
+		error->type = RTE_TM_ERROR_TYPE_CAPABILITIES;
+		error->message = "dynamic update not supported";
+		return -EIO;
+	}
+
+	parent_node = roc_nix_tm_node_get(nix, parent_node_id);
+	/* find the right level */
+	if (lvl == RTE_TM_NODE_LEVEL_ID_ANY) {
+		if (parent_node_id == RTE_TM_NODE_ID_NULL) {
+			lvl = ROC_TM_LVL_ROOT;
+		} else if (parent_node) {
+			lvl = parent_node->lvl + 1;
+		} else {
+			/* Neither proper parent nor proper level id given */
+			error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;
+			error->message = "invalid parent node id";
+			return -ERANGE;
+		}
+	}
+
+	node = rte_zmalloc("cnxk_nix_tm_node", sizeof(struct cnxk_nix_tm_node),
+			   0);
+	if (!node)
+		return -ENOMEM;
+
+	rte_memcpy(&node->params, params, sizeof(struct rte_tm_node_params));
+
+	node->nix_node.id = node_id;
+	node->nix_node.parent_id = parent_node_id;
+	node->nix_node.priority = priority;
+	node->nix_node.weight = weight;
+	node->nix_node.lvl = lvl;
+	node->nix_node.shaper_profile_id = params->shaper_profile_id;
+
+	profile = roc_nix_tm_shaper_profile_get(nix, params->shaper_profile_id);
+	/* Packet mode */
+	if (!roc_nix_tm_lvl_is_leaf(nix, lvl) &&
+	    ((profile && profile->pkt_mode) ||
+	     (params->nonleaf.wfq_weight_mode &&
+	      params->nonleaf.n_sp_priorities &&
+	      !params->nonleaf.wfq_weight_mode[0])))
+		node->nix_node.pkt_mode = 1;
+
+	rc = roc_nix_tm_node_add(nix, &node->nix_node);
+	if (rc < 0) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+		return rc;
+	}
+	error->type = RTE_TM_ERROR_TYPE_NONE;
+	roc_nix_tm_shaper_default_red_algo(&node->nix_node, profile);
+
+	return 0;
+}
+
+static int
+cnxk_nix_tm_node_delete(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	struct cnxk_nix_tm_node *node;
+	int rc;
+
+	/* we don't support dynamic updates yet */
+	if (roc_nix_tm_is_user_hierarchy_enabled(nix)) {
+		error->type = RTE_TM_ERROR_TYPE_CAPABILITIES;
+		error->message = "hierarchy exists";
+		return -EIO;
+	}
+
+	if (node_id == RTE_TM_NODE_ID_NULL) {
+		error->type = RTE_TM_ERROR_TYPE_NODE_ID;
+		error->message = "invalid node id";
+		return -EINVAL;
+	}
+
+	node = (struct cnxk_nix_tm_node *)roc_nix_tm_node_get(nix, node_id);
+
+	rc = roc_nix_tm_node_delete(nix, node_id, 0);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	} else {
+		rte_free(node);
+	}
+
+	return rc;
+}
+
+static int
+cnxk_nix_tm_node_suspend(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			 struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	int rc;
+
+	rc = roc_nix_tm_node_suspend_resume(&dev->nix, node_id, true);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	}
+
+	return rc;
+}
+
+static int
+cnxk_nix_tm_node_resume(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	int rc;
+
+	rc = roc_nix_tm_node_suspend_resume(&dev->nix, node_id, false);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	}
+
+	return rc;
+}
+
+static int
+cnxk_nix_tm_hierarchy_commit(struct rte_eth_dev *eth_dev,
+			     int clear_on_fail __rte_unused,
+			     struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	int rc;
+
+	if (roc_nix_tm_is_user_hierarchy_enabled(nix)) {
+		error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
+		error->message = "hierarchy exists";
+		return -EIO;
+	}
+
+	if (roc_nix_tm_leaf_cnt(nix) < dev->nb_txq) {
+		error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
+		error->message = "incomplete hierarchy";
+		return -EINVAL;
+	}
+
+	rc = roc_nix_tm_hierarchy_disable(nix);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+		return -EIO;
+	}
+
+	rc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_USER, true);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+		return -EIO;
+	}
+	error->type = RTE_TM_ERROR_TYPE_NONE;
+
+	return 0;
+}
+
+static int
+cnxk_nix_tm_node_shaper_update(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			       uint32_t profile_id, struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix_tm_shaper_profile *profile;
+	struct roc_nix *nix = &dev->nix;
+	struct roc_nix_tm_node *node;
+	int rc;
+
+	rc = roc_nix_tm_node_shaper_update(nix, node_id, profile_id, false);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+		return -EINVAL;
+	}
+	node = roc_nix_tm_node_get(nix, node_id);
+	if (!node)
+		return -EINVAL;
+
+	profile = roc_nix_tm_shaper_profile_get(nix, profile_id);
+	roc_nix_tm_shaper_default_red_algo(node, profile);
+
+	return 0;
+}
+
+static int
+cnxk_nix_tm_node_parent_update(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			       uint32_t new_parent_id, uint32_t priority,
+			       uint32_t weight, struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix *nix = &dev->nix;
+	int rc;
+
+	rc = roc_nix_tm_node_parent_update(nix, node_id, new_parent_id,
+					   priority, weight);
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+cnxk_nix_tm_node_stats_read(struct rte_eth_dev *eth_dev, uint32_t node_id,
+			    struct rte_tm_node_stats *stats,
+			    uint64_t *stats_mask, int clear,
+			    struct rte_tm_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix_tm_node_stats nix_tm_stats;
+	struct roc_nix *nix = &dev->nix;
+	struct roc_nix_tm_node *node;
+	int rc;
+
+	node = roc_nix_tm_node_get(nix, node_id);
+	if (!node) {
+		error->type = RTE_TM_ERROR_TYPE_NODE_ID;
+		error->message = "no such node";
+		return -EINVAL;
+	}
+
+	if (roc_nix_tm_lvl_is_leaf(nix, node->lvl)) {
+		struct roc_nix_stats_queue qstats;
+
+		rc = roc_nix_stats_queue_get(nix, node->id, 0, &qstats);
+		if (!rc) {
+			stats->n_pkts = qstats.tx_pkts;
+			stats->n_bytes = qstats.tx_octs;
+			*stats_mask =
+				RTE_TM_STATS_N_PKTS | RTE_TM_STATS_N_BYTES;
+		}
+		goto exit;
+	}
+
+	rc = roc_nix_tm_node_stats_get(nix, node_id, clear, &nix_tm_stats);
+	if (!rc) {
+		stats->leaf.n_pkts_dropped[RTE_COLOR_RED] =
+			nix_tm_stats.stats[ROC_NIX_TM_NODE_PKTS_DROPPED];
+		stats->leaf.n_bytes_dropped[RTE_COLOR_RED] =
+			nix_tm_stats.stats[ROC_NIX_TM_NODE_BYTES_DROPPED];
+		*stats_mask = RTE_TM_STATS_N_PKTS_RED_DROPPED |
+			      RTE_TM_STATS_N_BYTES_RED_DROPPED;
+	}
+
+exit:
+	if (rc) {
+		error->type = roc_nix_tm_err_to_rte_err(rc);
+		error->message = roc_error_msg_get(rc);
+	}
+	return rc;
+}
+
 const struct rte_tm_ops cnxk_tm_ops = {
 	.node_type_get = cnxk_nix_tm_node_type_get,
 	.capabilities_get = cnxk_nix_tm_capa_get,
 	.level_capabilities_get = cnxk_nix_tm_level_capa_get,
 	.node_capabilities_get = cnxk_nix_tm_node_capa_get,
+
+	.shaper_profile_add = cnxk_nix_tm_shaper_profile_add,
+	.shaper_profile_delete = cnxk_nix_tm_shaper_profile_delete,
+
+	.node_add = cnxk_nix_tm_node_add,
+	.node_delete = cnxk_nix_tm_node_delete,
+	.node_suspend = cnxk_nix_tm_node_suspend,
+	.node_resume = cnxk_nix_tm_node_resume,
+	.hierarchy_commit = cnxk_nix_tm_hierarchy_commit,
+
+	.node_shaper_update = cnxk_nix_tm_node_shaper_update,
+	.node_parent_update = cnxk_nix_tm_node_parent_update,
+	.node_stats_read = cnxk_nix_tm_node_stats_read,
 };
 
 int
diff --git a/drivers/net/cnxk/cnxk_tm.h b/drivers/net/cnxk/cnxk_tm.h
index f7470c2..419c551 100644
--- a/drivers/net/cnxk/cnxk_tm.h
+++ b/drivers/net/cnxk/cnxk_tm.h
@@ -15,4 +15,9 @@ struct cnxk_nix_tm_node {
 	struct rte_tm_node_params params;
 };
 
+struct cnxk_nix_tm_shaper_profile {
+	struct roc_nix_tm_shaper_profile profile;
+	struct rte_tm_shaper_params params; /* Rate in bits/sec */
+};
+
 #endif /* __CNXK_TM_H__ */
-- 
1.8.3.1


  parent reply	other threads:[~2021-09-18 14:33 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-01 17:10 [dpdk-dev] [PATCH 1/8] common/cnxk: use different macros for sdp and lbk max frames skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 2/8] common/cnxk: flush smq skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 3/8] common/cnxk: increase sched weight and shaper burst limit skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 4/8] common/cnxk: handle packet mode shaper limits skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 5/8] common/cnxk: handler to get rte tm error type skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 6/8] common/cnxk: set of handlers to get tm hierarchy internals skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 7/8] net/cnxk: tm capabilities and queue rate limit handlers skoteshwar
2021-09-01 17:10 ` [dpdk-dev] [PATCH 8/8] net/cnxk: tm shaper and node operations skoteshwar
2021-09-16  7:17 ` [dpdk-dev] [PATCH 1/8] common/cnxk: use different macros for sdp and lbk max frames Jerin Jacob
2021-09-18 14:31 ` [dpdk-dev] [PATCH v2 0/8] Add TM Support for CN9K and CN10K skoteshwar
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 1/8] common/cnxk: use different macros for sdp and lbk max frames skoteshwar
2021-09-21  6:35     ` Jerin Jacob
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 2/8] common/cnxk: flush smq skoteshwar
2021-09-21  6:37     ` Jerin Jacob
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 3/8] common/cnxk: increase sched weight and shaper burst limit skoteshwar
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 4/8] common/cnxk: handle packet mode shaper limits skoteshwar
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 5/8] common/cnxk: handler to get rte tm error type skoteshwar
2021-09-21  6:41     ` Jerin Jacob
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 6/8] common/cnxk: set of handlers to get tm hierarchy internals skoteshwar
2021-09-18 14:31   ` [dpdk-dev] [PATCH v2 7/8] net/cnxk: tm capabilities and queue rate limit handlers skoteshwar
2021-09-21  6:43     ` Jerin Jacob
2021-09-18 14:31   ` skoteshwar [this message]
2021-09-20  8:59   ` [dpdk-dev] [PATCH v2 0/8] Add TM Support for CN9K and CN10K nithind1988
2021-09-22  6:11 ` [dpdk-dev] [PATCH v3 " skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 1/8] common/cnxk: set appropriate max frame size for SDP and LBK skoteshwar
2021-09-27 13:29     ` Jerin Jacob
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 2/8] common/cnxk: support SMQ flush skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 3/8] common/cnxk: increase sched weight and shaper burst limit skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 4/8] common/cnxk: handle packet mode shaper limits skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 5/8] common/cnxk: support TM error type get skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 6/8] common/cnxk: set of handlers to get TM hierarchy internals skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 7/8] net/cnxk: TM capabilities and queue rate limit handlers skoteshwar
2021-09-22  6:11   ` [dpdk-dev] [PATCH v3 8/8] net/cnxk: TM shaper and node operations skoteshwar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1631975519-30924-9-git-send-email-skoteshwar@marvell.com \
    --to=skoteshwar@marvell.com \
    --cc=dev@dpdk.org \
    --cc=kirankumark@marvell.com \
    --cc=ndabilpuram@marvell.com \
    --cc=skori@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).