From patchwork Wed Apr 3 22:53:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Pazdan X-Patchwork-Id: 139093 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 00D2143DF6; Thu, 4 Apr 2024 09:48:21 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C6D4B402D8; Thu, 4 Apr 2024 09:48:15 +0200 (CEST) Received: from mail-pf1-f225.google.com (mail-pf1-f225.google.com [209.85.210.225]) by mails.dpdk.org (Postfix) with ESMTP id E11974027B for ; Thu, 4 Apr 2024 00:53:36 +0200 (CEST) Received: by mail-pf1-f225.google.com with SMTP id d2e1a72fcca58-6e6fb9a494aso337481b3a.0 for ; Wed, 03 Apr 2024 15:53:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712184816; x=1712789616; h=content-transfer-encoding:message-id:date:subject:cc:to:from :dkim-signature:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=aIz/cEroY9gR6hApGt5GM4/qEDM7amFJ3JX6/7kOkNk=; b=mza3BsPS3eIbQdUKORbEFpyXwd5ktWUU7HbM1nFwcXxEwmkBvAGQYM5fol1PaLFHhW RpjO4audhEgj/To1Z6rOAnppChwBInZiQXXyzK4F8/pk2iBBgD6u6mk89ITeoOfNajZE 2aHD7Ceyhsj8vnG5gd/jMfyYz0r9CutyDXHKjg8TuW8PoVc67Oul3OPJzemcNLCFyb9V Z3zddHoTmc3U0xmku9IzH75PFlHWAZPH5PqGo7iiQd2/ChEjG6pAtALPVjJd6vkMXzSI ZXbxpcOF03gkbbeS4XZ8NqnxWrndeh12/JdI85SKa7SxySdYu4GXU7TtdHVCMNH61Woj +OPg== X-Gm-Message-State: AOJu0YzosXejvISheOOKneKyaFLXbf1BOk7CRLB8eB1P3Y4gV8uKYxQc uu4nvZQbKlwXuhhAxL3VjqwTbqVvr0t/7Lcl5hsjvo3oJrzRLJi/HG45jvSnQTdoyArP9FE1spr irPo78p0aErWmQYJBMwA6qB4PWhKEfwsBcVWd6g== X-Google-Smtp-Source: AGHT+IG+QUMiEYZc8oZF1fm4s+P3m+w/jTPHojnX/QjgOLIlL2K81VSCGSq25Q5g2faO3Cyevkr2ptt5meVS X-Received: by 2002:a05:6a20:d81a:b0:1a3:ae18:f1e4 with SMTP id iv26-20020a056a20d81a00b001a3ae18f1e4mr1463380pzb.34.1712184815872; Wed, 03 Apr 2024 15:53:35 -0700 (PDT) Received: from smtp.aristanetworks.com ([74.123.28.25]) by smtp-relay.gmail.com with ESMTPS id sd7-20020a17090b514700b0029c77d83fa5sm26934pjb.10.2024.04.03.15.53.35 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Apr 2024 15:53:35 -0700 (PDT) X-Relaying-Domain: arista.com Received: from mpazdan-autoneg-dpdk-0.sjc.aristanetworks.com (jhall-thisprojectnameisexactly64charspad-us183.sjc.aristanetworks.com [10.243.132.215]) by smtp.aristanetworks.com (Postfix) with ESMTP id 04D6A402016; Wed, 3 Apr 2024 15:53:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=Arista-A; t=1712184815; bh=aIz/cEroY9gR6hApGt5GM4/qEDM7amFJ3JX6/7kOkNk=; h=From:To:Cc:Subject:Date:From; b=Rt19imrLTVWcAoV8KlBhqF76z8cnUWV6mZLTKH8vT2OZ1WwqEnv+xg/oVfnen+v7s wQmjNrfoqZcyJSVl7FYxNrJToANcXgi3L6lAIFLqg06hIyASMzZsRSY0CEH9EssgCC I/JNOo8H6ojIBpIExuEqx214hr5ZYtfhoiPCrTDZwuU4d+24VmUSyaQIV7a6vP7LGS E4FzW+yJ+Wx2g814ATd1UDlE9t9kOVL8BG0rExFKNbg1uZbhq/8LCrA6rdt38Ju5JJ SvQM9wsW2g03Fqov3GDCulS/pnhmO+ptMXVqSqy15Aqy4CciLa6cakmVe9V2W1hy0a emuaxdUrznGig== X-SMTP-Authentication: Allow-List-permitted X-SMTP-Authentication: Allow-List-permitted From: Marek Pazdan To: Aman Singh , Yuying Zhang Cc: dev@dpdk.org, Marek Pazdan Subject: [PATCH] dpdk-testpmd: call get/set link settings interface Date: Wed, 3 Apr 2024 15:53:32 -0700 Message-ID: <20240403225333.16260-1-mpazdan@arista.com> X-Mailman-Approved-At: Thu, 04 Apr 2024 09:48:12 +0200 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add cmdline options for utilizing get/set link settings API added before in patch this patch depends on. Purpose of this change is to provide mechanism for testing link settings interface API. Signed-off-by: Marek Pazdan --- Depends-on: patch-139082 ("lib: add get/set link settings interface") --- app/test-pmd/cmdline.c | 9 + app/test-pmd/cmdline_settings.c | 516 ++++++++++++++++++++++++++++++++ app/test-pmd/cmdline_settings.h | 14 + app/test-pmd/meson.build | 1 + app/test-pmd/testpmd.h | 1 + app/test-pmd/util.c | 10 + 6 files changed, 551 insertions(+) create mode 100644 app/test-pmd/cmdline_settings.c create mode 100644 app/test-pmd/cmdline_settings.h diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index b7759e38a8..7fdd134467 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -65,6 +65,7 @@ #include "cmdline_cman.h" #include "cmdline_mtr.h" #include "cmdline_tm.h" +#include "cmdline_settings.h" #include "bpf_cmd.h" static struct cmdline *testpmd_cl; @@ -255,6 +256,9 @@ static void cmd_help_long_parsed(void *parsed_result, "show port (port_id) flow_ctrl" " Show flow control info of a port.\n\n" + "show port (port_id) link settings" + " Show link settings of a port.\n\n" + "dump_physmem\n" " Dumps all physical memory segment layouts\n\n" @@ -661,6 +665,9 @@ static void cmd_help_long_parsed(void *parsed_result, "(max_thresh) (prob_inv)]\n" " Set congestion management configuration\n\n" + "set port (port_id) link settings advertising (bitmap_str)" + " Set link advertising settings of a port.\n\n" + , list_pkt_forwarding_modes() ); } @@ -13219,6 +13226,8 @@ static cmdline_parse_ctx_t builtin_ctx[] = { (cmdline_parse_inst_t *)&cmd_link_flow_control_set_macfwd, (cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg, (cmdline_parse_inst_t *)&cmd_link_flow_control_show, + (cmdline_parse_inst_t *)&cmd_link_settings_show, + (cmdline_parse_inst_t *)&cmd_link_settings_set_advertising, (cmdline_parse_inst_t *)&cmd_priority_flow_control_set, (cmdline_parse_inst_t *)&cmd_queue_priority_flow_control_set, (cmdline_parse_inst_t *)&cmd_config_dcb, diff --git a/app/test-pmd/cmdline_settings.c b/app/test-pmd/cmdline_settings.c new file mode 100644 index 0000000000..4db6bd4e9a --- /dev/null +++ b/app/test-pmd/cmdline_settings.c @@ -0,0 +1,516 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2024 Arista Networks, Inc. All rights reserved. + * Arista Networks, Inc. Confidential and Proprietary + */ + +#include +#include + +#include +#include + +#include "testpmd.h" + +/* *** GET CURRENT ETHERNET LINK SETTINGS *** */ +struct cmd_link_settings_show { + cmdline_fixed_string_t show; + cmdline_fixed_string_t port; + portid_t port_id; + cmdline_fixed_string_t link; + cmdline_fixed_string_t settings; +}; + +cmdline_parse_token_string_t cmd_ls_show_show = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_show, + show, "show"); +cmdline_parse_token_string_t cmd_ls_show_port = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_show, + port, "port"); +cmdline_parse_token_num_t cmd_ls_show_portid = + TOKEN_NUM_INITIALIZER(struct cmd_link_settings_show, + port_id, RTE_UINT16); +cmdline_parse_token_string_t cmd_ls_show_link = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_show, + link, "link"); +cmdline_parse_token_string_t cmd_ls_show_settings = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_show, + settings, "settings"); + +/* Print link capability flags (supported, advertised or lp_advertised). + * Assumes that the corresponding SUPPORTED and ADVERTISED flags are equal. + */ +static void dump_link_caps(const char *prefix, const char *an_prefix, + const uint32_t *mask, int link_mode_only) +{ + static const struct { + int same_line; /* print on same line as previous */ + unsigned int bit_index; + const char *name; + } mode_defs[] = { + { 0, RTE_LINK_MODE_10baseT_Half_BIT, + "10baseT/Half" }, + { 1, RTE_LINK_MODE_10baseT_Full_BIT, + "10baseT/Full" }, + { 0, RTE_LINK_MODE_100baseT_Half_BIT, + "100baseT/Half" }, + { 1, RTE_LINK_MODE_100baseT_Full_BIT, + "100baseT/Full" }, + { 0, RTE_LINK_MODE_100baseT1_Full_BIT, + "100baseT1/Full" }, + { 0, RTE_LINK_MODE_1000baseT_Half_BIT, + "1000baseT/Half" }, + { 1, RTE_LINK_MODE_1000baseT_Full_BIT, + "1000baseT/Full" }, + { 0, RTE_LINK_MODE_1000baseT1_Full_BIT, + "1000baseT1/Full" }, + { 0, RTE_LINK_MODE_1000baseKX_Full_BIT, + "1000baseKX/Full" }, + { 0, RTE_LINK_MODE_2500baseX_Full_BIT, + "2500baseX/Full" }, + { 0, RTE_LINK_MODE_10000baseT_Full_BIT, + "10000baseT/Full" }, + { 0, RTE_LINK_MODE_10000baseKX4_Full_BIT, + "10000baseKX4/Full" }, + { 0, RTE_LINK_MODE_10000baseKR_Full_BIT, + "10000baseKR/Full" }, + { 0, RTE_LINK_MODE_10000baseR_FEC_BIT, + "10000baseR_FEC" }, + { 0, RTE_LINK_MODE_20000baseMLD2_Full_BIT, + "20000baseMLD2/Full" }, + { 0, RTE_LINK_MODE_20000baseKR2_Full_BIT, + "20000baseKR2/Full" }, + { 0, RTE_LINK_MODE_40000baseKR4_Full_BIT, + "40000baseKR4/Full" }, + { 0, RTE_LINK_MODE_40000baseCR4_Full_BIT, + "40000baseCR4/Full" }, + { 0, RTE_LINK_MODE_40000baseSR4_Full_BIT, + "40000baseSR4/Full" }, + { 0, RTE_LINK_MODE_40000baseLR4_Full_BIT, + "40000baseLR4/Full" }, + { 0, RTE_LINK_MODE_56000baseKR4_Full_BIT, + "56000baseKR4/Full" }, + { 0, RTE_LINK_MODE_56000baseCR4_Full_BIT, + "56000baseCR4/Full" }, + { 0, RTE_LINK_MODE_56000baseSR4_Full_BIT, + "56000baseSR4/Full" }, + { 0, RTE_LINK_MODE_56000baseLR4_Full_BIT, + "56000baseLR4/Full" }, + { 0, RTE_LINK_MODE_25000baseCR_Full_BIT, + "25000baseCR/Full" }, + { 0, RTE_LINK_MODE_25000baseKR_Full_BIT, + "25000baseKR/Full" }, + { 0, RTE_LINK_MODE_25000baseSR_Full_BIT, + "25000baseSR/Full" }, + { 0, RTE_LINK_MODE_50000baseCR2_Full_BIT, + "50000baseCR2/Full" }, + { 0, RTE_LINK_MODE_50000baseKR2_Full_BIT, + "50000baseKR2/Full" }, + { 0, RTE_LINK_MODE_100000baseKR4_Full_BIT, + "100000baseKR4/Full" }, + { 0, RTE_LINK_MODE_100000baseSR4_Full_BIT, + "100000baseSR4/Full" }, + { 0, RTE_LINK_MODE_100000baseCR4_Full_BIT, + "100000baseCR4/Full" }, + { 0, RTE_LINK_MODE_100000baseLR4_ER4_Full_BIT, + "100000baseLR4_ER4/Full" }, + { 0, RTE_LINK_MODE_50000baseSR2_Full_BIT, + "50000baseSR2/Full" }, + { 0, RTE_LINK_MODE_1000baseX_Full_BIT, + "1000baseX/Full" }, + { 0, RTE_LINK_MODE_10000baseCR_Full_BIT, + "10000baseCR/Full" }, + { 0, RTE_LINK_MODE_10000baseSR_Full_BIT, + "10000baseSR/Full" }, + { 0, RTE_LINK_MODE_10000baseLR_Full_BIT, + "10000baseLR/Full" }, + { 0, RTE_LINK_MODE_10000baseLRM_Full_BIT, + "10000baseLRM/Full" }, + { 0, RTE_LINK_MODE_10000baseER_Full_BIT, + "10000baseER/Full" }, + { 0, RTE_LINK_MODE_2500baseT_Full_BIT, + "2500baseT/Full" }, + { 0, RTE_LINK_MODE_5000baseT_Full_BIT, + "5000baseT/Full" }, + { 0, RTE_LINK_MODE_50000baseKR_Full_BIT, + "50000baseKR/Full" }, + { 0, RTE_LINK_MODE_50000baseSR_Full_BIT, + "50000baseSR/Full" }, + { 0, RTE_LINK_MODE_50000baseCR_Full_BIT, + "50000baseCR/Full" }, + { 0, RTE_LINK_MODE_50000baseLR_ER_FR_Full_BIT, + "50000baseLR_ER_FR/Full" }, + { 0, RTE_LINK_MODE_50000baseDR_Full_BIT, + "50000baseDR/Full" }, + { 0, RTE_LINK_MODE_100000baseKR2_Full_BIT, + "100000baseKR2/Full" }, + { 0, RTE_LINK_MODE_100000baseSR2_Full_BIT, + "100000baseSR2/Full" }, + { 0, RTE_LINK_MODE_100000baseCR2_Full_BIT, + "100000baseCR2/Full" }, + { 0, RTE_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, + "100000baseLR2_ER2_FR2/Full" }, + { 0, RTE_LINK_MODE_100000baseDR2_Full_BIT, + "100000baseDR2/Full" }, + { 0, RTE_LINK_MODE_200000baseKR4_Full_BIT, + "200000baseKR4/Full" }, + { 0, RTE_LINK_MODE_200000baseSR4_Full_BIT, + "200000baseSR4/Full" }, + { 0, RTE_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, + "200000baseLR4_ER4_FR4/Full" }, + { 0, RTE_LINK_MODE_200000baseDR4_Full_BIT, + "200000baseDR4/Full" }, + { 0, RTE_LINK_MODE_200000baseCR4_Full_BIT, + "200000baseCR4/Full" }, + }; + int indent; + int did1; + int new_line_pend; + int fecreported = 0; + + /* Indent just like the separate functions used to */ + indent = strlen(prefix) + 14; + if (indent < 24) + indent = 24; + + fprintf(stdout, " %s link modes:%*s", prefix, + indent - (int)strlen(prefix) - 12, ""); + did1 = 0; + new_line_pend = 0; + for (uint32_t i = 0; i < RTE_DIM(mode_defs); i++) { + if (did1 && !mode_defs[i].same_line) + new_line_pend = 1; + if (get_bit(mask, mode_defs[i].bit_index)) { + if (new_line_pend) { + fprintf(stdout, "\n"); + fprintf(stdout, " %*s", indent, ""); + new_line_pend = 0; + } + did1++; + fprintf(stdout, "%s ", mode_defs[i].name); + } + } + if (did1 == 0) + fprintf(stdout, "Not reported"); + fprintf(stdout, "\n"); + + if (!link_mode_only) { + fprintf(stdout, " %s pause frame use: ", prefix); + if (get_bit(mask, RTE_LINK_MODE_Pause_BIT)) { + fprintf(stdout, "Symmetric"); + if (get_bit(mask, RTE_LINK_MODE_Asym_Pause_BIT)) + fprintf(stdout, " Receive-only"); + fprintf(stdout, "\n"); + } else { + if (get_bit(mask, RTE_LINK_MODE_Asym_Pause_BIT)) + fprintf(stdout, "Transmit-only\n"); + else + fprintf(stdout, "No\n"); + } + + fprintf(stdout, " %s auto-negotiation: ", an_prefix); + if (get_bit(mask, RTE_LINK_MODE_Autoneg_BIT)) + fprintf(stdout, "Yes\n"); + else + fprintf(stdout, "No\n"); + + fprintf(stdout, " %s FEC modes:", prefix); + if (get_bit(mask, RTE_LINK_MODE_FEC_NONE_BIT)) { + fprintf(stdout, " None"); + fecreported = 1; + } + if (get_bit(mask, RTE_LINK_MODE_FEC_BASER_BIT)) { + fprintf(stdout, " BaseR"); + fecreported = 1; + } + if (get_bit(mask, RTE_LINK_MODE_FEC_RS_BIT)) { + fprintf(stdout, " RS"); + fecreported = 1; + } + if (!fecreported) + fprintf(stdout, " Not reported"); + fprintf(stdout, "\n"); + } +} + +static void +dump_supported(const struct rte_link_settings *link_settings) +{ + fprintf(stdout, " Supported ports: [ "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_TP_BIT)) + fprintf(stdout, "TP "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_AUI_BIT)) + fprintf(stdout, "AUI "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_BNC_BIT)) + fprintf(stdout, "BNC "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_MII_BIT)) + fprintf(stdout, "MII "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_FIBRE_BIT)) + fprintf(stdout, "FIBRE "); + if (get_bit(link_settings->link_modes.supported, + RTE_LINK_MODE_Backplane_BIT)) + fprintf(stdout, "Backplane "); + fprintf(stdout, "]\n"); + + dump_link_caps("Supported", "Supports", + link_settings->link_modes.supported, 0); +} + + + +static void +cmd_link_settings_show_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_link_settings_show *res = parsed_result; + static const char *info_border = "*********************"; + struct rte_link_settings link_settings; + int ret; + + memset(&link_settings, 0x00, sizeof(link_settings)); + ret = rte_eth_dev_get_link_settings(res->port_id, &link_settings); + if (ret != 0) { + fprintf(stderr, + "Failed to get current link settings: err = %d\n", + ret); + return; + } + + printf("\n%s Link settings for port %-2d %s\n", + info_border, res->port_id, info_border); + + dump_supported(&link_settings); + dump_link_caps("Advertised", "Advertised", + link_settings.link_modes.advertising, 0); + + bool show_lp_advertising = false; + for (uint32_t idx = 0; idx < RTE_DIM(link_settings.link_modes.lp_advertising); idx++) { + if (link_settings.link_modes.lp_advertising[idx] != 0) { + show_lp_advertising = true; + break; + } + } + + if (show_lp_advertising) { + dump_link_caps("Link partner advertised", + "Link partner advertised", + link_settings.link_modes.lp_advertising, 0); + } + + fprintf(stdout, " Speed: "); + if (link_settings.base.link.link_speed == 0 + || link_settings.base.link.link_speed == (uint16_t)(-1) + || link_settings.base.link.link_speed == (uint32_t)(-1)) + fprintf(stdout, "Unknown!\n"); + else + fprintf(stdout, "%uMb/s\n", link_settings.base.link.link_speed); + + fprintf(stdout, " Duplex: "); + switch (link_settings.base.link.link_duplex) { + case RTE_ETH_LINK_HALF_DUPLEX: + fprintf(stdout, "Half\n"); + break; + case RTE_ETH_LINK_FULL_DUPLEX: + fprintf(stdout, "Full\n"); + break; + default: + fprintf(stdout, "Unknown! (%i)\n", link_settings.base.link.link_duplex); + break; + }; + + fprintf(stdout, " Port: "); + switch (link_settings.base.port) { + case RTE_PORT_TP: + fprintf(stdout, "Twisted Pair\n"); + break; + case RTE_PORT_AUI: + fprintf(stdout, "AUI\n"); + break; + case RTE_PORT_BNC: + fprintf(stdout, "BNC\n"); + break; + case RTE_PORT_MII: + fprintf(stdout, "MII\n"); + break; + case RTE_PORT_FIBRE: + fprintf(stdout, "FIBRE\n"); + break; + case RTE_PORT_DA: + fprintf(stdout, "Direct Attach Copper\n"); + break; + case RTE_PORT_NONE: + fprintf(stdout, "None\n"); + break; + case RTE_PORT_OTHER: + fprintf(stdout, "Other\n"); + break; + default: + fprintf(stdout, "Unknown! (%i)\n", link_settings.base.port); + break; + }; + + fprintf(stdout, " PHYAD: %d\n", link_settings.base.phy_address); + + fprintf(stdout, " Auto-negotiation: %s\n", + (link_settings.base.link.link_autoneg == RTE_AUTONEG_DISABLE) ? + "off" : "on"); + + if (link_settings.base.port == RTE_PORT_TP) { + fprintf(stdout, " MDI-X: "); + if (link_settings.base.eth_tp_mdix_ctrl == RTE_TP_MDI) { + fprintf(stdout, "off (forced)\n"); + } else if (link_settings.base.eth_tp_mdix_ctrl + == RTE_TP_MDI_X) { + fprintf(stdout, "on (forced)\n"); + } else { + switch (link_settings.base.eth_tp_mdix) { + case RTE_TP_MDI: + fprintf(stdout, "off"); + break; + case RTE_TP_MDI_X: + fprintf(stdout, "on"); + break; + default: + fprintf(stdout, "Unknown"); + break; + } + if (link_settings.base.eth_tp_mdix_ctrl + == RTE_TP_MDI_AUTO) + fprintf(stdout, " (auto)"); + fprintf(stdout, "\n"); + } + } +} + +cmdline_parse_inst_t cmd_link_settings_show = { + .f = cmd_link_settings_show_parsed, + .data = NULL, + .help_str = "show port link settings", + .tokens = { + (void *)&cmd_ls_show_show, + (void *)&cmd_ls_show_port, + (void *)&cmd_ls_show_portid, + (void *)&cmd_ls_show_link, + (void *)&cmd_ls_show_settings, + NULL, + }, +}; + +static int parse_hex_u32_bitmap(const char *s, + unsigned int nbits, uint32_t *result) +{ + const unsigned int nwords = RTE_DIV_ROUND_UP(nbits, 32); + size_t slen = strlen(s); + size_t i; + + /* ignore optional '0x' prefix */ + if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) { + slen -= 2; + s += 2; + } + + if (slen > 8 * nwords) /* up to 2 digits per byte */ + return -1; + + memset(result, 0, 4 * nwords); + for (i = 0; i < slen; ++i) { + const unsigned int shift = (slen - 1 - i) * 4; + uint32_t *dest = &result[shift / 32]; + uint32_t nibble; + + if ('a' <= s[i] && s[i] <= 'f') + nibble = 0xa + (s[i] - 'a'); + else if ('A' <= s[i] && s[i] <= 'F') + nibble = 0xa + (s[i] - 'A'); + else if ('0' <= s[i] && s[i] <= '9') + nibble = (s[i] - '0'); + else + return -1; + + *dest |= (nibble << (shift % 32)); + } + + return 0; +} + +/* *** SET ETHERNET LINK SETTINGS *** */ +struct cmd_link_settings_set { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + portid_t port_id; + cmdline_fixed_string_t link; + cmdline_fixed_string_t settings; + cmdline_fixed_string_t advertising; + cmdline_multi_string_t bitmap_str; +}; + +cmdline_parse_token_string_t cmd_ls_set_set = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + set, "set"); +cmdline_parse_token_string_t cmd_ls_set_port = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + port, "port"); +cmdline_parse_token_num_t cmd_ls_set_portid = + TOKEN_NUM_INITIALIZER(struct cmd_link_settings_set, + port_id, RTE_UINT16); +cmdline_parse_token_string_t cmd_ls_set_link = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + link, "link"); +cmdline_parse_token_string_t cmd_ls_set_settings = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + settings, "settings"); +cmdline_parse_token_string_t cmd_ls_set_advertising = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + advertising, "advertising"); +cmdline_parse_token_string_t cmd_ls_set_bitmap_str = + TOKEN_STRING_INITIALIZER(struct cmd_link_settings_set, + bitmap_str, TOKEN_STRING_MULTI); + +static void +cmd_link_settings_set_advertising_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_link_settings_set *res = parsed_result; + struct rte_link_settings link_settings; + int ret; + + if (parse_hex_u32_bitmap(res->bitmap_str, + __RTE_LINK_MODE_MASK_NBITS, + link_settings.link_modes.advertising)) { + fprintf(stderr, "cannot parse bitmap_str\n"); + return; + + } + + link_settings.base.link.link_autoneg = RTE_AUTONEG_ENABLE; + + ret = rte_eth_dev_set_link_settings(res->port_id, &link_settings); + if (ret != 0) { + fprintf(stderr, + "Failed to set link settings: err = %d\n", + ret); + } +} + +cmdline_parse_inst_t cmd_link_settings_set_advertising = { + .f = cmd_link_settings_set_advertising_parsed, + .data = NULL, + .help_str = "set port link settings advertising " + " Bitmap_str - bitmap respresentation of advertising speeds", + .tokens = { + (void *)&cmd_ls_set_set, + (void *)&cmd_ls_set_port, + (void *)&cmd_ls_set_portid, + (void *)&cmd_ls_set_link, + (void *)&cmd_ls_set_settings, + (void *)&cmd_ls_set_advertising, + (void *)&cmd_ls_set_bitmap_str, + NULL, + }, +}; diff --git a/app/test-pmd/cmdline_settings.h b/app/test-pmd/cmdline_settings.h new file mode 100644 index 0000000000..1bcd75f7ef --- /dev/null +++ b/app/test-pmd/cmdline_settings.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2024 Arista Networks, Inc. All rights reserved. + * Arista Networks, Inc. Confidential and Proprietary + */ + +#ifndef _CMDLINE_SETTINGS_H +#define _CMDLINE_SETTINGS_H + +/* Link settings CLI */ +extern cmdline_parse_inst_t cmd_link_settings_show; +extern cmdline_parse_inst_t cmd_link_settings_set_advertising; + +#endif /* _CMDLINE_SETTINGS_H */ + diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index 719f875be0..7aadc2ec42 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -11,6 +11,7 @@ sources = files( 'cmdline_flow.c', 'cmdline_mtr.c', 'cmdline_tm.c', + 'cmdline_settings.c', 'cmd_flex_item.c', 'config.c', 'csumonly.c', diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 0afae7d771..1873b45d23 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -1187,6 +1187,7 @@ void eth_set_allmulticast_mode(uint16_t port, int enable); int eth_link_get_nowait_print_err(uint16_t port_id, struct rte_eth_link *link); int eth_macaddr_get_print_err(uint16_t port_id, struct rte_ether_addr *mac_addr); +int get_bit(const uint32_t *ptr, uint32_t pos); /* Functions to display the set of MAC addresses added to a port*/ void show_macs(portid_t port_id); diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c index bf9b639d95..4d26776cc7 100644 --- a/app/test-pmd/util.c +++ b/app/test-pmd/util.c @@ -17,6 +17,8 @@ #define MAX_STRING_LEN 8192 +#define UINT_32_BIT_WIDTH (CHAR_BIT * sizeof(uint32_t)) + #define MKDUMPSTR(buf, buf_size, cur_len, ...) \ do { \ if (cur_len >= buf_size) \ @@ -525,3 +527,11 @@ eth_macaddr_get_print_err(uint16_t port_id, struct rte_ether_addr *mac_addr) return ret; } + +int +get_bit(const uint32_t *ptr, uint32_t pos) +{ + uint32_t byte_idx = pos / UINT_32_BIT_WIDTH; + uint32_t bit_idx = pos % UINT_32_BIT_WIDTH; + return (ptr[byte_idx] >> bit_idx) & 0x1; +}