add test command to configure flexible payload

Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
Acked-by: Chen Jing D(Mark) <jing.d.chen at intel.com>
Acked-by: Helin Zhang <helin.zhang at intel.com>
---
 app/test-pmd/cmdline.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 240a464..da77752 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -58,6 +58,7 @@
 #include <rte_debug.h>
 #include <rte_cycles.h>
 #include <rte_memory.h>
+#include <rte_malloc.h>
 #include <rte_memzone.h>
 #include <rte_launch.h>
 #include <rte_tailq.h>
@@ -685,6 +686,10 @@ static void cmd_help_long_parsed(void *parsed_result,

                        "flush_flow_diretor (port_id)\n"
                        "    Flush all flow director entries of a device.\n\n"
+
+                       "flow_director_flex_payload (port_id)"
+                       " (l2|l3|l4) (config)\n"
+                       "    configure flexible payload selection.\n\n"
                );
        }
 }
@@ -7903,6 +7908,144 @@ cmdline_parse_inst_t cmd_flush_flow_director = {
        },
 };

+/* *** deal with flow director flexible payload configuration *** */
+struct cmd_flow_director_flexpayload_result {
+       cmdline_fixed_string_t flow_director_flexpayload;
+       uint8_t port_id;
+       cmdline_fixed_string_t payload_layer;
+       cmdline_fixed_string_t payload_cfg;
+};
+
+static inline int
+parse_flex_payload_cfg(const char *q_arg,
+                            struct rte_eth_flex_payload_cfg *cfg)
+{
+       char s[256];
+       const char *p, *p0 = q_arg;
+       char *end;
+       enum fieldnames {
+               FLD_OFFSET = 0,
+               FLD_SIZE,
+               _NUM_FLD
+       };
+       unsigned long int_fld[_NUM_FLD];
+       char *str_fld[_NUM_FLD];
+       int i;
+       unsigned size;
+
+       cfg->nb_field = 0;
+       p = strchr(p0, '(');
+       while (p != NULL) {
+               ++p;
+               p0 = strchr(p, ')');
+               if (p0 == NULL)
+                       return -1;
+
+               size = p0 - p;
+               if (size >= sizeof(s))
+                       return -1;
+
+               snprintf(s, sizeof(s), "%.*s", size, p);
+               if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != 
_NUM_FLD)
+                       return -1;
+               for (i = 0; i < _NUM_FLD; i++) {
+                       errno = 0;
+                       int_fld[i] = strtoul(str_fld[i], &end, 0);
+                       if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+                               return -1;
+               }
+               cfg->field[cfg->nb_field].offset = (uint8_t)int_fld[FLD_OFFSET];
+               cfg->field[cfg->nb_field].size = (uint8_t)int_fld[FLD_SIZE];
+               cfg->nb_field++;
+               if (cfg->nb_field > 3) {
+                       printf("exceeded max number of fields\n");
+                       return -1;
+               }
+               p = strchr(p0, '(');
+       }
+       return 0;
+}
+
+static void
+cmd_flow_director_flxpld_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_flexpayload_result *res = parsed_result;
+       struct rte_eth_fdir_cfg fdir_cfg;
+       struct rte_eth_flex_payload_cfg *flxpld_cfg;
+       int ret = 0;
+       int cfg_size = 3 * sizeof(struct rte_eth_field_vector) +
+                 offsetof(struct rte_eth_flex_payload_cfg, field);
+
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
+       if (ret < 0) {
+               printf("flow director is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       memset(&fdir_cfg, 0, sizeof(struct rte_eth_fdir_cfg));
+
+       flxpld_cfg = (struct rte_eth_flex_payload_cfg 
*)rte_zmalloc_socket("CLI",
+               cfg_size, CACHE_LINE_SIZE, rte_socket_id());
+
+       if (flxpld_cfg == NULL) {
+               printf("fail to malloc memory to configure flexible payload\n");
+               return;
+       }
+
+       if (!strcmp(res->payload_layer, "l2"))
+               flxpld_cfg->type = RTE_ETH_L2_PAYLOAD;
+       else if (!strcmp(res->payload_layer, "l3"))
+               flxpld_cfg->type = RTE_ETH_L3_PAYLOAD;
+       else if (!strcmp(res->payload_layer, "l4"))
+               flxpld_cfg->type = RTE_ETH_L4_PAYLOAD;
+
+       ret = parse_flex_payload_cfg(res->payload_cfg, flxpld_cfg);
+       if (ret < 0) {
+               printf("fdir flexpayload parsing error: (%s)\n",
+                       strerror(-ret));
+               rte_free(flxpld_cfg);
+               return;
+       }
+       fdir_cfg.cmd = RTE_ETH_FDIR_CFG_FLX;
+       fdir_cfg.cfg = flxpld_cfg;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                    RTE_ETH_FILTER_OP_SET, &fdir_cfg);
+       if (ret < 0)
+               printf("fdir flexpayload setting error: (%s)\n",
+                       strerror(-ret));
+       rte_free(flxpld_cfg);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_flexpayload =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                flow_director_flexpayload,
+                                "flow_director_flex_payload");
+cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                payload_layer, "l2#l3#l4");
+cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                payload_cfg, NULL);
+
+cmdline_parse_inst_t cmd_set_flow_director_flex_payload = {
+       .f = cmd_flow_director_flxpld_parsed,
+       .data = NULL,
+       .help_str = "set flow director's flexible payload on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_flexpayload,
+               (void *)&cmd_flow_director_flexpayload_port_id,
+               (void *)&cmd_flow_director_flexpayload_payload_layer,
+               (void *)&cmd_flow_director_flexpayload_payload_cfg,
+               NULL,
+       },
+};
+
 /* 
********************************************************************************
 */

 /* list of instructions */
@@ -8033,6 +8176,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
        (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
        (cmdline_parse_inst_t *)&cmd_flush_flow_director,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
        NULL,
 };

-- 
1.8.1.4

Reply via email to