Add TM command to enable packet mode for all SP children
in non leaf node. This is a new command as
"add tm nonleaf node pktmode".

This patch also dumps new tm capabilities
"sched_wfq_weight_mode_supported" and "sched_shaper_private_weight_mode".

Signed-off-by: Nithin Dabilpuram <ndabilpu...@marvell.com>
---
 app/test-pmd/cmdline.c                      |   7 ++
 app/test-pmd/cmdline_tm.c                   | 178 ++++++++++++++++++++++++++++
 app/test-pmd/cmdline_tm.h                   |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  27 +++++
 4 files changed, 213 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a037a55..eba79f1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1221,6 +1221,12 @@ static void cmd_help_long_parsed(void *parsed_result,
                        " [(shared_shaper_id_0) (shared_shaper_id_1)...]\n"
                        "       Add port tm nonleaf node.\n\n"
 
+                       "add port tm nonleaf node pktmode (port_id) (node_id) 
(parent_node_id)"
+                       " (priority) (weight) (level_id) (shaper_profile_id)"
+                       " (n_sp_priorities) (stats_mask) (n_shared_shapers)"
+                       " [(shared_shaper_id_0) (shared_shaper_id_1)...]\n"
+                       "       Add port tm nonleaf node with pkt mode 
enabled.\n\n"
+
                        "add port tm leaf node (port_id) (node_id) 
(parent_node_id)"
                        " (priority) (weight) (level_id) (shaper_profile_id)"
                        " (cman_mode) (wred_profile_id) (stats_mask) 
(n_shared_shapers)"
@@ -19583,6 +19589,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_del_port_tm_node_wred_profile,
        (cmdline_parse_inst_t *)&cmd_set_port_tm_node_shaper_profile,
        (cmdline_parse_inst_t *)&cmd_add_port_tm_nonleaf_node,
+       (cmdline_parse_inst_t *)&cmd_add_port_tm_nonleaf_node_pmode,
        (cmdline_parse_inst_t *)&cmd_add_port_tm_leaf_node,
        (cmdline_parse_inst_t *)&cmd_del_port_tm_node,
        (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
diff --git a/app/test-pmd/cmdline_tm.c b/app/test-pmd/cmdline_tm.c
index d62a4f5..269a4b1 100644
--- a/app/test-pmd/cmdline_tm.c
+++ b/app/test-pmd/cmdline_tm.c
@@ -283,6 +283,10 @@ static void cmd_show_port_tm_cap_parsed(void 
*parsed_result,
                cap.sched_wfq_n_groups_max);
        printf("cap.sched_wfq_weight_max %" PRIu32 "\n",
                cap.sched_wfq_weight_max);
+       printf("cap.sched_wfq_weight_mode_supported %" PRId32 "\n",
+               cap.sched_wfq_weight_mode_supported);
+       printf("cap.sched_shaper_private_weight_mode %" PRId32 "\n",
+               cap.sched_shaper_private_weight_mode);
        printf("cap.cman_head_drop_supported %" PRId32 "\n",
                cap.cman_head_drop_supported);
        printf("cap.cman_wred_context_n_max %" PRIu32 "\n",
@@ -413,6 +417,10 @@ static void cmd_show_port_tm_level_cap_parsed(void 
*parsed_result,
                        lcap.nonleaf.sched_wfq_n_groups_max);
                printf("cap.nonleaf.sched_wfq_weight_max %" PRIu32 "\n",
                        lcap.nonleaf.sched_wfq_weight_max);
+               printf("cap.nonleaf.sched_wfq_weight_mode_supported %" PRId32 
"\n",
+                       lcap.nonleaf.sched_wfq_weight_mode_supported);
+               printf("cap.nonleaf.sched_shaper_private_weight_mode %" PRId32 
"\n",
+                       lcap.nonleaf.sched_shaper_private_weight_mode);
                printf("cap.nonleaf.stats_mask %" PRIx64 "\n",
                        lcap.nonleaf.stats_mask);
        } else {
@@ -537,6 +545,10 @@ static void cmd_show_port_tm_node_cap_parsed(void 
*parsed_result,
                        ncap.nonleaf.sched_wfq_n_groups_max);
                printf("cap.nonleaf.sched_wfq_weight_max %" PRIu32 "\n",
                        ncap.nonleaf.sched_wfq_weight_max);
+               printf("cap.nonleaf.sched_wfq_weight_mode_supported %" PRId32 
"\n",
+                       ncap.nonleaf.sched_wfq_weight_mode_supported);
+               printf("cap.nonleaf.sched_shaper_private_weight_mode %" PRId32 
"\n",
+                       ncap.nonleaf.sched_shaper_private_weight_mode);
        } else {
                printf("cap.leaf.cman_head_drop_supported %" PRId32 "\n",
                        ncap.leaf.cman_head_drop_supported);
@@ -1671,6 +1683,172 @@ cmdline_parse_inst_t cmd_add_port_tm_nonleaf_node = {
        },
 };
 
+/* *** Add Port TM nonleaf node pkt mode *** */
+struct cmd_add_port_tm_nonleaf_node_pmode_result {
+       cmdline_fixed_string_t add;
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t tm;
+       cmdline_fixed_string_t nonleaf;
+       cmdline_fixed_string_t node;
+       uint16_t port_id;
+       uint32_t node_id;
+       int32_t parent_node_id;
+       uint32_t priority;
+       uint32_t weight;
+       uint32_t level_id;
+       int32_t shaper_profile_id;
+       uint32_t n_sp_priorities;
+       uint64_t stats_mask;
+       cmdline_multi_string_t multi_shared_shaper_id;
+};
+
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_add =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, add, "add");
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_port =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, port, "port");
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_tm =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, tm, "tm");
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_nonleaf =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, nonleaf, 
"nonleaf");
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_node =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, node, "node");
+cmdline_parse_token_string_t cmd_add_port_tm_nonleaf_node_pmode_pktmode =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result, node, 
"pktmode");
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_port_id =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                port_id, UINT16);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_node_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                node_id, UINT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_parent_node_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                parent_node_id, INT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_priority =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                priority, UINT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_weight =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                weight, UINT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_level_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                level_id, UINT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_shaper_profile_id 
=
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                shaper_profile_id, INT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_n_sp_priorities =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                n_sp_priorities, UINT32);
+cmdline_parse_token_num_t cmd_add_port_tm_nonleaf_node_pmode_stats_mask =
+       TOKEN_NUM_INITIALIZER(struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                stats_mask, UINT64);
+cmdline_parse_token_string_t
+       cmd_add_port_tm_nonleaf_node_pmode_multi_shrd_shpr_id =
+       TOKEN_STRING_INITIALIZER(
+                       struct cmd_add_port_tm_nonleaf_node_pmode_result,
+                       multi_shared_shaper_id, TOKEN_STRING_MULTI);
+
+static void cmd_add_port_tm_nonleaf_node_pmode_parsed(void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_add_port_tm_nonleaf_node_pmode_result *res = parsed_result;
+       uint32_t parent_node_id, n_shared_shapers = 0;
+       char *s_str = res->multi_shared_shaper_id;
+       portid_t port_id = res->port_id;
+       struct rte_tm_node_params np;
+       int *wfq_weight_mode = NULL;
+       uint32_t *shared_shaper_id;
+       struct rte_tm_error error;
+       int ret;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       memset(&np, 0, sizeof(struct rte_tm_node_params));
+       memset(&error, 0, sizeof(struct rte_tm_error));
+
+       /* Node parameters */
+       if (res->parent_node_id < 0)
+               parent_node_id = UINT32_MAX;
+       else
+               parent_node_id = res->parent_node_id;
+
+       shared_shaper_id = (uint32_t *)malloc(MAX_NUM_SHARED_SHAPERS *
+               sizeof(uint32_t));
+       if (shared_shaper_id == NULL) {
+               printf(" Memory not allocated for shared shapers (error)\n");
+               return;
+       }
+
+       /* Parse multi shared shaper id string */
+       ret = parse_multi_ss_id_str(s_str, &n_shared_shapers, shared_shaper_id);
+       if (ret) {
+               printf(" Shared shapers params string parse error\n");
+               free(shared_shaper_id);
+               return;
+       }
+
+       if (res->shaper_profile_id < 0)
+               np.shaper_profile_id = UINT32_MAX;
+       else
+               np.shaper_profile_id = res->shaper_profile_id;
+
+       np.n_shared_shapers = n_shared_shapers;
+       if (np.n_shared_shapers) {
+               np.shared_shaper_id = &shared_shaper_id[0];
+       } else {
+               free(shared_shaper_id);
+               shared_shaper_id = NULL;
+       }
+
+       if (res->n_sp_priorities)
+               wfq_weight_mode = calloc(res->n_sp_priorities, sizeof(int));
+       np.nonleaf.n_sp_priorities = res->n_sp_priorities;
+       np.stats_mask = res->stats_mask;
+       np.nonleaf.wfq_weight_mode = wfq_weight_mode;
+
+       ret = rte_tm_node_add(port_id, res->node_id, parent_node_id,
+                               res->priority, res->weight, res->level_id,
+                               &np, &error);
+       if (ret != 0) {
+               print_err_msg(&error);
+               free(shared_shaper_id);
+               free(wfq_weight_mode);
+               return;
+       }
+}
+
+cmdline_parse_inst_t cmd_add_port_tm_nonleaf_node_pmode = {
+       .f = cmd_add_port_tm_nonleaf_node_pmode_parsed,
+       .data = NULL,
+       .help_str = "Add port tm nonleaf node pktmode",
+       .tokens = {
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_add,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_port,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_tm,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_nonleaf,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_node,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_pktmode,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_port_id,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_node_id,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_parent_node_id,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_priority,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_weight,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_level_id,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_shaper_profile_id,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_n_sp_priorities,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_stats_mask,
+               (void *)&cmd_add_port_tm_nonleaf_node_pmode_multi_shrd_shpr_id,
+               NULL,
+       },
+};
 /* *** Add Port TM leaf node *** */
 struct cmd_add_port_tm_leaf_node_result {
        cmdline_fixed_string_t add;
diff --git a/app/test-pmd/cmdline_tm.h b/app/test-pmd/cmdline_tm.h
index 950cb75..e59c15c 100644
--- a/app/test-pmd/cmdline_tm.h
+++ b/app/test-pmd/cmdline_tm.h
@@ -19,6 +19,7 @@ extern cmdline_parse_inst_t cmd_add_port_tm_node_wred_profile;
 extern cmdline_parse_inst_t cmd_del_port_tm_node_wred_profile;
 extern cmdline_parse_inst_t cmd_set_port_tm_node_shaper_profile;
 extern cmdline_parse_inst_t cmd_add_port_tm_nonleaf_node;
+extern cmdline_parse_inst_t cmd_add_port_tm_nonleaf_node_pmode;
 extern cmdline_parse_inst_t cmd_add_port_tm_leaf_node;
 extern cmdline_parse_inst_t cmd_del_port_tm_node;
 extern cmdline_parse_inst_t cmd_set_port_tm_node_parent;
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst 
b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 5bb12a5..9072ed6 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2971,6 +2971,33 @@ where:
 * ``n_shared_shapers``: Number of shared shapers.
 * ``shared_shaper_id``: Shared shaper id.
 
+Add port traffic management hierarchy nonleaf node with packet mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add nonleaf node with packet mode to port traffic management hierarchy::
+
+   testpmd> add port tm nonleaf node pktmode (port_id) (node_id) 
(parent_node_id) \
+   (priority) (weight) (level_id) (shaper_profile_id) \
+   (n_sp_priorities) (stats_mask) (n_shared_shapers) \
+   [(shared_shaper_0) (shared_shaper_1) ...] \
+
+where:
+
+* ``parent_node_id``: Node ID of the parent.
+* ``priority``: Node priority (highest node priority is zero). This is used by
+  the SP algorithm running on the parent node for scheduling this node.
+* ``weight``: Node weight (lowest weight is one). The node weight is relative
+  to the weight sum of all siblings that have the same priority. It is used by
+  the WFQ algorithm running on the parent node for scheduling this node.
+* ``level_id``: Hierarchy level of the node.
+* ``shaper_profile_id``: Shaper profile ID of the private shaper to be used by
+  the node.
+* ``n_sp_priorities``: Number of strict priorities. Packet mode is enabled on
+  all of them.
+* ``stats_mask``: Mask of statistics counter types to be enabled for this node.
+* ``n_shared_shapers``: Number of shared shapers.
+* ``shared_shaper_id``: Shared shaper id.
+
 Add port traffic management hierarchy leaf node
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- 
2.8.4

Reply via email to