From: "Björn Töpel" <bjorn@kernel.org>
To: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Donald Hunter <donald.hunter@gmail.com>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Maxime Chevallier <maxime.chevallier@bootlin.com>,
Naveen Mamindlapalli <naveenm@marvell.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>
Cc: "Björn Töpel" <bjorn@kernel.org>,
"Danielle Ratson" <danieller@nvidia.com>,
"Hariprasad Kelam" <hkelam@marvell.com>,
"Ido Schimmel" <idosch@nvidia.com>,
"Kory Maincent" <kory.maincent@bootlin.com>,
"Leon Romanovsky" <leon@kernel.org>,
"Michael Chan" <michael.chan@broadcom.com>,
"Oleksij Rempel" <o.rempel@pengutronix.de>,
"Pavan Chebbi" <pavan.chebbi@broadcom.com>,
"Piergiorgio Beruto" <piergiorgio.beruto@gmail.com>,
"Russell King" <linux@armlinux.org.uk>,
"Saeed Mahameed" <saeedm@nvidia.com>,
"Shuah Khan" <shuah@kernel.org>,
"Tariq Toukan" <tariqt@nvidia.com>,
"Willem de Bruijn" <willemb@google.com>,
"Kees Cook" <kees@kernel.org>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-rdma@vger.kernel.org
Subject: [PATCH net-next v2 07/12] ethtool: Add MAC loopback support via ethtool_ops
Date: Wed, 25 Mar 2026 15:50:14 +0100 [thread overview]
Message-ID: <20260325145022.2607545-8-bjorn@kernel.org> (raw)
In-Reply-To: <20260325145022.2607545-1-bjorn@kernel.org>
Extend struct ethtool_ops with three loopback callbacks that drivers
can implement for MAC-level loopback control:
- get_loopback(dev, name, id, entry): exact lookup by name and
instance id, used by doit (single-entry GET) requests.
- get_loopback_by_index(dev, index, entry): flat enumeration by
index, used by dumpit (multi-entry GET) requests to iterate all
loopback points on a device.
- set_loopback(dev, entry, extack): apply a loopback configuration
change. Returns 1 if hardware state changed, 0 if no-op.
Wire the MAC component into loopback.c's dispatch functions. For dump
enumeration, MAC entries are tried first via the driver's
get_loopback_by_index() op, then MODULE/CMIS entries follow at the
next index offset.
Signed-off-by: Björn Töpel <bjorn@kernel.org>
---
include/linux/ethtool.h | 10 ++++++++
net/ethtool/loopback.c | 56 ++++++++++++++++++++++++++++++++---------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 81a9c186564d..971be759a915 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1168,6 +1168,9 @@ struct kernel_ethtool_ts_info {
* @get_mm: Query the 802.3 MAC Merge layer state.
* @set_mm: Set the 802.3 MAC Merge layer parameters.
* @get_mm_stats: Query the 802.3 MAC Merge layer statistics.
+ * @get_loopback: Get the state of a loopback entry identified by name and id.
+ * @get_loopback_by_index: Get the state of a loopback entry by its index.
+ * @set_loopback: Set the loopback mode for a given entry.
*
* All operations are optional (i.e. the function pointer may be set
* to %NULL) and callers must take this into account. Callers must
@@ -1337,6 +1340,13 @@ struct ethtool_ops {
int (*set_mm)(struct net_device *dev, struct ethtool_mm_cfg *cfg,
struct netlink_ext_ack *extack);
void (*get_mm_stats)(struct net_device *dev, struct ethtool_mm_stats *stats);
+ int (*get_loopback)(struct net_device *dev, const char *name,
+ u32 id, struct ethtool_loopback_entry *entry);
+ int (*get_loopback_by_index)(struct net_device *dev, u32 index,
+ struct ethtool_loopback_entry *entry);
+ int (*set_loopback)(struct net_device *dev,
+ const struct ethtool_loopback_entry *entry,
+ struct netlink_ext_ack *extack);
};
int ethtool_check_ops(const struct ethtool_ops *ops);
diff --git a/net/ethtool/loopback.c b/net/ethtool/loopback.c
index 2d0ad62ce42f..60eb7b94a716 100644
--- a/net/ethtool/loopback.c
+++ b/net/ethtool/loopback.c
@@ -88,6 +88,10 @@ static int loopback_get(struct net_device *dev,
struct ethtool_loopback_entry *entry)
{
switch (component) {
+ case ETHTOOL_LOOPBACK_COMPONENT_MAC:
+ if (!dev->ethtool_ops->get_loopback)
+ return -EOPNOTSUPP;
+ return dev->ethtool_ops->get_loopback(dev, name, id, entry);
case ETHTOOL_LOOPBACK_COMPONENT_MODULE:
return ethtool_cmis_get_loopback(dev, name, entry);
default:
@@ -95,10 +99,22 @@ static int loopback_get(struct net_device *dev,
}
}
-static int loopback_get_by_index(struct net_device *dev, u32 index,
+static int loopback_get_by_index(struct net_device *dev,
+ enum ethtool_loopback_component component,
+ u32 index,
struct ethtool_loopback_entry *entry)
{
- return ethtool_cmis_get_loopback_by_index(dev, index, entry);
+ switch (component) {
+ case ETHTOOL_LOOPBACK_COMPONENT_MAC:
+ if (!dev->ethtool_ops->get_loopback_by_index)
+ return -EOPNOTSUPP;
+ return dev->ethtool_ops->get_loopback_by_index(dev, index,
+ entry);
+ case ETHTOOL_LOOPBACK_COMPONENT_MODULE:
+ return ethtool_cmis_get_loopback_by_index(dev, index, entry);
+ default:
+ return -EOPNOTSUPP;
+ }
}
static int loopback_prepare_data(const struct ethnl_req_info *req_base,
@@ -118,7 +134,8 @@ static int loopback_prepare_data(const struct ethnl_req_info *req_base,
ret = loopback_get(dev, req_info->component, req_info->id,
req_info->name, &data->entry);
else
- ret = loopback_get_by_index(dev, req_info->index, &data->entry);
+ ret = loopback_get_by_index(dev, req_info->component,
+ req_info->index, &data->entry);
ethnl_ops_complete(dev);
@@ -235,6 +252,10 @@ static int __loopback_set(struct net_device *dev,
struct netlink_ext_ack *extack)
{
switch (entry->component) {
+ case ETHTOOL_LOOPBACK_COMPONENT_MAC:
+ if (!dev->ethtool_ops->set_loopback)
+ return -EOPNOTSUPP;
+ return dev->ethtool_ops->set_loopback(dev, entry, extack);
case ETHTOOL_LOOPBACK_COMPONENT_MODULE:
return ethtool_cmis_set_loopback(dev, entry, extack);
default:
@@ -284,20 +305,31 @@ static int loopback_dump_one_dev(struct sk_buff *skb,
{
struct loopback_req_info *req_info =
container_of(ctx->req_info, struct loopback_req_info, base);
+ /* pos_sub encodes: upper 16 bits = component phase, lower 16 = index
+ * within that component. dump_one_dev is called repeatedly with
+ * increasing pos_sub until all components are exhausted.
+ */
+ enum ethtool_loopback_component phase = *pos_sub >> 16;
+ u32 idx = *pos_sub & 0xffff;
int ret;
- for (;; (*pos_sub)++) {
- req_info->index = *pos_sub;
- ret = ethnl_default_dump_one(skb, ctx->req_info->dev, ctx,
- info);
- if (ret == -EOPNOTSUPP)
- break;
- if (ret)
- return ret;
+ for (; phase <= ETHTOOL_LOOPBACK_COMPONENT_MODULE; phase++) {
+ for (;; idx++) {
+ req_info->component = phase;
+ req_info->index = idx;
+ ret = ethnl_default_dump_one(skb, ctx->req_info->dev,
+ ctx, info);
+ if (ret == -EOPNOTSUPP)
+ break;
+ if (ret) {
+ *pos_sub = ((unsigned long)phase << 16) | idx;
+ return ret;
+ }
+ }
+ idx = 0;
}
*pos_sub = 0;
-
return 0;
}
--
2.53.0
next prev parent reply other threads:[~2026-03-25 14:51 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-25 14:50 [PATCH net-next v2 00/12] ethtool: Generic loopback support Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 01/12] ethtool: Add dump_one_dev callback for per-device sub-iteration Björn Töpel
2026-03-25 18:20 ` Maxime Chevallier
2026-03-25 14:50 ` [PATCH net-next v2 02/12] ethtool: Convert per-PHY commands to dump_one_dev Björn Töpel
2026-03-25 18:21 ` Maxime Chevallier
2026-03-25 14:50 ` [PATCH net-next v2 03/12] ethtool: Add loopback netlink UAPI definitions Björn Töpel
2026-03-26 8:10 ` Maxime Chevallier
2026-03-26 8:55 ` Björn Töpel
2026-03-26 22:22 ` Jakub Kicinski
2026-03-26 22:23 ` Jakub Kicinski
2026-03-27 8:57 ` Maxime Chevallier
2026-03-25 14:50 ` [PATCH net-next v2 04/12] ethtool: Add loopback GET/SET netlink implementation Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 05/12] ethtool: Add CMIS loopback helpers for module loopback control Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 06/12] selftests: drv-net: Add loopback driver test Björn Töpel
2026-03-25 14:50 ` Björn Töpel [this message]
2026-03-26 9:49 ` [PATCH net-next v2 07/12] ethtool: Add MAC loopback support via ethtool_ops Breno Leitao
2026-03-25 14:50 ` [PATCH net-next v2 08/12] netdevsim: Add MAC loopback simulation Björn Töpel
2026-03-26 9:40 ` Breno Leitao
2026-03-25 14:50 ` [PATCH net-next v2 09/12] selftests: drv-net: Add MAC loopback netdevsim test Björn Töpel
2026-03-26 9:32 ` Breno Leitao
2026-03-26 9:44 ` Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 10/12] MAINTAINERS: Add entry for ethtool loopback Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 11/12] netdevsim: Add module EEPROM simulation via debugfs Björn Töpel
2026-03-25 14:50 ` [PATCH net-next v2 12/12] selftests: drv-net: Add CMIS loopback netdevsim test Björn Töpel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260325145022.2607545-8-bjorn@kernel.org \
--to=bjorn@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=danieller@nvidia.com \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=hkelam@marvell.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kees@kernel.org \
--cc=kory.maincent@bootlin.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=maxime.chevallier@bootlin.com \
--cc=michael.chan@broadcom.com \
--cc=naveenm@marvell.com \
--cc=netdev@vger.kernel.org \
--cc=o.rempel@pengutronix.de \
--cc=pabeni@redhat.com \
--cc=pavan.chebbi@broadcom.com \
--cc=piergiorgio.beruto@gmail.com \
--cc=saeedm@nvidia.com \
--cc=shuah@kernel.org \
--cc=tariqt@nvidia.com \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.