Add the command "port config X rss-hash-key key" in the 'testpmd'
application to configure the RSS hash key used to compute the RSS
hash of input [IP] packets received on port X.

Signed-off-by: Ivan Boule <ivan.boule at 6wind.com>
---
 app/test-pmd/cmdline.c |   96 +++++++++++++++++++++++++++++++++++++++++++++++-
 app/test-pmd/config.c  |   28 ++++++++++++++
 app/test-pmd/testpmd.h |    1 +
 3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0b6749c..7b4f090 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1192,6 +1192,99 @@ cmdline_parse_inst_t cmd_config_rss = {
        },
 };

+/* *** configure rss hash key *** */
+struct cmd_config_rss_hash_key {
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t config;
+       uint8_t port_id;
+       cmdline_fixed_string_t rss_hash_key;
+       cmdline_fixed_string_t key;
+};
+
+#define RSS_HASH_KEY_LENGTH 40
+static uint8_t
+hexa_digit_to_value(char hexa_digit)
+{
+       if ((hexa_digit >= '0') && (hexa_digit <= '9'))
+               return (uint8_t) (hexa_digit - '0');
+       if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
+               return (uint8_t) ((hexa_digit - 'a') + 10);
+       if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
+               return (uint8_t) ((hexa_digit - 'A') + 10);
+       /* Invalid hexa digit */
+       return 0xFF;
+}
+
+static uint8_t
+parse_and_check_key_hexa_digit(char *key, int idx)
+{
+       uint8_t hexa_v;
+
+       hexa_v = hexa_digit_to_value(key[idx]);
+       if (hexa_v == 0xFF)
+               printf("invalid key: character %c at position %d is not a "
+                      "valid hexa digit\n", key[idx], idx);
+       return hexa_v;
+}
+
+static void
+cmd_config_rss_hash_key_parsed(void *parsed_result,
+                              __attribute__((unused)) struct cmdline *cl,
+                              __attribute__((unused)) void *data)
+{
+       struct cmd_config_rss_hash_key *res = parsed_result;
+       uint8_t hash_key[RSS_HASH_KEY_LENGTH];
+       uint8_t xdgt0;
+       uint8_t xdgt1;
+       int i;
+
+       /* Check the length of the RSS hash key */
+       if (strlen(res->key) != (RSS_HASH_KEY_LENGTH * 2)) {
+               printf("key length: %d invalid - key must be a string of %d"
+                      "hexa-decimal numbers\n", (int) strlen(res->key),
+                      RSS_HASH_KEY_LENGTH * 2);
+               return;
+       }
+       /* Translate RSS hash key into binary representation */
+       for (i = 0; i < RSS_HASH_KEY_LENGTH; i++) {
+               xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
+               if (xdgt0 == 0xFF)
+                       return;
+               xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
+               if (xdgt1 == 0xFF)
+                       return;
+               hash_key[i]= (uint8_t) ((xdgt0 * 16) + xdgt1);
+       }
+       port_rss_hash_key_update(res->port_id, hash_key);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
+                                "config");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
+                                rss_hash_key, "rss-hash-key");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
+
+cmdline_parse_inst_t cmd_config_rss_hash_key = {
+       .f = cmd_config_rss_hash_key_parsed,
+       .data = NULL,
+       .help_str = "port config X rss-hash-key 80 hexa digits",
+       .tokens = {
+               (void *)&cmd_config_rss_hash_key_port,
+               (void *)&cmd_config_rss_hash_key_config,
+               (void *)&cmd_config_rss_hash_key_port_id,
+               (void *)&cmd_config_rss_hash_key_rss_hash_key,
+               (void *)&cmd_config_rss_hash_key_value,
+               NULL,
+       },
+};
+
 /* *** Configure RSS RETA *** */
 struct cmd_config_rss_reta {
        cmdline_fixed_string_t port;
@@ -1413,7 +1506,7 @@ cmdline_parse_inst_t cmd_showport_rss_hash = {

 cmdline_parse_inst_t cmd_showport_rss_hash_key = {
        .f = cmd_showport_rss_hash_parsed,
-       .data = "show_rss_key",
+       .data = (void *)1,
        .help_str = "show port X rss-hash key (X = port number)\n",
        .tokens = {
                (void *)&cmd_showport_rss_hash_show,
@@ -5322,6 +5415,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
        (cmdline_parse_inst_t *)&cmd_showport_rss_hash,
        (cmdline_parse_inst_t *)&cmd_showport_rss_hash_key,
+       (cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
        (cmdline_parse_inst_t *)&cmd_dump,
        (cmdline_parse_inst_t *)&cmd_dump_one,
        NULL,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 614f28f..6feda7a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -746,6 +746,34 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
        printf("\n");
 }

+void
+port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key)
+{
+       struct rte_eth_rss_conf rss_conf;
+       int diag;
+
+       rss_conf.rss_key = NULL;
+       diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+       if (diag == 0) {
+               rss_conf.rss_key = hash_key;
+               diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf);
+       }
+       if (diag == 0)
+               return;
+
+       switch (diag) {
+       case -ENODEV:
+               printf("port index %d invalid\n", port_id);
+               break;
+       case -ENOTSUP:
+               printf("operation not supported by device\n");
+               break;
+       default:
+               printf("operation failed - diag=%d\n", diag);
+               break;
+       }
+}
+
 /*
  * Setup forwarding configuration for each logical core.
  */
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b9d47c4..66c7736 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -524,6 +524,7 @@ void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,
                uint64_t vf_mask, uint8_t on);

 void port_rss_hash_conf_show(portid_t port_id, int show_rss_key);
+void port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key);

 /*
  * Work-around of a compilation error with ICC on invocations of the
-- 
1.7.10.4

Reply via email to