net/ice: refine debug build option
[dpdk.git] / drivers / common / cnxk / roc_nix_tm.c
index 581de4b..ad54e17 100644 (file)
@@ -30,6 +30,93 @@ nix_tm_clear_shaper_profiles(struct nix *nix)
        }
 }
 
+static int
+nix_tm_node_reg_conf(struct nix *nix, struct nix_tm_node *node)
+{
+       uint64_t regval_mask[MAX_REGS_PER_MBOX_MSG];
+       uint64_t regval[MAX_REGS_PER_MBOX_MSG];
+       struct nix_tm_shaper_profile *profile;
+       uint64_t reg[MAX_REGS_PER_MBOX_MSG];
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_txschq_config *req;
+       int rc = -EFAULT;
+       uint32_t hw_lvl;
+       uint8_t k = 0;
+
+       memset(regval, 0, sizeof(regval));
+       memset(regval_mask, 0, sizeof(regval_mask));
+
+       profile = nix_tm_shaper_profile_search(nix, node->shaper_profile_id);
+       hw_lvl = node->hw_lvl;
+
+       /* Need this trigger to configure TL1 */
+       if (!nix_tm_have_tl1_access(nix) && hw_lvl == NIX_TXSCH_LVL_TL2) {
+               /* Prepare default conf for TL1 */
+               req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+               req->lvl = NIX_TXSCH_LVL_TL1;
+
+               k = nix_tm_tl1_default_prep(node->parent_hw_id, req->reg,
+                                           req->regval);
+               req->num_regs = k;
+               rc = mbox_process(mbox);
+               if (rc)
+                       goto error;
+       }
+
+       /* Prepare topology config */
+       k = nix_tm_topology_reg_prep(nix, node, reg, regval, regval_mask);
+
+       /* Prepare schedule config */
+       k += nix_tm_sched_reg_prep(nix, node, &reg[k], &regval[k]);
+
+       /* Prepare shaping config */
+       k += nix_tm_shaper_reg_prep(node, profile, &reg[k], &regval[k]);
+
+       if (!k)
+               return 0;
+
+       /* Copy and send config mbox */
+       req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+       req->lvl = hw_lvl;
+       req->num_regs = k;
+
+       mbox_memcpy(req->reg, reg, sizeof(uint64_t) * k);
+       mbox_memcpy(req->regval, regval, sizeof(uint64_t) * k);
+       mbox_memcpy(req->regval_mask, regval_mask, sizeof(uint64_t) * k);
+
+       rc = mbox_process(mbox);
+       if (rc)
+               goto error;
+
+       return 0;
+error:
+       plt_err("Txschq conf failed for node %p, rc=%d", node, rc);
+       return rc;
+}
+
+int
+nix_tm_txsch_reg_config(struct nix *nix, enum roc_nix_tm_tree tree)
+{
+       struct nix_tm_node_list *list;
+       struct nix_tm_node *node;
+       uint32_t hw_lvl;
+       int rc = 0;
+
+       list = nix_tm_node_list(nix, tree);
+
+       for (hw_lvl = 0; hw_lvl <= nix->tm_root_lvl; hw_lvl++) {
+               TAILQ_FOREACH(node, list, node) {
+                       if (node->hw_lvl != hw_lvl)
+                               continue;
+                       rc = nix_tm_node_reg_conf(nix, node);
+                       if (rc)
+                               goto exit;
+               }
+       }
+exit:
+       return rc;
+}
+
 int
 nix_tm_update_parent_info(struct nix *nix, enum roc_nix_tm_tree tree)
 {
@@ -306,6 +393,7 @@ roc_nix_tm_sq_flush_spin(struct roc_nix_sq *sq)
 
        return 0;
 exit:
+       roc_nix_tm_dump(sq->roc_nix);
        roc_nix_queues_ctx_dump(sq->roc_nix);
        return -EFAULT;
 }
@@ -477,6 +565,66 @@ nix_tm_sq_flush_post(struct roc_nix_sq *sq)
        return 0;
 }
 
