common/cnxk: support NIX TM debug and misc utils
authorNithin Dabilpuram <ndabilpuram@marvell.com>
Tue, 6 Apr 2021 14:41:31 +0000 (20:11 +0530)
committerJerin Jacob <jerinj@marvell.com>
Fri, 9 Apr 2021 06:32:24 +0000 (08:32 +0200)
Add support to dump TM HW registers and hierarchy on error.
This patch also adds support for misc utils such as API to
query TM HW resource availability, resource pre-allocation
and static priority support on root node.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
drivers/common/cnxk/roc_nix.h
drivers/common/cnxk/roc_nix_debug.c
drivers/common/cnxk/roc_nix_tm.c
drivers/common/cnxk/roc_nix_tm_ops.c
drivers/common/cnxk/roc_nix_tm_utils.c
drivers/common/cnxk/roc_utils.c
drivers/common/cnxk/version.map

index ad00efe..b39f461 100644 (file)
@@ -291,6 +291,7 @@ void __roc_api roc_nix_cqe_dump(const struct nix_cqe_hdr_s *cq);
 void __roc_api roc_nix_rq_dump(struct roc_nix_rq *rq);
 void __roc_api roc_nix_cq_dump(struct roc_nix_cq *cq);
 void __roc_api roc_nix_sq_dump(struct roc_nix_sq *sq);
+void __roc_api roc_nix_tm_dump(struct roc_nix *roc_nix);
 void __roc_api roc_nix_dump(struct roc_nix *roc_nix);
 
 /* IRQ */
