app/testpmd: add CLI to set TC min bandwidth
[dpdk.git] / app / test-pmd / cmdline.c
index b93b096..e650d18 100644 (file)
@@ -214,6 +214,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 
                        "read txd (port_id) (queue_id) (txd_id)\n"
                        "    Display a TX descriptor of a port TX queue.\n\n"
+
+                       "ddp get list (port_id)\n"
+                       "    Get ddp profile info list\n\n"
                );
        }
 
@@ -327,6 +330,9 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "set tx strict-link-priority (port_id) (tc_bitmap)\n"
                        "    Set some TCs' strict link priority mode on a physical port.\n\n"
 
+                       "set tc tx min-bandwidth (port_id) (bw1, bw2, ...)\n"
+                       "    Set all TCs' min bandwidth(%%) for all PF and VFs.\n\n"
+
                        "vlan set filter (on|off) (port_id)\n"
                        "    Set the VLAN filter on a port.\n\n"
 
@@ -590,6 +596,9 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "E-tag set filter del e-tag-id (value) port (port_id)\n"
                        "    Delete an E-tag forwarding filter on a port\n\n"
 
+                       "ddp add (port_id) (profile_path)\n"
+                       "    Load a profile package on a port\n\n"
+
                        , list_pkt_forwarding_modes()
                );
        }
@@ -2075,7 +2084,9 @@ showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
        char s[256];
        char *end;
        char *str_fld[8];
-       uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
+       uint16_t i;
+       uint16_t num = (nb_entries + RTE_RETA_GROUP_SIZE - 1) /
+                       RTE_RETA_GROUP_SIZE;
        int ret;
 
        p = strchr(p0, '(');
@@ -12636,6 +12647,68 @@ cmdline_parse_inst_t cmd_vf_tc_min_bw = {
        },
 };
 
+static void
+cmd_tc_min_bw_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_vf_tc_bw_result *res = parsed_result;
+       struct rte_port *port;
+       uint8_t tc_num;
+       uint8_t bw[16];
+       int ret = -ENOTSUP;
+
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+               return;
+
+       port = &ports[res->port_id];
+       /** Check if the port is not started **/
+       if (port->port_status != RTE_PORT_STOPPED) {
+               printf("Please stop port %d first\n", res->port_id);
+               return;
+       }
+
+       ret = vf_tc_min_bw_parse_bw_list(bw, &tc_num, res->bw_list);
+       if (ret)
+               return;
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+       ret = rte_pmd_ixgbe_set_tc_bw_alloc(res->port_id, tc_num, bw);
+#endif
+
+       switch (ret) {
+       case 0:
+               break;
+       case -EINVAL:
+               printf("invalid bandwidth\n");
+               break;
+       case -ENODEV:
+               printf("invalid port_id %d\n", res->port_id);
+               break;
+       case -ENOTSUP:
+               printf("function not implemented\n");
+               break;
+       default:
+               printf("programming error: (%s)\n", strerror(-ret));
+       }
+}
+
+cmdline_parse_inst_t cmd_tc_min_bw = {
+       .f = cmd_tc_min_bw_parsed,
+       .data = NULL,
+       .help_str = "set tc tx min-bandwidth <port_id> <bw1, bw2, ...>",
+       .tokens = {
+               (void *)&cmd_vf_tc_bw_set,
+               (void *)&cmd_vf_tc_bw_tc,
+               (void *)&cmd_vf_tc_bw_tx,
+               (void *)&cmd_vf_tc_bw_min_bw,
+               (void *)&cmd_vf_tc_bw_port_id,
+               (void *)&cmd_vf_tc_bw_bw_list,
+               NULL,
+       },
+};
+
 /* TC max bandwidth setting */
 static void
 cmd_vf_tc_max_bw_parsed(
@@ -12739,7 +12812,163 @@ cmdline_parse_inst_t cmd_strict_link_prio = {
        },
 };
 
