On Tue, Mar 12, 2024 at 12:52 AM Dengdui Huang wrote: > > Extended speed command for setting lane number and > Show info print lane number. > > Signed-off-by: Dengdui Huang > --- > app/test-pmd/cmdline.c | 110 +++++++++++--------- > app/test-pmd/config.c | 60 +++++++---- > doc/guides/rel_notes/release_24_03.rst | 1 + > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 3 +- > 4 files changed, 103 insertions(+), 71 deletions(-) > > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c > index f521a1fe9e..e66daf4bba 100644 > --- a/app/test-pmd/cmdline.c > +++ b/app/test-pmd/cmdline.c > @@ -1356,15 +1356,20 @@ struct cmd_config_speed_all { > cmdline_fixed_string_t keyword; > cmdline_fixed_string_t all; > cmdline_fixed_string_t item1; > + cmdline_fixed_string_t lanes_item; > cmdline_fixed_string_t item2; > cmdline_fixed_string_t value1; > + uint8_t lanes_value; > cmdline_fixed_string_t value2; > }; > > 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) > { > We internally implemented a similar feature, without changing the existing testpmd speed cmd. Instead of modifying the existing command set we can have a separate cmd for the lanes configuration similar to FEC configuration. Our internal implementation looks something like this, without affecting existing implementations. testpmd> port stop 0 testpmd> port config 0 speed_lanes 4 testpmd> port config 0 speed 200000 duplex full testpmd> port start 0 testpmd> show port summary 0 Number of available ports: 2 Port MAC Address Name Driver Status Link Lanes 0 14:23:F2:C3:BA:D2 0000:b1:00.0 net_bnxt up 200 Gbps 4 testpmd> testpmd> show port info 0 ********************* Infos for port 0 ********************* MAC address: 14:23:F2:C3:BA:D2 Device name: 0000:b1:00.0 Driver name: net_bnxt Firmware-version: 228.9.115.0 Connect to socket: 2 memory allocation on the socket: 2 Link status: up Link speed: 200 Gbps Lanes: 4 Link duplex: full-duplex Autoneg status: Off > + uint32_t speed_num; > + char *endptr; > int duplex; > > if (!strcmp(duplexstr, "half")) { > @@ -1378,47 +1383,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; > } > @@ -1429,19 +1409,27 @@ cmd_config_speed_all_parsed(void *parsed_result, > __rte_unused 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 (parse_and_check_speed_duplex(res->value1, res->lanes_value, > + res->value2, &link_speed) < 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) > + fprintf(stderr, "The setting lane may not take effect because " > + "the port (%u) does not support it\n", pid); > ports[pid].dev_conf.link_speeds = link_speed; > } > > @@ -1460,6 +1448,11 @@ 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_lanes_item = > + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, lanes_item, "lanes"); > +static cmdline_parse_token_num_t cmd_config_speed_all_lanes_value = > + TOKEN_NUM_INITIALIZER(struct cmd_config_speed_all, lanes_value, > + RTE_UINT8); > 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 = > @@ -1470,14 +1463,16 @@ static cmdline_parse_inst_t cmd_config_speed_all = { > .f = cmd_config_speed_all_parsed, > .data = NULL, > .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 1|2|4|8 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_lanes_item, > + (void *)&cmd_config_speed_all_lanes_value, > (void *)&cmd_config_speed_all_item2, > (void *)&cmd_config_speed_all_value2, > NULL, > @@ -1490,8 +1485,10 @@ struct cmd_config_speed_specific { > cmdline_fixed_string_t keyword; > portid_t id; > cmdline_fixed_string_t item1; > + cmdline_fixed_string_t lanes_item; > cmdline_fixed_string_t item2; > cmdline_fixed_string_t value1; > + uint8_t lanes_value; > cmdline_fixed_string_t value2; > }; > > @@ -1501,7 +1498,9 @@ cmd_config_speed_specific_parsed(void *parsed_result, > __rte_unused 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 +1510,15 @@ 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) > + fprintf(stderr, "The setting lane may not take effect because " > + "the port (%d) does not support it\n", res->id); > + > + if (parse_and_check_speed_duplex(res->value1, res->lanes_value, > + res->value2, &link_speed) < 0) > return; > > ports[res->id].dev_conf.link_speeds = link_speed; > @@ -1535,6 +1541,12 @@ static cmdline_parse_token_string_t cmd_config_speed_specific_item1 = > static cmdline_parse_token_string_t cmd_config_speed_specific_value1 = > TOKEN_STRING_INITIALIZER(struct 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_lanes_item = > + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, lanes_item, > + "lanes"); > +static cmdline_parse_token_num_t cmd_config_speed_specific_lanes_value = > + TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, lanes_value, > + RTE_UINT8); > static cmdline_parse_token_string_t cmd_config_speed_specific_item2 = > TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2, > "duplex"); > @@ -1546,14 +1558,16 @@ static cmdline_parse_inst_t cmd_config_speed_specific = { > .f = cmd_config_speed_specific_parsed, > .data = NULL, > .help_str = "port config 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 1|2|4|8 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_lanes_item, > + (void *)&cmd_config_speed_specific_lanes_value, > (void *)&cmd_config_speed_specific_item2, > (void *)&cmd_config_speed_specific_value2, > NULL, > diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c > index 968d2164ab..c104327878 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_full-duplex /"); > if (speed_capa & RTE_ETH_LINK_SPEED_2_5G) > - printf(" 2.5 Gbps "); > + printf(" 2.5Gbps_1lane_full-duplex /"); > if (speed_capa & RTE_ETH_LINK_SPEED_5G) > - printf(" 5 Gbps "); > + printf(" 5Gbps_1lane_full-duplex /"); > 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_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_10G_4LANES) > + printf(" 10Gbps_4lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_20G_2LANES) > + printf(" 20Gbps_2lane_full-duplex /"); > 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_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_40G_4LANES) > + printf(" 40Gbps_4lane_full-duplex /"); > 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_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_50G_2LANES) > + printf(" 50Gbps_2lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_56G_4LANES) > + printf(" 56Gbps_4lane_full-duplex /"); > 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_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_100G_2LANES) > + printf(" 100Gbps_2lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_100G_4LANES) > + printf(" 100Gbps_4lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_200G_4LANES) > + printf(" 200Gbps_4lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_200G_2LANES) > + printf(" 200Gbps_2lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_400G_4LANES) > + printf(" 400Gbps_4lane_full-duplex /"); > + if (speed_capa & RTE_ETH_LINK_SPEED_400G_8LANES) > + printf(" 400Gbps_8lane_full-duplex /"); > } > > 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) ? > diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst > index c17334ac25..46aceeee93 100644 > --- a/doc/guides/rel_notes/release_24_03.rst > +++ b/doc/guides/rel_notes/release_24_03.rst > @@ -79,6 +79,7 @@ New Features > * **Support setting lanes for ethdev.** > * Support setting lanes by extended ``RTE_ETH_LINK_SPEED_*``. > * Added function to convert bitmap flag to the struct of link speed info. > + ``rte_eth_speed_capa_to_info()`` > > * **Added hash calculation of an encapsulated packet as done by the HW.** > > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > index 2fbf9220d8..087f7fe853 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 > @@ -2065,7 +2066,7 @@ port config - speed > 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) > + lanes 1|2|4|8 duplex (half|full|auto) > > port config - queues/descriptors > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > -- > 2.33.0 > -- This electronic communication and the information and any files transmitted with it, or attached to it, are confidential and are intended solely for the use of the individual or entity to whom it is addressed and may contain information that is confidential, legally privileged, protected by privacy laws, or otherwise restricted from disclosure to anyone else. If you are not the intended recipient or the person responsible for delivering the e-mail to the intended recipient, you are hereby notified that any use, copying, distributing, dissemination, forwarding, printing, or copying of this e-mail is strictly prohibited. If you received this e-mail in error, please return the e-mail to the sender, delete it from your computer, and destroy any printed copy of it.