From: Satha Rao <[email protected]>

Create a new default tree for the SDP interface if more than one TX
queue is requested. This helps to backpressure each queue independently
when they are created with separate channels.

Signed-off-by: Satha Rao <[email protected]>
---

v5:
- Rebase to ToT

v4:
- Further split patch 19/19 to 5 patches.

v3:
- Fixed usage of rte_atomic in common/cnxk folder.

v2:
- Handled comments related to commit messages
- Fixed typo

 drivers/common/cnxk/roc_nix.h                 |   2 +
 drivers/common/cnxk/roc_nix_priv.h            |   2 +
 drivers/common/cnxk/roc_nix_tm.c              | 158 ++++++++++++++++++
 drivers/common/cnxk/roc_nix_tm_ops.c          |   5 +-
 drivers/common/cnxk/roc_nix_tm_utils.c        |   2 +-
 .../common/cnxk/roc_platform_base_symbols.c   |   1 +
 6 files changed, 168 insertions(+), 2 deletions(-)

diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index a62ddf4732..f4b9236486 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -689,6 +689,7 @@ enum roc_nix_tm_tree {
        ROC_NIX_TM_DEFAULT = 0,
        ROC_NIX_TM_RLIMIT,
        ROC_NIX_TM_PFC,
+       ROC_NIX_TM_SDP,
        ROC_NIX_TM_USER,
        ROC_NIX_TM_TREE_MAX,
 };
@@ -861,6 +862,7 @@ int __roc_api roc_nix_tm_lvl_cnt_get(struct roc_nix 
*roc_nix);
 int __roc_api roc_nix_tm_lvl_have_link_access(struct roc_nix *roc_nix, int 
lvl);
 int __roc_api roc_nix_tm_prepare_rate_limited_tree(struct roc_nix *roc_nix);
 int __roc_api roc_nix_tm_pfc_prepare_tree(struct roc_nix *roc_nix);
+int __roc_api roc_nix_tm_sdp_prepare_tree(struct roc_nix *roc_nix);
 bool __roc_api roc_nix_tm_is_user_hierarchy_enabled(struct roc_nix *nix);
 int __roc_api roc_nix_tm_tree_type_get(struct roc_nix *nix);
 int __roc_api roc_nix_tm_mark_config(struct roc_nix *roc_nix,
diff --git a/drivers/common/cnxk/roc_nix_priv.h 
b/drivers/common/cnxk/roc_nix_priv.h
index c949621196..f1fcee2acb 100644
--- a/drivers/common/cnxk/roc_nix_priv.h
+++ b/drivers/common/cnxk/roc_nix_priv.h
@@ -389,6 +389,8 @@ nix_tm_tree2str(enum roc_nix_tm_tree tree)
                return "Rate Limit Tree";
        else if (tree == ROC_NIX_TM_PFC)
                return "PFC Tree";
+       else if (tree == ROC_NIX_TM_SDP)
+               return "SDP Tree";
        else if (tree == ROC_NIX_TM_USER)
                return "User Tree";
        return "???";
diff --git a/drivers/common/cnxk/roc_nix_tm.c b/drivers/common/cnxk/roc_nix_tm.c
index abfe80978b..2771fd8fc4 100644
--- a/drivers/common/cnxk/roc_nix_tm.c
+++ b/drivers/common/cnxk/roc_nix_tm.c
@@ -1890,6 +1890,164 @@ roc_nix_tm_pfc_prepare_tree(struct roc_nix *roc_nix)
        return rc;
 }
 