+/* Load dynamic device personalization*/
+struct cmd_ddp_add_result {
+       cmdline_fixed_string_t ddp;
+       cmdline_fixed_string_t add;
+       uint8_t port_id;
+       char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_ddp_add_ddp =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_ddp_add_add =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, add, "add");
+cmdline_parse_token_num_t cmd_ddp_add_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ddp_add_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_ddp_add_filepath =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, filepath, NULL);
+
+static void
+cmd_ddp_add_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_ddp_add_result *res = parsed_result;
+       uint8_t *buff;
+       uint32_t size;
+       int ret = -ENOTSUP;
+
+       if (res->port_id > nb_ports) {
+               printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+               return;
+       }
+
+       if (!all_ports_stopped()) {
+               printf("Please stop all ports first\n");
+               return;
+       }
+
+       buff = open_ddp_package_file(res->filepath, &size);
+       if (!buff)
+               return;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+       if (ret == -ENOTSUP)
+               ret = rte_pmd_i40e_process_ddp_package(res->port_id,
+                                              buff, size,
+                                              RTE_PMD_I40E_PKG_OP_WR_ADD);
+#endif
+
+       if (ret < 0)
+               printf("Failed to load profile.\n");
+       else if (ret > 0)
+               printf("Profile has already existed.\n");
+
+       close_ddp_package_file(buff);
+}
+
+cmdline_parse_inst_t cmd_ddp_add = {
+       .f = cmd_ddp_add_parsed,
+       .data = NULL,
+       .help_str = "ddp add <port_id> <profile_path>",
+       .tokens = {
+               (void *)&cmd_ddp_add_ddp,
+               (void *)&cmd_ddp_add_add,
+               (void *)&cmd_ddp_add_port_id,
+               (void *)&cmd_ddp_add_filepath,
+               NULL,
+       },
+};
+
+/* Get dynamic device personalization profile info list*/
+#define PROFILE_INFO_SIZE 48
+#define MAX_PROFILE_NUM 16
 
+struct cmd_ddp_get_list_result {
+       cmdline_fixed_string_t ddp;
+       cmdline_fixed_string_t get;
+       cmdline_fixed_string_t list;
+       uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_ddp_get_list_ddp =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, ddp, "ddp");
+cmdline_parse_token_string_t cmd_ddp_get_list_get =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, get, "get");
+cmdline_parse_token_string_t cmd_ddp_get_list_list =
+       TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, list, "list");
+cmdline_parse_token_num_t cmd_ddp_get_list_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ddp_get_list_result, port_id, UINT8);
+
+static void
+cmd_ddp_get_list_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_ddp_get_list_result *res = parsed_result;
+#ifdef RTE_LIBRTE_I40E_PMD
+       struct rte_pmd_i40e_profile_list *p_list;
+       struct rte_pmd_i40e_profile_info *p_info;
+       uint32_t p_num;
+       uint32_t size;
+       uint32_t i;
+#endif
+       int ret = -ENOTSUP;
+
+       if (res->port_id > nb_ports) {
+               printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+               return;
+       }
+
+#ifdef RTE_LIBRTE_I40E_PMD
+       size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4;
+       p_list = (struct rte_pmd_i40e_profile_list *)malloc(size);
+       if (!p_list)
+               printf("%s: Failed to malloc buffer\n", __func__);
+
+       if (ret == -ENOTSUP)
+               ret = rte_pmd_i40e_get_ddp_list(res->port_id,
+                                               (uint8_t *)p_list, size);
+
+       if (!ret) {
+               p_num = p_list->p_count;
+               printf("Profile number is: %d\n\n", p_num);
+
+               for (i = 0; i < p_num; i++) {
+                       p_info = &p_list->p_info[i];
+                       printf("Profile %d:\n", i);
+                       printf("Track id:     0x%x\n", p_info->track_id);
+                       printf("Version:      %d.%d.%d.%d\n",
+                              p_info->version.major,
+                              p_info->version.minor,
+                              p_info->version.update,
+                              p_info->version.draft);
+                       printf("Profile name: %s\n\n", p_info->name);
+               }
+       }
+
+       free(p_list);
+#endif
+
+       if (ret < 0)
+               printf("Failed to get ddp list\n");
+}
+
+cmdline_parse_inst_t cmd_ddp_get_list = {
+       .f = cmd_ddp_get_list_parsed,
+       .data = NULL,
+       .help_str = "ddp get list <port_id>",
+       .tokens = {
+               (void *)&cmd_ddp_get_list_ddp,
+               (void *)&cmd_ddp_get_list_get,
+               (void *)&cmd_ddp_get_list_list,
+               (void *)&cmd_ddp_get_list_port_id,
+               NULL,
+       },
+};
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12919,6 +13148,9 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_vf_tc_min_bw,
        (cmdline_parse_inst_t *)&cmd_vf_tc_max_bw,
        (cmdline_parse_inst_t *)&cmd_strict_link_prio,
+       (cmdline_parse_inst_t *)&cmd_tc_min_bw,
+       (cmdline_parse_inst_t *)&cmd_ddp_add,
+       (cmdline_parse_inst_t *)&cmd_ddp_get_list,
        NULL,
 };