Add following CLIs in testpmd application;
- command to set the packet field mask and offset value for
  classification.
- command to set traffic class translation table entry

Signed-off-by: Jasvinder Singh <jasvinder.si...@intel.com>
---
 app/test-pmd/cmdline.c    |  11 ++
 app/test-pmd/cmdline_tm.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 316 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 70a376a..480fe4b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -702,6 +702,13 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "port tm hierarchy commit (port_id) (clean_on_fail)\n"
                        "       Commit tm hierarchy.\n\n"
 
+                       "set port tm pktfield (subport|pipe|tc) (port_id) 
offset"
+                       " (offset) mask (mask)\n"
+                       "       Set port tm packet field.\n\n"
+
+                       "set port tm tc table (port_id) index (tb_index) tc 
(tc_id)"
+                       " queue (queue id)\n"
+                       "       Set port tm traffic class table entry.\n\n"
 #endif
                        , list_pkt_forwarding_modes()
                );
@@ -14275,6 +14282,8 @@ extern cmdline_parse_inst_t cmd_del_port_tm_node;
 extern cmdline_parse_inst_t cmd_set_port_tm_node_parent;
 #endif
 extern cmdline_parse_inst_t cmd_port_tm_hierarchy_commit;
+extern cmdline_parse_inst_t cmd_set_port_tm_pktfield;
+extern cmdline_parse_inst_t cmd_set_port_tm_tc_table;
 #endif
 
 /* *********************************************************************** */
@@ -14488,6 +14497,8 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 #endif
        (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+       (cmdline_parse_inst_t *)&cmd_set_port_tm_pktfield,
+       (cmdline_parse_inst_t *)&cmd_set_port_tm_tc_table,
 #endif
        NULL,
 };
diff --git a/app/test-pmd/cmdline_tm.c b/app/test-pmd/cmdline_tm.c
index b36326d..829442f 100644
--- a/app/test-pmd/cmdline_tm.c
+++ b/app/test-pmd/cmdline_tm.c
@@ -2197,3 +2197,308 @@ cmdline_parse_inst_t cmd_port_tm_hierarchy_commit = {
                NULL,
        },
 };
