Skip to content

Commit

Permalink
ethdev: support link speed lanes
Browse files Browse the repository at this point in the history
Update the eth_dev_ops structure with new function vectors
to get, get capabilities and set Ethernet link speed lanes.
Update the testpmd to provide required config and information
display infrastructure.

The supporting Ethernet controller driver will register callbacks
to avail link speed lanes config and get services. This lanes
configuration is applicable only when the NIC is forced to fixed
speeds. In Autonegotiation mode, the hardware automatically
negotiates the number of lanes.

These are the new commands.

testpmd> show port 0 speed_lanes capabilities

 Supported speeds         Valid lanes
-----------------------------------
 10 Gbps                  1
 25 Gbps                  1
 40 Gbps                  4
 50 Gbps                  1 2
 100 Gbps                 1 2 4
 200 Gbps                 2 4
 400 Gbps                 4 8
testpmd>

testpmd>
testpmd> port stop 0
testpmd> port config 0 speed_lanes 4
testpmd> port config 0 speed 200000 duplex full
testpmd> port start 0
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
Active Lanes: 4
Link duplex: full-duplex
Autoneg status: Off

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
  • Loading branch information
Damodharam Ammepalli authored and ferruhy committed Sep 27, 2024
1 parent 3fa84cc commit b741f55
Show file tree
Hide file tree
Showing 6 changed files with 480 additions and 1 deletion.
248 changes: 247 additions & 1 deletion app/test-pmd/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ static void cmd_help_long_parsed(void *parsed_result,

"dump_log_types\n"
" Dumps the log level for all the dpdk modules\n\n"

"show port (port_id) speed_lanes capabilities"
" Show speed lanes capabilities of a port.\n\n"
);
}

Expand Down Expand Up @@ -823,6 +826,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"port config (port_id) txq (queue_id) affinity (value)\n"
" Map a Tx queue with an aggregated port "
"of the DPDK port\n\n"

"port config (port_id|all) speed_lanes (value)\n"
" Set number of lanes for all ports or port_id for a forced speed\n\n"
);
}

Expand Down Expand Up @@ -1560,6 +1566,244 @@ static cmdline_parse_inst_t cmd_config_speed_specific = {
},
};

static int
parse_speed_lanes_cfg(portid_t pid, uint32_t lanes)
{
int ret;

ret = rte_eth_speed_lanes_set(pid, lanes);
if (ret == -ENOTSUP) {
fprintf(stderr, "Function not implemented\n");
return -1;
} else if (ret < 0) {
fprintf(stderr, "Set speed lanes failed\n");
return -1;
}

return 0;
}

static void
show_speed_lanes_capability(unsigned int num, struct rte_eth_speed_lanes_capa *speed_lanes_capa)
{
unsigned int i;
uint32_t capa;

printf("\n%-15s %-10s", "Supported-speeds", "Valid-lanes");
printf("\n-----------------------------------\n");
for (i = 0; i < num; i++) {
printf("%-17s ",
rte_eth_link_speed_to_str(speed_lanes_capa[i].speed));
capa = speed_lanes_capa[i].capa;
int s = 0;

while (capa) {
if (capa & 0x1)
printf("%-2d ", s);
s++;
capa = capa >> 1;
}
printf("\n");
}
}

/* *** display speed lanes per port capabilities *** */
struct cmd_show_speed_lanes_result {
cmdline_fixed_string_t cmd_show;
cmdline_fixed_string_t cmd_port;
cmdline_fixed_string_t cmd_keyword;
portid_t cmd_pid;
};

static void
cmd_show_speed_lanes_parsed(void *parsed_result,
__rte_unused struct cmdline *cl,
__rte_unused void *data)
{
struct cmd_show_speed_lanes_result *res = parsed_result;
struct rte_eth_speed_lanes_capa *speed_lanes_capa;
unsigned int num;
int ret;

if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
fprintf(stderr, "Invalid port id %u\n", res->cmd_pid);
return;
}

ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, NULL, 0);
if (ret == -ENOTSUP) {
fprintf(stderr, "Function not implemented\n");
return;
} else if (ret < 0) {
fprintf(stderr, "Get speed lanes capability failed: %d\n", ret);
return;
}

num = (unsigned int)ret;
speed_lanes_capa = calloc(num, sizeof(*speed_lanes_capa));
if (speed_lanes_capa == NULL) {
fprintf(stderr, "Failed to alloc speed lanes capability buffer\n");
return;
}

ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, speed_lanes_capa, num);
if (ret < 0) {
fprintf(stderr, "Error getting speed lanes capability: %d\n", ret);
goto out;
}

show_speed_lanes_capability(num, speed_lanes_capa);
out:
free(speed_lanes_capa);
}

static cmdline_parse_token_string_t cmd_show_speed_lanes_show =
TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
cmd_show, "show");
static cmdline_parse_token_string_t cmd_show_speed_lanes_port =
TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
cmd_port, "port");
static cmdline_parse_token_num_t cmd_show_speed_lanes_pid =
TOKEN_NUM_INITIALIZER(struct cmd_show_speed_lanes_result,
cmd_pid, RTE_UINT16);
static cmdline_parse_token_string_t cmd_show_speed_lanes_keyword =
TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
cmd_keyword, "speed_lanes");
static cmdline_parse_token_string_t cmd_show_speed_lanes_cap_keyword =
TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
cmd_keyword, "capabilities");