@@ -394,6 +395,10 @@ int __roc_api roc_nix_tm_shaper_profile_update(
 int __roc_api roc_nix_tm_shaper_profile_delete(struct roc_nix *roc_nix,
                                               uint32_t id);
 
+int __roc_api roc_nix_tm_prealloc_res(struct roc_nix *roc_nix, uint8_t lvl,
+                                     uint16_t discontig, uint16_t contig);
+uint16_t __roc_api roc_nix_tm_leaf_cnt(struct roc_nix *roc_nix);
+
 struct roc_nix_tm_node *__roc_api roc_nix_tm_node_get(struct roc_nix *roc_nix,
                                                      uint32_t node_id);
 struct roc_nix_tm_node *__roc_api
@@ -420,6 +425,10 @@ int __roc_api roc_nix_tm_hierarchy_enable(struct roc_nix *roc_nix,
  * TM utilities API.
  */
 int __roc_api roc_nix_tm_node_lvl(struct roc_nix *roc_nix, uint32_t node_id);
+bool __roc_api roc_nix_tm_root_has_sp(struct roc_nix *roc_nix);
+void __roc_api roc_nix_tm_rsrc_max(bool pf, uint16_t schq[ROC_TM_LVL_MAX]);
+int __roc_api roc_nix_tm_rsrc_count(struct roc_nix *roc_nix,
+                                   uint16_t schq[ROC_TM_LVL_MAX]);
 int __roc_api roc_nix_tm_node_name_get(struct roc_nix *roc_nix,
                                       uint32_t node_id, char *buf,
                                       size_t buflen);
index a0cf98e..6e56513 100644 (file)
@@ -44,6 +44,33 @@ static const struct nix_lf_reg_info nix_lf_reg[] = {
        NIX_REG_INFO(NIX_LF_SEND_ERR_DBG),
 };
 
+static void
+nix_bitmap_dump(struct plt_bitmap *bmp)
+{
+       uint32_t pos = 0, start_pos;
+       uint64_t slab = 0;
+       int i;
+
+       plt_bitmap_scan_init(bmp);
+       plt_bitmap_scan(bmp, &pos, &slab);
+       start_pos = pos;
+
+       nix_dump_no_nl("  \t\t[");
+       do {
+               if (!slab)
+                       break;
+               i = 0;
+
+               for (i = 0; i < 64; i++)
+                       if (slab & (1ULL << i))
+                               nix_dump_no_nl("%d, ", i);
+
+               if (!plt_bitmap_scan(bmp, &pos, &slab))
+                       break;
+       } while (start_pos != pos);
+       nix_dump_no_nl(" ]");
+}
+
 int
 roc_nix_lf_get_reg_count(struct roc_nix *roc_nix)
 {
@@ -761,6 +788,309 @@ roc_nix_sq_dump(struct roc_nix_sq *sq)
        nix_dump("  fc = %p", sq->fc);
 };
 
+static uint8_t
+nix_tm_reg_dump_prep(uint16_t hw_lvl, uint16_t schq, uint16_t link,
+                    uint64_t *reg, char regstr[][NIX_REG_NAME_SZ])
+{
+       uint8_t k = 0;
+
+       switch (hw_lvl) {
+       case NIX_TXSCH_LVL_SMQ:
+               reg[k] = NIX_AF_SMQX_CFG(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_SMQ[%u]_CFG",
+                        schq);
+
+               reg[k] = NIX_AF_MDQX_PARENT(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_MDQ[%u]_PARENT",
+                        schq);
+
+               reg[k] = NIX_AF_MDQX_SCHEDULE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_MDQ[%u]_SCHEDULE", schq);
+
+               reg[k] = NIX_AF_MDQX_PIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_MDQ[%u]_PIR",
+                        schq);
+
+               reg[k] = NIX_AF_MDQX_CIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_MDQ[%u]_CIR",
+                        schq);
+
+               reg[k] = NIX_AF_MDQX_SHAPE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_MDQ[%u]_SHAPE",
+                        schq);
+
+               reg[k] = NIX_AF_MDQX_SW_XOFF(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_MDQ[%u]_SW_XOFF",
+                        schq);
+               break;
+       case NIX_TXSCH_LVL_TL4:
+               reg[k] = NIX_AF_TL4X_PARENT(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL4[%u]_PARENT",
+                        schq);
+
+               reg[k] = NIX_AF_TL4X_TOPOLOGY(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL4[%u]_TOPOLOGY", schq);
+
+               reg[k] = NIX_AF_TL4X_SDP_LINK_CFG(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL4[%u]_SDP_LINK_CFG", schq);
+
+               reg[k] = NIX_AF_TL4X_SCHEDULE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL4[%u]_SCHEDULE", schq);
+
+               reg[k] = NIX_AF_TL4X_PIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL4[%u]_PIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL4X_CIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL4[%u]_CIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL4X_SHAPE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL4[%u]_SHAPE",
+                        schq);
+
+               reg[k] = NIX_AF_TL4X_SW_XOFF(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL4[%u]_SW_XOFF",
+                        schq);
+               break;
+       case NIX_TXSCH_LVL_TL3:
+               reg[k] = NIX_AF_TL3X_PARENT(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL3[%u]_PARENT",
+                        schq);
+
+               reg[k] = NIX_AF_TL3X_TOPOLOGY(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL3[%u]_TOPOLOGY", schq);
+
+               reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, link);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq, link);
+
+               reg[k] = NIX_AF_TL3X_SCHEDULE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL3[%u]_SCHEDULE", schq);
+
+               reg[k] = NIX_AF_TL3X_PIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL3[%u]_PIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL3X_CIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL3[%u]_CIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL3X_SHAPE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL3[%u]_SHAPE",
+                        schq);
+
+               reg[k] = NIX_AF_TL3X_SW_XOFF(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL3[%u]_SW_XOFF",
+                        schq);
+               break;
+       case NIX_TXSCH_LVL_TL2:
+               reg[k] = NIX_AF_TL2X_PARENT(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL2[%u]_PARENT",
+                        schq);
+
+               reg[k] = NIX_AF_TL2X_TOPOLOGY(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL2[%u]_TOPOLOGY", schq);
+
+               reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, link);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL3_TL2[%u]_LINK[%u]_CFG", schq, link);
+
+               reg[k] = NIX_AF_TL2X_SCHEDULE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL2[%u]_SCHEDULE", schq);
+
+               reg[k] = NIX_AF_TL2X_PIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL2[%u]_PIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL2X_CIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL2[%u]_CIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL2X_SHAPE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL2[%u]_SHAPE",
+                        schq);
+
+               reg[k] = NIX_AF_TL2X_SW_XOFF(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL2[%u]_SW_XOFF",
+                        schq);
+               break;
+       case NIX_TXSCH_LVL_TL1:
+
+               reg[k] = NIX_AF_TL1X_TOPOLOGY(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL1[%u]_TOPOLOGY", schq);
+
+               reg[k] = NIX_AF_TL1X_SCHEDULE(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL1[%u]_SCHEDULE", schq);
+
+               reg[k] = NIX_AF_TL1X_CIR(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL1[%u]_CIR",
+                        schq);
+
+               reg[k] = NIX_AF_TL1X_SW_XOFF(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ, "NIX_AF_TL1[%u]_SW_XOFF",
+                        schq);
+
+               reg[k] = NIX_AF_TL1X_DROPPED_PACKETS(schq);
+               snprintf(regstr[k++], NIX_REG_NAME_SZ,
+                        "NIX_AF_TL1[%u]_DROPPED_PACKETS", schq);
+               break;
+       default:
+               break;
+       }
+
+       if (k > MAX_REGS_PER_MBOX_MSG) {
+               nix_dump("\t!!!NIX TM Registers request overflow!!!");
+               return 0;
+       }
+       return k;
+}
+
+static void
+nix_tm_dump_lvl(struct nix *nix, struct nix_tm_node_list *list, uint8_t hw_lvl)
+{
+       char regstr[MAX_REGS_PER_MBOX_MSG * 2][NIX_REG_NAME_SZ];
+       uint64_t reg[MAX_REGS_PER_MBOX_MSG * 2];
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_txschq_config *req, *rsp;
+       const char *lvlstr, *parent_lvlstr;
+       struct nix_tm_node *node, *parent;
+       struct nix_tm_node *root = NULL;
+       uint32_t schq, parent_schq;
+       bool found = false;
+       uint8_t j, k, rc;
+
+       TAILQ_FOREACH(node, list, node) {
+               if (node->hw_lvl != hw_lvl)
+                       continue;
+
+               found = true;
+               parent = node->parent;
+               if (hw_lvl == NIX_TXSCH_LVL_CNT) {
+                       lvlstr = "SQ";
+                       schq = node->id;
+               } else {
+                       lvlstr = nix_tm_hwlvl2str(node->hw_lvl);
+                       schq = node->hw_id;
+               }
+
+               if (parent) {
+                       parent_schq = parent->hw_id;
+                       parent_lvlstr = nix_tm_hwlvl2str(parent->hw_lvl);
+               } else if (node->hw_lvl == NIX_TXSCH_LVL_TL1) {
+                       parent_schq = nix->tx_link;
+                       parent_lvlstr = "LINK";
+               } else {
+                       parent_schq = node->parent_hw_id;
+                       parent_lvlstr = nix_tm_hwlvl2str(node->hw_lvl + 1);
+               }
+
+               nix_dump("\t(%p%s) %s_%d->%s_%d", node,
+                        node->child_realloc ? "[CR]" : "", lvlstr, schq,
+                        parent_lvlstr, parent_schq);
+
+               if (!(node->flags & NIX_TM_NODE_HWRES))
+                       continue;
+
+               /* Need to dump TL1 when root is TL2 */
+               if (node->hw_lvl == nix->tm_root_lvl)
+                       root = node;
+
+               /* Dump registers only when HWRES is present */
+               k = nix_tm_reg_dump_prep(node->hw_lvl, schq, nix->tx_link, reg,
+                                        regstr);
+               if (!k)
+                       continue;
+
+               req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+               req->read = 1;
+               req->lvl = node->hw_lvl;
+               req->num_regs = k;
+               mbox_memcpy(req->reg, reg, sizeof(uint64_t) * k);
+               rc = mbox_process_msg(mbox, (void **)&rsp);
+               if (!rc) {
+                       for (j = 0; j < k; j++)
+                               nix_dump("\t\t%s=0x%016" PRIx64, regstr[j],
+                                        rsp->regval[j]);
+               } else {
+                       nix_dump("\t!!!Failed to dump registers!!!");
+               }
+       }
+
+       if (found)
+               nix_dump("\n");
+
+       /* Dump TL1 node data when root level is TL2 */
+       if (root && root->hw_lvl == NIX_TXSCH_LVL_TL2) {
+               k = nix_tm_reg_dump_prep(NIX_TXSCH_LVL_TL1, root->parent_hw_id,
+                                        nix->tx_link, reg, regstr);
+               if (!k)
+                       return;
+
+               req = mbox_alloc_msg_nix_txschq_cfg(mbox);
+               req->read = 1;
+               req->lvl = NIX_TXSCH_LVL_TL1;
+               req->num_regs = k;
+               mbox_memcpy(req->reg, reg, sizeof(uint64_t) * k);
+               rc = mbox_process_msg(mbox, (void **)&rsp);
+               if (!rc) {
+                       for (j = 0; j < k; j++)
+                               nix_dump("\t\t%s=0x%016" PRIx64, regstr[j],
+                                        rsp->regval[j]);
+               } else {
+                       nix_dump("\t!!!Failed to dump registers!!!");
+               }
+               nix_dump("\n");
+       }
+}
+
+void
+roc_nix_tm_dump(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct dev *dev = &nix->dev;
+       uint8_t hw_lvl, i;
+
+       nix_dump("===TM hierarchy and registers dump of %s (pf:vf) (%d:%d)===",
+                nix->pci_dev->name, dev_get_pf(dev->pf_func),
+                dev_get_vf(dev->pf_func));
+
+       /* Dump all trees */
+       for (i = 0; i < ROC_NIX_TM_TREE_MAX; i++) {
+               nix_dump("\tTM %s:", nix_tm_tree2str(i));
+               for (hw_lvl = 0; hw_lvl <= NIX_TXSCH_LVL_CNT; hw_lvl++)
+                       nix_tm_dump_lvl(nix, &nix->trees[i], hw_lvl);
+       }
+
+       /* Dump unused resources */
+       nix_dump("\tTM unused resources:");
+       hw_lvl = NIX_TXSCH_LVL_SMQ;
+       for (; hw_lvl < NIX_TXSCH_LVL_CNT; hw_lvl++) {
+               nix_dump("\t\ttxschq        %7s num = %d",
+                        nix_tm_hwlvl2str(hw_lvl),
+                        nix_tm_resource_avail(nix, hw_lvl, false));
+
+               nix_bitmap_dump(nix->schq_bmp[hw_lvl]);
+               nix_dump("\n");
+
+               nix_dump("\t\ttxschq_contig %7s num = %d",
+                        nix_tm_hwlvl2str(hw_lvl),
+                        nix_tm_resource_avail(nix, hw_lvl, true));
+               nix_bitmap_dump(nix->schq_contig_bmp[hw_lvl]);
+               nix_dump("\n");
+       }
+}
+
 void
 roc_nix_dump(struct roc_nix *roc_nix)
 {
index 9b328c9..ad54e17 100644 (file)
@@ -393,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;
 }