+
+static int
+port_tm_pktfield_validate_mask(uint64_t mask, uint64_t n)
+{
+       int count = __builtin_popcountll(mask);
+       int pos_lead = sizeof(uint64_t) * 8 - __builtin_clzll(mask);
+       int pos_trail = __builtin_ctzll(mask);
+       int count_expected = __builtin_popcount(n - 1);
+
+       /* Handle the exceptions */
+       if (n == 0)
+               return -1;                      /* Error */
+
+       if ((mask == 0) && (n == 1))
+               return 0;                       /* OK */
+
+       if (((mask == 0) && (n != 1)) || ((mask != 0) && (n == 1)))
+               return -2;                      /* Error */
+
+       /* Check that mask is contiguous */
+       if ((pos_lead - pos_trail) != count)
+               return -3;                      /* Error */
+
+       /* Check that mask contains the expected number of bits set */
+       if (count != count_expected)
+               return -4;                      /* Error */
+
+       return 0;                       /* OK */
+       }
+
+/* *** Set Port TM Packet Fields *** */
+struct cmd_set_port_tm_pktfield_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t tm;
+       cmdline_fixed_string_t pktfield;
+       cmdline_fixed_string_t type;
+       uint8_t port_id;
+       cmdline_fixed_string_t offset_string;
+       uint32_t offset;
+       cmdline_fixed_string_t mask_string;
+       uint64_t mask;
+};
+
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_set =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result, set, "set");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_port =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result, port, "port");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_tm =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result, tm, "tm");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_pktfield =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       pktfield, "pktfield");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_type =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       type, "subport#pipe#tc");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_port_id =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_offset_string =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       offset_string, "offset");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_offset =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       offset, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_mask_string =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       mask_string, "mask");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_mask =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_pktfield_result,
+                       mask, UINT64);
+
+static void cmd_set_port_tm_pktfield_parsed(void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_set_port_tm_pktfield_result *res = parsed_result;
+       struct rte_port *p;
+       uint32_t offset = res->offset;
+       uint64_t mask = res->mask;
+       uint8_t port_id = res->port_id;
+       int ret;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       p = &ports[port_id];
+
+       /* Port tm flag */
+       if (p->softport.tm_flag == 0) {
+               printf("  tm not enabled on port %u (error)\n", port_id);
+               return;
+       }
+
+       /* Forward mode: tm */
+       if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) {
+               printf("  tm mode not enabled(error)\n");
+               return;
+       }
+
+       /* Subport */
+       if (strcmp(res->type, "subport") == 0) {
+               uint32_t n = p->softport.tm.n_subports_per_port;
+
+               ret = port_tm_pktfield_validate_mask(mask, n);
+               if (ret) {
+                       printf(" invalid subport mask(error %d)", ret);
+                       return;
+               }
+               /* Set packet field */
+               p->softport.tm.tm_pktfield0_slabpos = offset;
+               p->softport.tm.tm_pktfield0_slabmask = mask;
+               p->softport.tm.tm_pktfield0_slabshr = __builtin_ctzll(mask);
+               return;
+       }
+
+       /* Pipe */
+       if (strcmp(res->type, "pipe") == 0) {
+               uint32_t n = p->softport.tm.n_pipes_per_subport;
+
+               ret = port_tm_pktfield_validate_mask(mask, n);
+               if (ret) {
+                       printf(" invalid pipe mask(error %d)", ret);
+                       return;
+               }
+               /* Set packet field */
+               p->softport.tm.tm_pktfield1_slabpos = offset;
+               p->softport.tm.tm_pktfield1_slabmask = mask;
+               p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask);
+               return;
+       }
+
+       /* Traffic class */
+       if (strcmp(res->type, "tc") == 0) {
+               uint32_t n = RTE_DIM(p->softport.tm.tm_tc_table);
+
+               ret = port_tm_pktfield_validate_mask(mask, n);
+               if (ret) {
+                       printf(" invalid tc mask(error %d)", ret);
+                       return;
+               }
+               /* Set packet field */
+               p->softport.tm.tm_pktfield1_slabpos = offset;
+               p->softport.tm.tm_pktfield1_slabmask = mask;
+               p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask);
+               return;
+       }
+}
+
+cmdline_parse_inst_t cmd_set_port_tm_pktfield = {
+       .f = cmd_set_port_tm_pktfield_parsed,
+       .data = NULL,
+       .help_str = "Set port tm pktfield",
+       .tokens = {
+               (void *)&cmd_set_port_tm_pktfield_set,
+               (void *)&cmd_set_port_tm_pktfield_port,
+               (void *)&cmd_set_port_tm_pktfield_tm,
+               (void *)&cmd_set_port_tm_pktfield_pktfield,
+               (void *)&cmd_set_port_tm_pktfield_type,
+               (void *)&cmd_set_port_tm_pktfield_port_id,
+               (void *)&cmd_set_port_tm_pktfield_offset_string,
+               (void *)&cmd_set_port_tm_pktfield_offset,
+               (void *)&cmd_set_port_tm_pktfield_mask_string,
+               (void *)&cmd_set_port_tm_pktfield_mask,
+               NULL,
+       },
+};
+
+/* *** Set Port TM Traffic Class Table Entry *** */
+struct cmd_set_port_tm_tc_table_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t tm;
+       cmdline_fixed_string_t tc_table;
+       uint8_t port_id;
+       cmdline_fixed_string_t index_string;
+       uint32_t index;
+       cmdline_fixed_string_t tc_string;
+       uint32_t tc;
+       cmdline_fixed_string_t queue_string;
+       uint32_t queue;
+};
+
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_set =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result, set, "set");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_port =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result, port, "port");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tm =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result, tm, "tm");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_table =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       tc_table, "tc table");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_port_id =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_index_string =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       index_string, "index");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_index =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       index, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_string =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       tc_string, "tc");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_tc =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       tc, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_queue_string =
+       TOKEN_STRING_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       queue_string, "queue");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_queue =
+       TOKEN_NUM_INITIALIZER(
+               struct cmd_set_port_tm_tc_table_result,
+                       queue, UINT32);
+
+static void cmd_set_port_tm_tc_table_parsed(void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_set_port_tm_tc_table_result *res = parsed_result;
+       struct rte_port *p;
+       uint32_t tc = res->tc;
+       uint32_t index = res->index;
+       uint32_t queue = res->queue;
+       uint32_t val;
+       uint8_t port_id = res->port_id;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       p = &ports[port_id];
+
+       /* Port tm flag */
+       if (p->softport.tm_flag == 0) {
+               printf("  tm not enabled on port %u (error)\n", port_id);
+               return;
+       }
+
+       /* Forward mode: tm */
+       if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) {
+               printf("  tm mode not enabled(error)\n");
+               return;
+       }
+
+       /* Traffic class table index */
+       if (tc >= RTE_DIM(p->softport.tm.tm_tc_table)) {
+               printf("  invalid traffic class table index(error)\n");
+               return;
+       }
+
+       /* Traffic class id */
+       if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) {
+               printf("  invalid traffic class id(error)\n");
+               return;
+       }
+
+       /* Traffic class queue */
+       if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) {
+               printf("  invalid traffic class queue(error)\n");
+               return;
+       }
+
+       val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
+       p->softport.tm.tm_tc_table[index] = val;
+}
+
+cmdline_parse_inst_t cmd_set_port_tm_tc_table = {
+       .f = cmd_set_port_tm_tc_table_parsed,
+       .data = NULL,
+       .help_str = "Set port tm TC table entry",
+       .tokens = {
+               (void *)&cmd_set_port_tm_tc_table_set,
+               (void *)&cmd_set_port_tm_tc_table_port,
+               (void *)&cmd_set_port_tm_tc_table_tm,
+               (void *)&cmd_set_port_tm_tc_table_tc_table,
+               (void *)&cmd_set_port_tm_tc_table_port_id,
+               (void *)&cmd_set_port_tm_tc_table_index_string,
+               (void *)&cmd_set_port_tm_tc_table_index,
+               (void *)&cmd_set_port_tm_tc_table_tc_string,
+               (void *)&cmd_set_port_tm_tc_table_tc,
+               (void *)&cmd_set_port_tm_tc_table_queue_string,
+               (void *)&cmd_set_port_tm_tc_table_queue,
+               NULL,
+       },
+};
-- 
2.9.3

Reply via email to