From patchwork Thu Feb 29 12:34:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 137487 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 E60A843C36; Thu, 29 Feb 2024 13:37:22 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AD671410E3; Thu, 29 Feb 2024 13:37:22 +0100 (CET) Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) by mails.dpdk.org (Postfix) with ESMTP id D7B47402AE for ; Thu, 29 Feb 2024 13:37:17 +0100 (CET) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id CFFE832002E2; Thu, 29 Feb 2024 07:37:13 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 29 Feb 2024 07:37:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monjalon.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to; s=fm1; t=1709210233; x=1709296633; bh=lbYE0GCQqotrttjzY7kGC /8L2+1nYMGeQ3n4avWjbiI=; b=A3Lu9B2Yy33lSIB1HPWb7DNZH2IgP+Y2bxql1 j2rIEtt7BLMfMFE7LzMaAYzgtlAi+2eI5nWstGrRL3TZyNedZcRBX0eV3KRnldG/ vEebZKEIgGS+pojLJJXnWdP6HDU3kglwpYoTjlz5mA5FD3yTm1nYT4/ts7FtfBVL uOLRhUT33QoMfR28s+Bt4tJ77jYyjwmbE3na5qQwvv8VatIFT+YkglmXbzCp6pQd T3PSg0JVYKdUQEl1DXkaHKJ+4CwTJ9feJTco7ZR4WxQhldY4eS8oAVskYPzolmHv F55WcHUH+KDhCRGkRB8YfoZpxhGyYJx7V6UuKiDp2sZHfuGEA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1709210233; x=1709296633; bh=lbYE0GCQqotrttjzY7kGC/8L2+1n YMGeQ3n4avWjbiI=; b=CJEt9EFJ1ygjv4G393OxpLxagUiVJTxZ7etZtteDICvF cJHad8vnK7dTVhj5UY10/l9A2128l00vvx2L6v4myslzwkDBJRK9uKjqgEEbyBFq UuzVnnZK5YoK0ndzove34+snwP2e0kLtndzakhU5FVMUN2uHQaK7Nf0IvamkR7ZM MSEil51RwPPrWVovvDQVNaGG3rSfstuBRJ4Xf3ag4O0iiWc+Dqj7GRrNEL4zcyml mp1zGr4rWpR+uxUcWKZ521rnG3X8YBcfzaCy/CNlaFJg+u9PO2ukNxY3aO0qh7Nm 4do2h5Yf998ENHFtXKxy2cmujKCs86l92dHCL6vuHQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrgeelgdegvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvfevufffkffoggfgsedtkeertdertddtnecuhfhrohhmpefvhhhomhgrshcu ofhonhhjrghlohhnuceothhhohhmrghssehmohhnjhgrlhhonhdrnhgvtheqnecuggftrf grthhtvghrnhepveevfeevieeihfetudekgeekleeigeffueekveduteeuffeiudevteei udekfeelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomh epthhhohhmrghssehmohhnjhgrlhhonhdrnhgvth X-ME-Proxy: Feedback-ID: i47234305:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 29 Feb 2024 07:37:12 -0500 (EST) From: Thomas Monjalon To: dev@dpdk.org Cc: Ferruh Yigit , Andrew Rybchenko Subject: [PATCH v1] ethdev: add Linux ethtool link mode conversion Date: Thu, 29 Feb 2024 13:34:27 +0100 Message-ID: <20240229123653.1379466-1-thomas@monjalon.net> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 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 Speed capabilities of a NIC may be discovered through its Linux kernel driver. It is especially useful for bifurcated drivers, so they don't have to duplicate the same logic in the DPDK driver. Parsing ethtool speed capabilities is made easy thanks to the functions added in ethdev for internal usage only. Of course these functions work only on Linux, so they are not compiled in other environments. In order to ease parsing, the ethtool macro names are parsed externally in a shell command which generates a C array included in this patch. It also avoids to depend on a kernel version. This C array should be updated in future to get latest ethtool bits. Note it is easier to update this array than adding new cases in a parsing code. The types in the functions are following the ethtool type: uint32_t for bitmaps, and int8_t for the number of 32-bitmaps. Signed-off-by: Thomas Monjalon --- A follow-up patch will be sent to use these functions in mlx5. I suspect mana could use this parsing as well. --- lib/ethdev/ethdev_linux_ethtool.c | 162 ++++++++++++++++++++++++++++++ lib/ethdev/ethdev_linux_ethtool.h | 41 ++++++++ lib/ethdev/meson.build | 9 ++ lib/ethdev/version.map | 3 + 4 files changed, 215 insertions(+) create mode 100644 lib/ethdev/ethdev_linux_ethtool.c create mode 100644 lib/ethdev/ethdev_linux_ethtool.h diff --git a/lib/ethdev/ethdev_linux_ethtool.c b/lib/ethdev/ethdev_linux_ethtool.c new file mode 100644 index 0000000000..fe98882b8a --- /dev/null +++ b/lib/ethdev/ethdev_linux_ethtool.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2024 NVIDIA Corporation & Affiliates + */ + +#include + +#include "rte_ethdev.h" +#include "ethdev_linux_ethtool.h" + +/* +Link modes sorted with index as defined in ethtool. +Values are speed in Mbps with LSB indicating duplex. + +The ethtool bits definition should not change as it is a kernel API. +Using raw numbers directly avoids checking API availability +and allows to compile with new bits included even on an old kernel. + +The array below is built from bit definitions with this shell command: + sed -rn 's;.*(ETHTOOL_LINK_MODE_)([0-9]+)([0-9a-zA-Z_]*).*= *([0-9]*).*;'\ + '[\4] = \2, /\* \1\2\3 *\/;p' /usr/include/linux/ethtool.h | + awk '/_Half_/{$3=$3+1","}1' +*/ +static uint32_t link_modes[] = { + [ 0] = 11, /* ETHTOOL_LINK_MODE_10baseT_Half_BIT */ + [ 1] = 10, /* ETHTOOL_LINK_MODE_10baseT_Full_BIT */ + [ 2] = 101, /* ETHTOOL_LINK_MODE_100baseT_Half_BIT */ + [ 3] = 100, /* ETHTOOL_LINK_MODE_100baseT_Full_BIT */ + [ 4] = 1001, /* ETHTOOL_LINK_MODE_1000baseT_Half_BIT */ + [ 5] = 1000, /* ETHTOOL_LINK_MODE_1000baseT_Full_BIT */ + [ 12] = 10000, /* ETHTOOL_LINK_MODE_10000baseT_Full_BIT */ + [ 15] = 2500, /* ETHTOOL_LINK_MODE_2500baseX_Full_BIT */ + [ 17] = 1000, /* ETHTOOL_LINK_MODE_1000baseKX_Full_BIT */ + [ 18] = 10000, /* ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT */ + [ 19] = 10000, /* ETHTOOL_LINK_MODE_10000baseKR_Full_BIT */ + [ 20] = 10000, /* ETHTOOL_LINK_MODE_10000baseR_FEC_BIT */ + [ 21] = 20000, /* ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT */ + [ 22] = 20000, /* ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT */ + [ 23] = 40000, /* ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT */ + [ 24] = 40000, /* ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT */ + [ 25] = 40000, /* ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT */ + [ 26] = 40000, /* ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT */ + [ 27] = 56000, /* ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT */ + [ 28] = 56000, /* ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT */ + [ 29] = 56000, /* ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT */ + [ 30] = 56000, /* ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT */ + [ 31] = 25000, /* ETHTOOL_LINK_MODE_25000baseCR_Full_BIT */ + [ 32] = 25000, /* ETHTOOL_LINK_MODE_25000baseKR_Full_BIT */ + [ 33] = 25000, /* ETHTOOL_LINK_MODE_25000baseSR_Full_BIT */ + [ 34] = 50000, /* ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT */ + [ 35] = 50000, /* ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT */ + [ 36] = 100000, /* ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT */ + [ 37] = 100000, /* ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT */ + [ 38] = 100000, /* ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT */ + [ 39] = 100000, /* ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT */ + [ 40] = 50000, /* ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT */ + [ 41] = 1000, /* ETHTOOL_LINK_MODE_1000baseX_Full_BIT */ + [ 42] = 10000, /* ETHTOOL_LINK_MODE_10000baseCR_Full_BIT */ + [ 43] = 10000, /* ETHTOOL_LINK_MODE_10000baseSR_Full_BIT */ + [ 44] = 10000, /* ETHTOOL_LINK_MODE_10000baseLR_Full_BIT */ + [ 45] = 10000, /* ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT */ + [ 46] = 10000, /* ETHTOOL_LINK_MODE_10000baseER_Full_BIT */ + [ 47] = 2500, /* ETHTOOL_LINK_MODE_2500baseT_Full_BIT */ + [ 48] = 5000, /* ETHTOOL_LINK_MODE_5000baseT_Full_BIT */ + [ 52] = 50000, /* ETHTOOL_LINK_MODE_50000baseKR_Full_BIT */ + [ 53] = 50000, /* ETHTOOL_LINK_MODE_50000baseSR_Full_BIT */ + [ 54] = 50000, /* ETHTOOL_LINK_MODE_50000baseCR_Full_BIT */ + [ 55] = 50000, /* ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT */ + [ 56] = 50000, /* ETHTOOL_LINK_MODE_50000baseDR_Full_BIT */ + [ 57] = 100000, /* ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT */ + [ 58] = 100000, /* ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT */ + [ 59] = 100000, /* ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT */ + [ 60] = 100000, /* ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT */ + [ 61] = 100000, /* ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT */ + [ 62] = 200000, /* ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT */ + [ 63] = 200000, /* ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT */ + [ 64] = 200000, /* ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT */ + [ 65] = 200000, /* ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT */ + [ 66] = 200000, /* ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT */ + [ 67] = 100, /* ETHTOOL_LINK_MODE_100baseT1_Full_BIT */ + [ 68] = 1000, /* ETHTOOL_LINK_MODE_1000baseT1_Full_BIT */ + [ 69] = 400000, /* ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT */ + [ 70] = 400000, /* ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT */ + [ 71] = 400000, /* ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT */ + [ 72] = 400000, /* ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT */ + [ 73] = 400000, /* ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT */ + [ 75] = 100000, /* ETHTOOL_LINK_MODE_100000baseKR_Full_BIT */ + [ 76] = 100000, /* ETHTOOL_LINK_MODE_100000baseSR_Full_BIT */ + [ 77] = 100000, /* ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT */ + [ 78] = 100000, /* ETHTOOL_LINK_MODE_100000baseCR_Full_BIT */ + [ 79] = 100000, /* ETHTOOL_LINK_MODE_100000baseDR_Full_BIT */ + [ 80] = 200000, /* ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT */ + [ 81] = 200000, /* ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT */ + [ 82] = 200000, /* ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT */ + [ 83] = 200000, /* ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT */ + [ 84] = 200000, /* ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT */ + [ 85] = 400000, /* ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT */ + [ 86] = 400000, /* ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT */ + [ 87] = 400000, /* ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT */ + [ 88] = 400000, /* ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT */ + [ 89] = 400000, /* ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT */ + [ 90] = 101, /* ETHTOOL_LINK_MODE_100baseFX_Half_BIT */ + [ 91] = 100, /* ETHTOOL_LINK_MODE_100baseFX_Full_BIT */ + [ 92] = 10, /* ETHTOOL_LINK_MODE_10baseT1L_Full_BIT */ + [ 93] = 800000, /* ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT */ + [ 94] = 800000, /* ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT */ + [ 95] = 800000, /* ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT */ + [ 96] = 800000, /* ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT */ + [ 97] = 800000, /* ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT */ + [ 98] = 800000, /* ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT */ + [ 99] = 10, /* ETHTOOL_LINK_MODE_10baseT1S_Full_BIT */ + [100] = 11, /* ETHTOOL_LINK_MODE_10baseT1S_Half_BIT */ + [101] = 11, /* ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT */ +}; + +uint32_t +rte_eth_link_speed_ethtool(enum ethtool_link_mode_bit_indices bit) +{ + uint32_t speed; + int duplex; + + /* get mode from array */ + if (bit >= RTE_DIM(link_modes)) + return RTE_ETH_LINK_SPEED_AUTONEG; + speed = link_modes[bit]; + if (speed == 0) + return RTE_ETH_LINK_SPEED_AUTONEG; + RTE_BUILD_BUG_ON(RTE_ETH_LINK_SPEED_AUTONEG != 0); + + /* duplex is LSB */ + duplex = (speed & 1)? + RTE_ETH_LINK_HALF_DUPLEX: + RTE_ETH_LINK_FULL_DUPLEX; + speed &= RTE_GENMASK32(31, 1); + + return rte_eth_speed_bitflag(speed, duplex); +} + +uint32_t +rte_eth_link_speed_glink(const uint32_t *bitmap, int8_t nwords) +{ + uint8_t word, bit; + uint32_t ethdev_bitmap = 0; + + if (nwords < 1) + return 0; + + for (word = 0; word < nwords; word ++) { + for (bit = 0; bit < 32; bit ++) { + if ((bitmap[word] & RTE_BIT32(bit)) == 0) + continue; + ethdev_bitmap |= rte_eth_link_speed_ethtool(word * 32 + bit); + } + } + + return ethdev_bitmap; +} + +uint32_t +rte_eth_link_speed_gset(uint32_t legacy_bitmap) +{ + return rte_eth_link_speed_glink(&legacy_bitmap, 1); +} diff --git a/lib/ethdev/ethdev_linux_ethtool.h b/lib/ethdev/ethdev_linux_ethtool.h new file mode 100644 index 0000000000..de235bd5f4 --- /dev/null +++ b/lib/ethdev/ethdev_linux_ethtool.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2024 NVIDIA Corporation & Affiliates + */ + +#ifndef ETHDEV_ETHTOOL_H +#define ETHDEV_ETHTOOL_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Convert bit from ETHTOOL_LINK_MODE_* to RTE_ETH_LINK_SPEED_* + */ +__rte_internal +uint32_t rte_eth_link_speed_ethtool(enum ethtool_link_mode_bit_indices bit); + +/* + * Convert bitmap from ETHTOOL_GLINKSETTINGS ethtool_link_settings::link_mode_masks + * to bitmap RTE_ETH_LINK_SPEED_* + */ +__rte_internal +uint32_t rte_eth_link_speed_glink(const uint32_t *bitmap, int8_t nwords); + +/* + * Convert bitmap from deprecated ETHTOOL_GSET ethtool_cmd::supported + * to bitmap RTE_ETH_LINK_SPEED_* + */ +__rte_internal +uint32_t rte_eth_link_speed_gset(uint32_t legacy_bitmap); + +#ifdef __cplusplus +} +#endif + +#endif /* ETHDEV_ETHTOOL_H */ diff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build index d11f06bc88..f1d2586591 100644 --- a/lib/ethdev/meson.build +++ b/lib/ethdev/meson.build @@ -44,6 +44,15 @@ driver_sdk_headers += files( 'ethdev_vdev.h', ) +if is_linux + driver_sdk_headers += files( + 'ethdev_linux_ethtool.h', + ) + sources += files( + 'ethdev_linux_ethtool.c', + ) +endif + deps += ['net', 'kvargs', 'meter', 'telemetry'] if is_freebsd diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index 17e4eac8a4..9a51f3a562 100644 --- a/lib/ethdev/version.map +++ b/lib/ethdev/version.map @@ -350,6 +350,9 @@ INTERNAL { rte_eth_hairpin_queue_peer_unbind; rte_eth_hairpin_queue_peer_update; rte_eth_ip_reassembly_dynfield_register; + rte_eth_link_speed_ethtool; + rte_eth_link_speed_glink; + rte_eth_link_speed_gset; rte_eth_pkt_burst_dummy; rte_eth_representor_id_get; rte_eth_switch_domain_alloc;