index e4463d1..ed244d4 100644 (file)
@@ -578,6 +578,58 @@ roc_nix_tm_node_suspend_resume(struct roc_nix *roc_nix, uint32_t node_id,
        return rc;
 }
 
+int
+roc_nix_tm_prealloc_res(struct roc_nix *roc_nix, uint8_t lvl,
+                       uint16_t discontig, uint16_t contig)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct nix_txsch_alloc_req *req;
+       struct nix_txsch_alloc_rsp *rsp;
+       uint8_t hw_lvl;
+       int rc = -ENOSPC;
+
+       hw_lvl = nix_tm_lvl2nix(nix, lvl);
+       if (hw_lvl == NIX_TXSCH_LVL_CNT)
+               return -EINVAL;
+
+       /* Preallocate contiguous */
+       if (nix->contig_rsvd[hw_lvl] < contig) {
+               req = mbox_alloc_msg_nix_txsch_alloc(mbox);
+               if (req == NULL)
+                       return rc;
+               req->schq_contig[hw_lvl] = contig - nix->contig_rsvd[hw_lvl];
+
+               rc = mbox_process_msg(mbox, (void *)&rsp);
+               if (rc)
+                       return rc;
+
+               nix_tm_copy_rsp_to_nix(nix, rsp);
+       }
+
+       /* Preallocate contiguous */
+       if (nix->discontig_rsvd[hw_lvl] < discontig) {
+               req = mbox_alloc_msg_nix_txsch_alloc(mbox);
+               if (req == NULL)
+                       return -ENOSPC;
+               req->schq[hw_lvl] = discontig - nix->discontig_rsvd[hw_lvl];
+
+               rc = mbox_process_msg(mbox, (void *)&rsp);
+               if (rc)
+                       return rc;
+
+               nix_tm_copy_rsp_to_nix(nix, rsp);
+       }
+
+       /* Save thresholds */
+       nix->contig_rsvd[hw_lvl] = contig;
+       nix->discontig_rsvd[hw_lvl] = discontig;
+       /* Release anything present above thresholds */
+       nix_tm_release_resources(nix, hw_lvl, true, true);
+       nix_tm_release_resources(nix, hw_lvl, false, true);
+       return 0;
+}
+
 int
 roc_nix_tm_node_shaper_update(struct roc_nix *roc_nix, uint32_t node_id,
                              uint32_t profile_id, bool force_update)
