Add a command to config speed with lanes and
added print the lane number for show info command.

Signed-off-by: Dengdui Huang <huangdeng...@huawei.com>
---
 app/test-pmd/cmdline.c                      | 199 +++++++++++++-------
 app/test-pmd/config.c                       |  78 +++++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   9 +
 3 files changed, 194 insertions(+), 92 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f521a1fe9e..413bf735a2 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -696,6 +696,11 @@ static void cmd_help_long_parsed(void *parsed_result,
                        " duplex (half|full|auto)\n"
                        "    Set speed and duplex for all ports or port_id\n\n"
 
+                       "port config (port_id|all)"
+                       " speed 
(10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto)"
+                       " lanes (lane_num) duplex (half|full|auto)\n"
+                       "    Set speed and duplex for all ports or port_id\n\n"
+
                        "port config (port_id|all) loopback (mode)\n"
                        "    Set loopback mode for all ports or port_id\n\n"
 
@@ -1357,14 +1362,19 @@ struct cmd_config_speed_all {
        cmdline_fixed_string_t all;
        cmdline_fixed_string_t item1;
        cmdline_fixed_string_t item2;
+       cmdline_fixed_string_t item3;
        cmdline_fixed_string_t value1;
-       cmdline_fixed_string_t value2;
+       uint8_t value2;
+       cmdline_fixed_string_t value3;
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
+parse_and_check_speed_duplex(char *speedstr, uint8_t lanes, char *duplexstr,
+                            uint32_t *speed)
 {
 
+       uint32_t speed_num;
+       char *endptr;
        int duplex;
 
        if (!strcmp(duplexstr, "half")) {
@@ -1378,47 +1388,22 @@ parse_and_check_speed_duplex(char *speedstr, char 
*duplexstr, uint32_t *speed)
                return -1;
        }
 
-       if (!strcmp(speedstr, "10")) {
-               *speed = (duplex == RTE_ETH_LINK_HALF_DUPLEX) ?
-                               RTE_ETH_LINK_SPEED_10M_HD : 
RTE_ETH_LINK_SPEED_10M;
-       } else if (!strcmp(speedstr, "100")) {
-               *speed = (duplex == RTE_ETH_LINK_HALF_DUPLEX) ?
-                               RTE_ETH_LINK_SPEED_100M_HD : 
RTE_ETH_LINK_SPEED_100M;
-       } else {
-               if (duplex != RTE_ETH_LINK_FULL_DUPLEX) {
-                       fprintf(stderr, "Invalid speed/duplex parameters\n");
-                       return -1;
-               }
-               if (!strcmp(speedstr, "1000")) {
-                       *speed = RTE_ETH_LINK_SPEED_1G;
-               } else if (!strcmp(speedstr, "2500")) {
-                       *speed = RTE_ETH_LINK_SPEED_2_5G;
-               } else if (!strcmp(speedstr, "5000")) {
-                       *speed = RTE_ETH_LINK_SPEED_5G;
-               } else if (!strcmp(speedstr, "10000")) {
-                       *speed = RTE_ETH_LINK_SPEED_10G;
-               } else if (!strcmp(speedstr, "25000")) {
-                       *speed = RTE_ETH_LINK_SPEED_25G;
-               } else if (!strcmp(speedstr, "40000")) {
-                       *speed = RTE_ETH_LINK_SPEED_40G;
-               } else if (!strcmp(speedstr, "50000")) {
-                       *speed = RTE_ETH_LINK_SPEED_50G;
-               } else if (!strcmp(speedstr, "100000")) {
-                       *speed = RTE_ETH_LINK_SPEED_100G;
-               } else if (!strcmp(speedstr, "200000")) {
-                       *speed = RTE_ETH_LINK_SPEED_200G;
-               } else if (!strcmp(speedstr, "400000")) {
-                       *speed = RTE_ETH_LINK_SPEED_400G;
-               } else if (!strcmp(speedstr, "auto")) {
-                       *speed = RTE_ETH_LINK_SPEED_AUTONEG;
-               } else {
-                       fprintf(stderr, "Unknown speed parameter\n");
-                       return -1;
-               }
+       if (!strcmp(speedstr, "auto")) {
+               *speed = RTE_ETH_LINK_SPEED_AUTONEG;
+               return 0;
        }
 
-       if (*speed != RTE_ETH_LINK_SPEED_AUTONEG)
-               *speed |= RTE_ETH_LINK_SPEED_FIXED;
+       speed_num = strtol(speedstr, &endptr, 10);
+       if (*endptr != '\0') {
+               fprintf(stderr, "Unknown speed parameter\n");
+               return -1;
+       }
+
+       *speed = rte_eth_speed_bitflag(speed_num, lanes, duplex);
+       if (*speed == 0) {
+               fprintf(stderr, "param error\n");
+               return -1;
+       }
 
        return 0;
 }
@@ -1426,22 +1411,37 @@ parse_and_check_speed_duplex(char *speedstr, char 
*duplexstr, uint32_t *speed)
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
                        __rte_unused struct cmdline *cl,
-                       __rte_unused void *data)
+                       void *data)
 {
        struct cmd_config_speed_all *res = parsed_result;
+       struct rte_eth_dev_info dev_info;
        uint32_t link_speed;
        portid_t pid;
+       int ret;
 
        if (!all_ports_stopped()) {
                fprintf(stderr, "Please stop all ports first\n");
                return;
        }
 
-       if (parse_and_check_speed_duplex(res->value1, res->value2,
-                       &link_speed) < 0)
+       if (data)
+               ret = parse_and_check_speed_duplex(res->value1, res->value2,
+                                                  res->value3, &link_speed);
+       else
+               ret = parse_and_check_speed_duplex(res->value1, 0, res->value3,
+                                                  &link_speed);
+       if (ret < 0)
                return;
 
        RTE_ETH_FOREACH_DEV(pid) {
+               ret = eth_dev_info_get_print_err(pid, &dev_info);
+               if (ret != 0)
+                       return;
+               if ((dev_info.dev_capa & RTE_ETH_DEV_CAPA_SETTING_LANES) == 0 
&& data) {
+                       fprintf(stderr, "The port (%d) does not support setting 
lane\n",
+                               pid);
+                       return;
+               }
                ports[pid].dev_conf.link_speeds = link_speed;
        }
 
@@ -1460,26 +1460,51 @@ static cmdline_parse_token_string_t 
cmd_config_speed_all_item1 =
 static cmdline_parse_token_string_t cmd_config_speed_all_value1 =
        TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
                                
"10#100#1000#2500#5000#10000#25000#40000#50000#100000#200000#400000#auto");
-static cmdline_parse_token_string_t cmd_config_speed_all_item2 =
-       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
-static cmdline_parse_token_string_t cmd_config_speed_all_value2 =
-       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
+static cmdline_parse_token_string_t cmd_config_speed_all__item2 =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "lanes");
+static cmdline_parse_token_num_t cmd_config_speed_all_value2 =
+       TOKEN_NUM_INITIALIZER(struct cmd_config_speed_all, value2,
+                             RTE_UINT8);
+static cmdline_parse_token_string_t cmd_config_speed_all_item3 =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item3, "duplex");
+static cmdline_parse_token_string_t cmd_config_speed_all_value3 =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value3,
                                                "half#full#auto");
 