+int
+roc_nix_tm_sdp_prepare_tree(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       uint32_t nonleaf_id = nix->nb_tx_queues;
+       uint32_t tl2_node_id, tl3_node_id;
+       uint8_t leaf_lvl, lvl, lvl_start;
+       struct nix_tm_node *node = NULL;
+       uint32_t parent, i;
+       int rc = -ENOMEM;
+
+       parent = ROC_NIX_TM_NODE_ID_INVALID;
+       leaf_lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_QUEUE : 
ROC_TM_LVL_SCH4);
+
+       /* TL1 node */
+       node = nix_tm_node_alloc();
+       if (!node)
+               goto error;
+
+       node->id = nonleaf_id;
+       node->parent_id = parent;
+       node->priority = 0;
+       node->weight = NIX_TM_DFLT_RR_WT;
+       node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+       node->lvl = ROC_TM_LVL_ROOT;
+       node->tree = ROC_NIX_TM_SDP;
+       node->rel_chan = NIX_TM_CHAN_INVALID;
+
+       rc = nix_tm_node_add(roc_nix, node);
+       if (rc)
+               goto error;
+
+       parent = nonleaf_id;
+       nonleaf_id++;
+
+       lvl_start = ROC_TM_LVL_SCH1;
+       if (roc_nix_is_pf(roc_nix)) {
+               /* TL2 node */
+               rc = -ENOMEM;
+               node = nix_tm_node_alloc();
+               if (!node)
+                       goto error;
+
+               node->id = nonleaf_id;
+               node->parent_id = parent;
+               node->priority = 0;
+               node->weight = NIX_TM_DFLT_RR_WT;
+               node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+               node->lvl = ROC_TM_LVL_SCH1;
+               node->tree = ROC_NIX_TM_SDP;
+               node->rel_chan = NIX_TM_CHAN_INVALID;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+
+               lvl_start = ROC_TM_LVL_SCH2;
+               tl2_node_id = nonleaf_id;
+               nonleaf_id++;
+       } else {
+               tl2_node_id = parent;
+       }
+
+       /* Allocate TL3 node */
+       rc = -ENOMEM;
+       node = nix_tm_node_alloc();
+       if (!node)
+               goto error;
+
+       node->id = nonleaf_id;
+       node->parent_id = tl2_node_id;
+       node->priority = 0;
+       node->weight = NIX_TM_DFLT_RR_WT;
+       node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+       node->lvl = lvl_start;
+       node->tree = ROC_NIX_TM_SDP;
+       node->rel_chan = NIX_TM_CHAN_INVALID;
+
+       rc = nix_tm_node_add(roc_nix, node);
+       if (rc)
+               goto error;
+
+       tl3_node_id = nonleaf_id;
+       nonleaf_id++;
+       lvl_start++;
+
+       for (i = 0; i < nix->nb_tx_queues; i++) {
+               parent = tl3_node_id;
+               rc = -ENOMEM;
+               node = nix_tm_node_alloc();
+               if (!node)
+                       goto error;
+
+               node->id = nonleaf_id;
+               node->parent_id = parent;
+               node->priority = 0;
+               node->weight = NIX_TM_DFLT_RR_WT;
+               node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+               node->lvl = lvl_start;
+               node->tree = ROC_NIX_TM_SDP;
+               /* For SDP, if BP enabled use channel to PAUSE the 
corresponding queue */
+               node->rel_chan = (i % nix->tx_chan_cnt);
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+
+               parent = nonleaf_id;
+               nonleaf_id++;
+
+               lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_SCH4 : 
ROC_TM_LVL_SCH3);
+
+               rc = -ENOMEM;
+               node = nix_tm_node_alloc();
+               if (!node)
+                       goto error;
+
+               node->id = nonleaf_id;
+               node->parent_id = parent;
+               node->priority = 0;
+               node->weight = NIX_TM_DFLT_RR_WT;
+               node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+               node->lvl = lvl;
+               node->tree = ROC_NIX_TM_SDP;
+               node->rel_chan = NIX_TM_CHAN_INVALID;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+
+               parent = nonleaf_id;
+               nonleaf_id++;
+
+               rc = -ENOMEM;
+               node = nix_tm_node_alloc();
+               if (!node)
+                       goto error;
+
+               node->id = i;
+               node->parent_id = parent;
+               node->priority = 0;
+               node->weight = NIX_TM_DFLT_RR_WT;
+               node->shaper_profile_id = ROC_NIX_TM_SHAPER_PROFILE_NONE;
+               node->lvl = leaf_lvl;
+               node->tree = ROC_NIX_TM_SDP;
+               node->rel_chan = NIX_TM_CHAN_INVALID;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+       }
+
+       return 0;
+error:
+       nix_tm_node_free(node);
+       return rc;
+}
+
 int
 nix_tm_free_resources(struct roc_nix *roc_nix, uint32_t tree_mask, bool 
hw_only)
 {
diff --git a/drivers/common/cnxk/roc_nix_tm_ops.c 
b/drivers/common/cnxk/roc_nix_tm_ops.c
index b89f08ac66..951c310a56 100644
--- a/drivers/common/cnxk/roc_nix_tm_ops.c
+++ b/drivers/common/cnxk/roc_nix_tm_ops.c
@@ -1035,7 +1035,10 @@ roc_nix_tm_init(struct roc_nix *roc_nix)
        }
 
        /* Prepare default tree */
-       rc = nix_tm_prepare_default_tree(roc_nix);
+       if (roc_nix_is_sdp(roc_nix) && (nix->nb_tx_queues > 1))
+               rc = roc_nix_tm_sdp_prepare_tree(roc_nix);
+       else
+               rc = nix_tm_prepare_default_tree(roc_nix);
        if (rc) {
                plt_err("failed to prepare default tm tree, rc=%d", rc);
                return rc;
diff --git a/drivers/common/cnxk/roc_nix_tm_utils.c 
b/drivers/common/cnxk/roc_nix_tm_utils.c
index 4a09cc2aae..eaf6f9e4c7 100644
--- a/drivers/common/cnxk/roc_nix_tm_utils.c
+++ b/drivers/common/cnxk/roc_nix_tm_utils.c
@@ -582,7 +582,7 @@ nix_tm_topology_reg_prep(struct nix *nix, struct 
nix_tm_node *node,
 
                /* Configure TL4 to send to SDP channel instead of CGX/LBK */
                if (nix->sdp_link) {
-                       relchan = nix->tx_chan_base & 0xff;
+                       relchan = (nix->tx_chan_base & 0xff) + node->rel_chan;
                        plt_tm_dbg("relchan=%u schq=%u tx_chan_cnt=%u", 
relchan, schq,
                                   nix->tx_chan_cnt);
                        reg[k] = NIX_AF_TL4X_SDP_LINK_CFG(schq);
diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c 
b/drivers/common/cnxk/roc_platform_base_symbols.c
index ff64e82914..40d5cd290b 100644
--- a/drivers/common/cnxk/roc_platform_base_symbols.c
+++ b/drivers/common/cnxk/roc_platform_base_symbols.c
@@ -223,6 +223,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_dump)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_cq_dump)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_sq_dump)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_tm_dump)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_tm_sdp_prepare_tree)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_dump)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_inl_dev_dump)
 RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_inl_outb_cpt_lfs_dump)
-- 
2.34.1

Reply via email to