@@ -904,3 +956,76 @@ roc_nix_tm_fini(struct roc_nix *roc_nix)
        nix->tm_tree = 0;
        nix->tm_flags &= ~NIX_TM_HIERARCHY_ENA;
 }
+
+int
+roc_nix_tm_rsrc_count(struct roc_nix *roc_nix, uint16_t schq[ROC_TM_LVL_MAX])
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct mbox *mbox = (&nix->dev)->mbox;
+       struct free_rsrcs_rsp *rsp;
+       uint8_t hw_lvl;
+       int rc, i;
+
+       /* Get the current free resources */
+       mbox_alloc_msg_free_rsrc_cnt(mbox);
+       rc = mbox_process_msg(mbox, (void *)&rsp);
+       if (rc)
+               return rc;
+
+       for (i = 0; i < ROC_TM_LVL_MAX; i++) {
+               hw_lvl = nix_tm_lvl2nix(nix, i);
+               if (hw_lvl == NIX_TXSCH_LVL_CNT)
+                       continue;
+
+               schq[i] = (nix->is_nix1 ? rsp->schq_nix1[hw_lvl] :
+                                               rsp->schq[hw_lvl]);
+       }
+
+       return 0;
+}
+
+void
+roc_nix_tm_rsrc_max(bool pf, uint16_t schq[ROC_TM_LVL_MAX])
+{
+       uint8_t hw_lvl, i;
+       uint16_t max;
+
+       for (i = 0; i < ROC_TM_LVL_MAX; i++) {
+               hw_lvl = pf ? nix_tm_lvl2nix_tl1_root(i) :
+                                   nix_tm_lvl2nix_tl2_root(i);
+
+               switch (hw_lvl) {
+               case NIX_TXSCH_LVL_SMQ:
+                       max = (roc_model_is_cn9k() ?
+                                            NIX_CN9K_TXSCH_LVL_SMQ_MAX :
+                                            NIX_TXSCH_LVL_SMQ_MAX);
+                       break;
+               case NIX_TXSCH_LVL_TL4:
+                       max = NIX_TXSCH_LVL_TL4_MAX;
+                       break;
+               case NIX_TXSCH_LVL_TL3:
+                       max = NIX_TXSCH_LVL_TL3_MAX;
+                       break;
+               case NIX_TXSCH_LVL_TL2:
+                       max = pf ? NIX_TXSCH_LVL_TL2_MAX : 1;
+                       break;
+               case NIX_TXSCH_LVL_TL1:
+                       max = pf ? 1 : 0;
+                       break;
+               default:
+                       max = 0;
+                       break;
+               }
+               schq[i] = max;
+       }
+}
+
+bool
+roc_nix_tm_root_has_sp(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+
+       if (nix->tm_flags & NIX_TM_TL1_NO_SP)
+               return false;
+       return true;
+}
index b644716..1d7dd68 100644 (file)
@@ -868,6 +868,24 @@ nix_tm_resource_estimate(struct nix *nix, uint16_t *schq_contig, uint16_t *schq,
        return cnt;
 }
 