-static cmdline_parse_inst_t cmd_config_speed_all = {
+static cmdline_parse_inst_t cmd_config_speed_lanes_all = {
        .f = cmd_config_speed_all_parsed,
-       .data = NULL,
+       .data = (void *)1,
        .help_str = "port config all speed "
-               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto duplex 
"
-                                                       "half|full|auto",
+               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto"
+               " lanes <lanes> duplex half|full|auto",
        .tokens = {
                (void *)&cmd_config_speed_all_port,
                (void *)&cmd_config_speed_all_keyword,
                (void *)&cmd_config_speed_all_all,
                (void *)&cmd_config_speed_all_item1,
                (void *)&cmd_config_speed_all_value1,
-               (void *)&cmd_config_speed_all_item2,
+               (void *)&cmd_config_speed_all__item2,
                (void *)&cmd_config_speed_all_value2,
+               (void *)&cmd_config_speed_all_item3,
+               (void *)&cmd_config_speed_all_value3,
+               NULL,
+       },
+};
+
+static cmdline_parse_inst_t cmd_config_speed_all = {
+       .f = cmd_config_speed_all_parsed,
+       .data = (void *)0,
+       .help_str = "port config all speed "
+               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto"
+               " duplex half|full|auto",
+       .tokens = {
+               (void *)&cmd_config_speed_all_port,
+               (void *)&cmd_config_speed_all_keyword,
+               (void *)&cmd_config_speed_all_all,
+               (void *)&cmd_config_speed_all_item1,
+               (void *)&cmd_config_speed_all_value1,
+               (void *)&cmd_config_speed_all_item3,
+               (void *)&cmd_config_speed_all_value3,
                NULL,
        },
 };
@@ -1491,17 +1516,20 @@ struct cmd_config_speed_specific {
        portid_t id;
        cmdline_fixed_string_t item1;
        cmdline_fixed_string_t item2;
+       cmdline_fixed_string_t item3;
        cmdline_fixed_string_t value1;
-       cmdline_fixed_string_t value2;
+       uint8_t value2;
+       cmdline_fixed_string_t value3;
 };
 
 static void
 cmd_config_speed_specific_parsed(void *parsed_result,
-                               __rte_unused struct cmdline *cl,
-                               __rte_unused void *data)
+                               __rte_unused struct cmdline *cl, void *data)
 {
        struct cmd_config_speed_specific *res = parsed_result;
+       struct rte_eth_dev_info dev_info;
        uint32_t link_speed;
+       int ret;
 
        if (port_id_is_invalid(res->id, ENABLED_WARN))
                return;
@@ -1511,8 +1539,23 @@ cmd_config_speed_specific_parsed(void *parsed_result,
                return;
        }
 
-       if (parse_and_check_speed_duplex(res->value1, res->value2,
-                       &link_speed) < 0)
+       ret = eth_dev_info_get_print_err(res->id, &dev_info);
+       if (ret != 0)
+               return;
+
+       if ((dev_info.dev_capa & RTE_ETH_DEV_CAPA_SETTING_LANES) == 0 && data) {
+               fprintf(stderr, "The port (%d) does not support setting 
lanes\n",
+                       res->id);
+               return;
+       }
+
+       if (data)
+               ret = parse_and_check_speed_duplex(res->value1, res->value2,
+                                                  res->value3, &link_speed);
+       else
+               ret = parse_and_check_speed_duplex(res->value1, 0, res->value3,
+                                                  &link_speed);
+       if (ret < 0)
                return;
 
        ports[res->id].dev_conf.link_speeds = link_speed;
@@ -1537,17 +1580,23 @@ static cmdline_parse_token_string_t 
cmd_config_speed_specific_value1 =
                                
"10#100#1000#2500#5000#10000#25000#40000#50000#100000#200000#400000#auto");
 static cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
        TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