+int
+nix_tm_sq_sched_conf(struct nix *nix, struct nix_tm_node *node,
+                    bool rr_quantum_only)
+{
+       struct mbox *mbox = (&nix->dev)->mbox;
+       uint16_t qid = node->id, smq;
+       uint64_t rr_quantum;
+       int rc;
+
+       smq = node->parent->hw_id;
+       rr_quantum = nix_tm_weight_to_rr_quantum(node->weight);
+
+       if (rr_quantum_only)
+               plt_tm_dbg("Update sq(%u) rr_quantum 0x%" PRIx64, qid,
+                          rr_quantum);
+       else
+               plt_tm_dbg("Enabling sq(%u)->smq(%u), rr_quantum 0x%" PRIx64,
+                          qid, smq, rr_quantum);
+
+       if (qid > nix->nb_tx_queues)
+               return -EFAULT;
+
+       if (roc_model_is_cn9k()) {
+               struct nix_aq_enq_req *aq;
+
+               aq = mbox_alloc_msg_nix_aq_enq(mbox);
+               aq->qidx = qid;
+               aq->ctype = NIX_AQ_CTYPE_SQ;
+               aq->op = NIX_AQ_INSTOP_WRITE;
+
+               /* smq update only when needed */
+               if (!rr_quantum_only) {
+                       aq->sq.smq = smq;
+                       aq->sq_mask.smq = ~aq->sq_mask.smq;
+               }
+               aq->sq.smq_rr_quantum = rr_quantum;
+               aq->sq_mask.smq_rr_quantum = ~aq->sq_mask.smq_rr_quantum;
+       } else {
+               struct nix_cn10k_aq_enq_req *aq;
+
+               aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+               aq->qidx = qid;
+               aq->ctype = NIX_AQ_CTYPE_SQ;
+               aq->op = NIX_AQ_INSTOP_WRITE;
+
+               /* smq update only when needed */
+               if (!rr_quantum_only) {
+                       aq->sq.smq = smq;
+                       aq->sq_mask.smq = ~aq->sq_mask.smq;
+               }
+               aq->sq.smq_rr_weight = rr_quantum;
+               aq->sq_mask.smq_rr_weight = ~aq->sq_mask.smq_rr_weight;
+       }
+
+       rc = mbox_process(mbox);
+       if (rc)
+               plt_err("Failed to set smq, rc=%d", rc);
+       return rc;
+}
+
 int
 nix_tm_release_resources(struct nix *nix, uint8_t hw_lvl, bool contig,
                         bool above_thresh)
@@ -941,6 +1089,162 @@ alloc_err:
        return rc;
 }
 
+int
+nix_tm_prepare_default_tree(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       uint32_t nonleaf_id = nix->nb_tx_queues;
+       struct nix_tm_node *node = NULL;
+       uint8_t leaf_lvl, lvl, lvl_end;
+       uint32_t parent, i;
+       int rc = 0;
+
+       /* Add ROOT, SCH1, SCH2, SCH3, [SCH4]  nodes */
+       parent = ROC_NIX_TM_NODE_ID_INVALID;
+       /* With TL1 access we have an extra level */
+       lvl_end = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_SCH4 :
+                                                      ROC_TM_LVL_SCH3);
+
+       for (lvl = ROC_TM_LVL_ROOT; lvl <= lvl_end; lvl++) {
+               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_DEFAULT;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+               parent = nonleaf_id;
+               nonleaf_id++;
+       }
+
+       parent = nonleaf_id - 1;
+       leaf_lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_QUEUE :
+                                                       ROC_TM_LVL_SCH4);
+
+       /* Add leaf nodes */
+       for (i = 0; i < nix->nb_tx_queues; i++) {
+               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_DEFAULT;
+
+               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_prepare_rate_limited_tree(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       uint32_t nonleaf_id = nix->nb_tx_queues;
+       struct nix_tm_node *node = NULL;
+       uint8_t leaf_lvl, lvl, lvl_end;
+       uint32_t parent, i;
+       int rc = 0;
+
+       /* Add ROOT, SCH1, SCH2 nodes */
+       parent = ROC_NIX_TM_NODE_ID_INVALID;
+       lvl_end = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_SCH3 :
+                                                      ROC_TM_LVL_SCH2);
+
+       for (lvl = ROC_TM_LVL_ROOT; lvl <= lvl_end; lvl++) {
+               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_RLIMIT;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+               parent = nonleaf_id;
+               nonleaf_id++;
+       }
+
+       /* SMQ is mapped to SCH4 when we have TL1 access and SCH3 otherwise */
+       lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_SCH4 : ROC_TM_LVL_SCH3);
+
+       /* Add per queue SMQ nodes i.e SCH4 / SCH3 */
+       for (i = 0; i < nix->nb_tx_queues; i++) {
+               rc = -ENOMEM;
+               node = nix_tm_node_alloc();
+               if (!node)
+                       goto error;
+
+               node->id = nonleaf_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 = lvl;
+               node->tree = ROC_NIX_TM_RLIMIT;
+
+               rc = nix_tm_node_add(roc_nix, node);
+               if (rc)
+                       goto error;
+       }
+
+       parent = nonleaf_id;
+       leaf_lvl = (nix_tm_have_tl1_access(nix) ? ROC_TM_LVL_QUEUE :
+                                                       ROC_TM_LVL_SCH4);
+
+       /* Add leaf nodes */
+       for (i = 0; i < nix->nb_tx_queues; i++) {
+               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_RLIMIT;
+
+               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)
 {