+uint16_t
+roc_nix_tm_leaf_cnt(struct roc_nix *roc_nix)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct nix_tm_node_list *list;
+       struct nix_tm_node *node;
+       uint16_t leaf_cnt = 0;
+
+       /* Count leafs only in user list */
+       list = nix_tm_node_list(nix, ROC_NIX_TM_USER);
+       TAILQ_FOREACH(node, list, node) {
+               if (node->id < nix->nb_tx_queues)
+                       leaf_cnt++;
+       }
+
+       return leaf_cnt;
+}
+
 int
 roc_nix_tm_node_lvl(struct roc_nix *roc_nix, uint32_t node_id)
 {
index c2693f8..986be3f 100644 (file)
@@ -38,6 +38,69 @@ roc_error_msg_get(int errorcode)
        case NIX_ERR_AQ_WRITE_FAILED:
                err_msg = "AQ write failed";
                break;
+       case NIX_ERR_TM_LEAF_NODE_GET:
+               err_msg = "TM leaf node get failed";
+               break;
+       case NIX_ERR_TM_INVALID_LVL:
+               err_msg = "TM node level invalid";
+               break;
+       case NIX_ERR_TM_INVALID_PRIO:
+               err_msg = "TM node priority invalid";
+               break;
+       case NIX_ERR_TM_INVALID_PARENT:
+               err_msg = "TM parent id invalid";
+               break;
+       case NIX_ERR_TM_NODE_EXISTS:
+               err_msg = "TM Node Exists";
+               break;
+       case NIX_ERR_TM_INVALID_NODE:
+               err_msg = "TM node id invalid";
+               break;
+       case NIX_ERR_TM_INVALID_SHAPER_PROFILE:
+               err_msg = "TM shaper profile invalid";
+               break;
+       case NIX_ERR_TM_WEIGHT_EXCEED:
+               err_msg = "TM DWRR weight exceeded";
+               break;
+       case NIX_ERR_TM_CHILD_EXISTS:
+               err_msg = "TM node children exists";
+               break;
+       case NIX_ERR_TM_INVALID_PEAK_SZ:
+               err_msg = "TM peak size invalid";
+               break;
+       case NIX_ERR_TM_INVALID_PEAK_RATE:
+               err_msg = "TM peak rate invalid";
+               break;
+       case NIX_ERR_TM_INVALID_COMMIT_SZ:
+               err_msg = "TM commit size invalid";
+               break;
+       case NIX_ERR_TM_INVALID_COMMIT_RATE:
+               err_msg = "TM commit rate invalid";
+               break;
+       case NIX_ERR_TM_SHAPER_PROFILE_IN_USE:
+               err_msg = "TM shaper profile in use";
+               break;
+       case NIX_ERR_TM_SHAPER_PROFILE_EXISTS:
+               err_msg = "TM shaper profile exists";
+               break;
+       case NIX_ERR_TM_INVALID_TREE:
+               err_msg = "TM tree invalid";
+               break;
+       case NIX_ERR_TM_PARENT_PRIO_UPDATE:
+               err_msg = "TM node parent and prio update failed";
+               break;
+       case NIX_ERR_TM_PRIO_EXCEEDED:
+               err_msg = "TM node priority exceeded";
+               break;
+       case NIX_ERR_TM_PRIO_ORDER:
+               err_msg = "TM node priority not in order";
+               break;
+       case NIX_ERR_TM_MULTIPLE_RR_GROUPS:
+               err_msg = "TM multiple rr groups";
+               break;
+       case NIX_ERR_TM_SQ_UPDATE_FAIL:
+               err_msg = "TM SQ update failed";
+               break;
        case NIX_ERR_NDC_SYNC:
                err_msg = "NDC Sync failed";
                break;
@@ -74,9 +137,54 @@ roc_error_msg_get(int errorcode)
        case NIX_AF_ERR_AF_LF_ALLOC:
                err_msg = "NIX LF alloc failed";
                break;
+       case NIX_AF_ERR_TLX_INVALID:
+               err_msg = "Invalid NIX TLX";
+               break;
+       case NIX_AF_ERR_TLX_ALLOC_FAIL:
+               err_msg = "NIX TLX alloc failed";
+               break;
+       case NIX_AF_ERR_RSS_SIZE_INVALID:
+               err_msg = "Invalid RSS size";
+               break;
+       case NIX_AF_ERR_RSS_GRPS_INVALID:
+               err_msg = "Invalid RSS groups";
+               break;
+       case NIX_AF_ERR_FRS_INVALID:
+               err_msg = "Invalid frame size";
+               break;
+       case NIX_AF_ERR_RX_LINK_INVALID:
+               err_msg = "Invalid Rx link";
+               break;
+       case NIX_AF_INVAL_TXSCHQ_CFG:
+               err_msg = "Invalid Tx scheduling config";
+               break;
+       case NIX_AF_SMQ_FLUSH_FAILED:
+               err_msg = "SMQ flush failed";
+               break;
        case NIX_AF_ERR_LF_RESET:
                err_msg = "NIX LF reset failed";
                break;
+       case NIX_AF_ERR_MARK_CFG_FAIL:
+               err_msg = "Marking config failed";
+               break;
+       case NIX_AF_ERR_LSO_CFG_FAIL:
+               err_msg = "LSO config failed";
+               break;
+       case NIX_AF_INVAL_NPA_PF_FUNC:
+               err_msg = "Invalid NPA pf_func";
+               break;
+       case NIX_AF_INVAL_SSO_PF_FUNC:
+               err_msg = "Invalid SSO pf_func";
+               break;
+       case NIX_AF_ERR_TX_VTAG_NOSPC:
+               err_msg = "No space for Tx VTAG";
+               break;
+       case NIX_AF_ERR_RX_VTAG_INUSE:
+               err_msg = "Rx VTAG is in use";
+               break;
+       case NIX_AF_ERR_PTP_CONFIG_FAIL:
+               err_msg = "PTP config failed";
+               break;
        case UTIL_ERR_FS:
                err_msg = "file operation failed";
                break;
index a5eb17e..a3f3059 100644 (file)
@@ -104,11 +104,13 @@ INTERNAL {
        roc_nix_xstats_names_get;
        roc_nix_switch_hdr_set;
        roc_nix_eeprom_info_get;
+       roc_nix_tm_dump;
        roc_nix_tm_fini;
        roc_nix_tm_free_resources;
        roc_nix_tm_hierarchy_disable;
        roc_nix_tm_hierarchy_enable;
        roc_nix_tm_init;
+       roc_nix_tm_leaf_cnt;
        roc_nix_tm_node_add;
        roc_nix_tm_node_delete;
        roc_nix_tm_node_get;
@@ -119,7 +121,11 @@ INTERNAL {
        roc_nix_tm_node_pkt_mode_update;
        roc_nix_tm_node_shaper_update;
        roc_nix_tm_node_suspend_resume;
+       roc_nix_tm_prealloc_res;
        roc_nix_tm_rlimit_sq;
+       roc_nix_tm_root_has_sp;
+       roc_nix_tm_rsrc_count;
+       roc_nix_tm_rsrc_max;
        roc_nix_tm_shaper_profile_add;
        roc_nix_tm_shaper_profile_delete;
        roc_nix_tm_shaper_profile_get;