static cmdline_parse_inst_t cmd_show_speed_lanes = {
.f = cmd_show_speed_lanes_parsed,
.data = NULL,
.help_str = "show port <port_id> speed_lanes capabilities",
.tokens = {
(void *)&cmd_show_speed_lanes_show,
(void *)&cmd_show_speed_lanes_port,
(void *)&cmd_show_speed_lanes_pid,
(void *)&cmd_show_speed_lanes_keyword,
(void *)&cmd_show_speed_lanes_cap_keyword,
NULL,
},
};

/* *** configure speed_lanes for all ports *** */
struct cmd_config_speed_lanes_all {
cmdline_fixed_string_t port;
cmdline_fixed_string_t keyword;
cmdline_fixed_string_t all;
cmdline_fixed_string_t item;
uint32_t lanes;
};

static void
cmd_config_speed_lanes_all_parsed(void *parsed_result,
__rte_unused struct cmdline *cl,
__rte_unused void *data)
{
struct cmd_config_speed_lanes_all *res = parsed_result;
portid_t pid;

if (!all_ports_stopped()) {
fprintf(stderr, "Please stop all ports first\n");
return;
}

RTE_ETH_FOREACH_DEV(pid) {
if (parse_speed_lanes_cfg(pid, res->lanes))
return;
}

cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
}

static cmdline_parse_token_string_t cmd_config_speed_lanes_all_port =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, port, "port");
static cmdline_parse_token_string_t cmd_config_speed_lanes_all_keyword =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, keyword,
"config");
static cmdline_parse_token_string_t cmd_config_speed_lanes_all_all =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, all, "all");
static cmdline_parse_token_string_t cmd_config_speed_lanes_all_item =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, item,
"speed_lanes");
static cmdline_parse_token_num_t cmd_config_speed_lanes_all_lanes =
TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_all, lanes, RTE_UINT32);

static cmdline_parse_inst_t cmd_config_speed_lanes_all = {
.f = cmd_config_speed_lanes_all_parsed,
.data = NULL,
.help_str = "port config all speed_lanes <value>",
.tokens = {
(void *)&cmd_config_speed_lanes_all_port,
(void *)&cmd_config_speed_lanes_all_keyword,
(void *)&cmd_config_speed_lanes_all_all,
(void *)&cmd_config_speed_lanes_all_item,
(void *)&cmd_config_speed_lanes_all_lanes,
NULL,
},
};

/* *** configure speed_lanes for specific port *** */
struct cmd_config_speed_lanes_specific {
cmdline_fixed_string_t port;
cmdline_fixed_string_t keyword;
uint16_t port_id;
cmdline_fixed_string_t item;
uint32_t lanes;
};

static void
cmd_config_speed_lanes_specific_parsed(void *parsed_result,
__rte_unused struct cmdline *cl,
__rte_unused void *data)
{
struct cmd_config_speed_lanes_specific *res = parsed_result;

if (port_id_is_invalid(res->port_id, ENABLED_WARN))
return;

if (!port_is_stopped(res->port_id)) {
fprintf(stderr, "Please stop port %u first\n", res->port_id);
return;
}

if (parse_speed_lanes_cfg(res->port_id, res->lanes))
return;

cmd_reconfig_device_queue(res->port_id, 1, 1);
}

static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_port =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, port,
"port");
static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_keyword =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, keyword,
"config");
static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_id =
TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, port_id,
RTE_UINT16);
static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_item =
TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, item,
"speed_lanes");
static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_lanes =
TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, lanes,
RTE_UINT32);

static cmdline_parse_inst_t cmd_config_speed_lanes_specific = {
.f = cmd_config_speed_lanes_specific_parsed,
.data = NULL,
.help_str = "port config <port_id> speed_lanes <value>",
.tokens = {
(void *)&cmd_config_speed_lanes_specific_port,
(void *)&cmd_config_speed_lanes_specific_keyword,
(void *)&cmd_config_speed_lanes_specific_id,
(void *)&cmd_config_speed_lanes_specific_item,
(void *)&cmd_config_speed_lanes_specific_lanes,
NULL,
},
};

/* *** configure loopback for all ports *** */
struct cmd_config_loopback_all {
cmdline_fixed_string_t port;
Expand Down Expand Up @@ -1645,7 +1889,6 @@ cmd_config_loopback_specific_parsed(void *parsed_result,
cmd_reconfig_device_queue(res->port_id, 1, 1);
}


static cmdline_parse_token_string_t cmd_config_loopback_specific_port =
TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_specific, port,
"port");
Expand Down Expand Up @@ -13238,6 +13481,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
&cmd_set_port_setup_on,
&cmd_config_speed_all,
&cmd_config_speed_specific,
&cmd_config_speed_lanes_all,
&cmd_config_speed_lanes_specific,
&cmd_show_speed_lanes,
&cmd_config_loopback_all,
&cmd_config_loopback_specific,
&cmd_config_rx_tx,
Expand Down
4 changes: 4 additions & 0 deletions app/test-pmd/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ port_infos_display(portid_t port_id)
char name[RTE_ETH_NAME_MAX_LEN];
int ret;
char fw_version[ETHDEV_FWVERS_LEN];
uint32_t lanes;

if (port_id_is_invalid(port_id, ENABLED_WARN)) {
print_valid_ports();
Expand Down Expand Up @@ -828,6 +829,8 @@ 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 (rte_eth_speed_lanes_get(port_id, &lanes) == 0)
printf("Active Lanes: %d\n", 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) ?
Expand Down Expand Up @@ -7254,3 +7257,4 @@ show_mcast_macs(portid_t port_id)
printf(" %s\n", buf);
}
}

Loading

0 comments on commit b741f55

Please sign in to comment.