+                                                               "lanes");
+static cmdline_parse_token_num_t cmd_config_speed_specific_value2 =
+       TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, value2,
+                             RTE_UINT8);
+static cmdline_parse_token_string_t cmd_config_speed_specific_item3 =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item3,
                                                                "duplex");
-static cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
-       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
+static cmdline_parse_token_string_t cmd_config_speed_specific_value3 =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value3,
                                                        "half#full#auto");
 
-static cmdline_parse_inst_t cmd_config_speed_specific = {
+static cmdline_parse_inst_t cmd_config_speed_lanes_specific = {
        .f = cmd_config_speed_specific_parsed,
-       .data = NULL,
+       .data = (void *)1,
        .help_str = "port config <port_id> speed "
-               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto duplex 
"
-                                                       "half|full|auto",
+               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto"
+               " lanes <lane_num> duplex half|full|auto",
        .tokens = {
                (void *)&cmd_config_speed_specific_port,
                (void *)&cmd_config_speed_specific_keyword,
@@ -1556,6 +1605,26 @@ static cmdline_parse_inst_t cmd_config_speed_specific = {
                (void *)&cmd_config_speed_specific_value1,
                (void *)&cmd_config_speed_specific_item2,
                (void *)&cmd_config_speed_specific_value2,
+               (void *)&cmd_config_speed_specific_item3,
+               (void *)&cmd_config_speed_specific_value3,
+               NULL,
+       },
+};
+
+static cmdline_parse_inst_t cmd_config_speed_specific = {
+       .f = cmd_config_speed_specific_parsed,
+       .data = (void *)0,
+       .help_str = "port config <port_id> speed "
+               
"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto"
+               " duplex half|full|auto",
+       .tokens = {
+               (void *)&cmd_config_speed_specific_port,
+               (void *)&cmd_config_speed_specific_keyword,
+               (void *)&cmd_config_speed_specific_id,
+               (void *)&cmd_config_speed_specific_item1,
+               (void *)&cmd_config_speed_specific_value1,
+               (void *)&cmd_config_speed_specific_item3,
+               (void *)&cmd_config_speed_specific_value3,
                NULL,
        },
 };
@@ -13237,6 +13306,8 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_set_port_setup_on,
        (cmdline_parse_inst_t *)&cmd_config_speed_all,
        (cmdline_parse_inst_t *)&cmd_config_speed_specific,
+       (cmdline_parse_inst_t *)&cmd_config_speed_lanes_all,
+       (cmdline_parse_inst_t *)&cmd_config_speed_lanes_specific,
        (cmdline_parse_inst_t *)&cmd_config_loopback_all,
        (cmdline_parse_inst_t *)&cmd_config_loopback_specific,
        (cmdline_parse_inst_t *)&cmd_config_rx_tx,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ba1007ace6..3f77f321a5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -587,39 +587,51 @@ device_infos_display_speeds(uint32_t speed_capa)
        if (speed_capa == RTE_ETH_LINK_SPEED_AUTONEG)
                printf(" Autonegotiate (all speeds)");
        if (speed_capa & RTE_ETH_LINK_SPEED_FIXED)
-               printf(" Disable autonegotiate (fixed speed)  ");
+               printf(" Disable autonegotiate (fixed speed) /");
        if (speed_capa & RTE_ETH_LINK_SPEED_10M_HD)
-               printf(" 10 Mbps half-duplex  ");
+               printf(" 10Mbps_1lane_half-duplex /");
        if (speed_capa & RTE_ETH_LINK_SPEED_10M)
-               printf(" 10 Mbps full-duplex  ");
+               printf(" 10Mbps_1lane_full-duplex /");
        if (speed_capa & RTE_ETH_LINK_SPEED_100M_HD)
-               printf(" 100 Mbps half-duplex  ");
+               printf(" 100Mbps_lane_half-duplex /");
        if (speed_capa & RTE_ETH_LINK_SPEED_100M)
-               printf(" 100 Mbps full-duplex  ");
+               printf(" 100Mbps_1lane_full-duplex /");
        if (speed_capa & RTE_ETH_LINK_SPEED_1G)
-               printf(" 1 Gbps  ");
+               printf(" 1Gbps_1lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_2_5G)
-               printf(" 2.5 Gbps  ");
+               printf(" 2.5Gbps_1lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_5G)
-               printf(" 5 Gbps  ");
+               printf(" 5Gbps_1lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_10G)
-               printf(" 10 Gbps  ");
-       if (speed_capa & RTE_ETH_LINK_SPEED_20G)
-               printf(" 20 Gbps  ");
+               printf(" 10Gbps_1lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_10G_4LANES)
+               printf(" 10Gbps_4lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_20G_2LANES)
+               printf(" 20Gbps_2lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_25G)
-               printf(" 25 Gbps  ");
-       if (speed_capa & RTE_ETH_LINK_SPEED_40G)
-               printf(" 40 Gbps  ");
+               printf(" 25Gbps_1lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_40G_4LANES)
+               printf(" 40Gbps_4lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_50G)
-               printf(" 50 Gbps  ");
-       if (speed_capa & RTE_ETH_LINK_SPEED_56G)
-               printf(" 56 Gbps  ");
+               printf(" 50Gbps_1lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_50G_2LANES)
+               printf(" 50Gbps_2lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_56G_4LANES)
+               printf(" 56Gbps_4lane /");
        if (speed_capa & RTE_ETH_LINK_SPEED_100G)
-               printf(" 100 Gbps  ");
-       if (speed_capa & RTE_ETH_LINK_SPEED_200G)
-               printf(" 200 Gbps  ");
-       if (speed_capa & RTE_ETH_LINK_SPEED_400G)
-               printf(" 400 Gbps  ");
+               printf(" 100Gbps_1lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_100G_2LANES)
+               printf(" 100Gbps_2lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_100G_4LANES)
+               printf(" 100Gbps_4lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_200G_4LANES)
+               printf(" 200Gbps_4lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_200G_2LANES)
+               printf(" 200Gbps_2lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_400G_4LANES)
+               printf(" 400Gbps_4lane /");
+       if (speed_capa & RTE_ETH_LINK_SPEED_400G_8LANES)
+               printf(" 400Gbps_8lane /");
 }
 
 void
@@ -828,6 +840,10 @@ port_infos_display(portid_t port_id)
 
        printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
        printf("Link speed: %s\n", rte_eth_link_speed_to_str(link.link_speed));
+       if (link.link_lanes == 0)
+               printf("Link lanes: unknown\n");
+       else
+               printf("Link lanes: %u\n", link.link_lanes);
        printf("Link duplex: %s\n", (link.link_duplex == 
RTE_ETH_LINK_FULL_DUPLEX) ?
               ("full-duplex") : ("half-duplex"));
        printf("Autoneg status: %s\n", (link.link_autoneg == 
RTE_ETH_LINK_AUTONEG) ?
@@ -962,8 +978,8 @@ port_summary_header_display(void)
 
        port_number = rte_eth_dev_count_avail();
        printf("Number of available ports: %i\n", port_number);
-       printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", 
"Name",
-                       "Driver", "Status", "Link");
+       printf("%-4s %-17s %-12s %-14s %-8s %-8s %s\n", "Port", "MAC Address", 
"Name",
+                       "Driver", "Status", "Link", "Lanes");
 }
 
 void
@@ -993,10 +1009,16 @@ port_summary_display(portid_t port_id)
        if (ret != 0)
                return;
 
-       printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %s\n",
-               port_id, RTE_ETHER_ADDR_BYTES(&mac_addr), name,
-               dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-               rte_eth_link_speed_to_str(link.link_speed));
+       if (link.link_lanes == RTE_ETH_LANES_UNKNOWN)
+               printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %-8s 
%s\n",
+                       port_id, RTE_ETHER_ADDR_BYTES(&mac_addr), name,
+                       dev_info.driver_name, (link.link_status) ? ("up") : 
("down"),
+                       rte_eth_link_speed_to_str(link.link_speed), "unknown");
+       else
+               printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %-8s 
%u\n",
+                       port_id, RTE_ETHER_ADDR_BYTES(&mac_addr), name,
+                       dev_info.driver_name, (link.link_status) ? ("up") : 
("down"),
+                       rte_eth_link_speed_to_str(link.link_speed), 
link.link_lanes);
 }
 
 void
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst 
b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2fbf9220d8..118a0956bc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -190,6 +190,7 @@ For example:
    memory allocation on the socket: 0
    Link status: up
    Link speed: 40000 Mbps
+   Link lanes: 4
    Link duplex: full-duplex
    Promiscuous mode: enabled
    Allmulticast mode: disabled
@@ -2067,6 +2068,14 @@ Set the speed and duplex mode for all ports or a 
specific port::
    testpmd> port config (port_id|all) speed 
(10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto) \
             duplex (half|full|auto)
 
+port config - speed with lanes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set the speed, lanes and duplex mode for all ports or a specific port::
+
+   testpmd> port config (port_id|all) speed 
(10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto) \
+            lanes (lane_num) duplex (half|full|auto)
+
 port config - queues/descriptors
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- 
2.33.0

Reply via email to