From: Maxime Chevallier <maxime.chevallier@bootlin.com>
To: "Björn Töpel" <bjorn@kernel.org>,
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>,
"Naveen Mamindlapalli" <naveenm@marvell.com>,
"Paolo Abeni" <pabeni@redhat.com>,
"Simon Horman" <horms@kernel.org>
Cc: 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: Re: [PATCH net-next v2 02/12] ethtool: Convert per-PHY commands to dump_one_dev
Date: Wed, 25 Mar 2026 19:21:14 +0100 [thread overview]
Message-ID: <b826daeb-e7af-42fc-bb18-0113e84b3891@bootlin.com> (raw)
In-Reply-To: <20260325145022.2607545-3-bjorn@kernel.org>
Hi Björn
On 25/03/2026 15:50, Björn Töpel wrote:
> Convert PSE, PLCA, PHY, and MSE commands from the separate
> ethnl_perphy_{start,dumpit,done} handlers to use the generic
> dump_one_dev callback. This removes the per-PHY specific dump
> infrastructure (ethnl_perphy_dump_ctx, ethnl_perphy_dump_context,
> ethnl_perphy_start, ethnl_perphy_dumpit, ethnl_perphy_done, and the
> internal helpers) in favor of a shared ethnl_perphy_dump_one_dev()
> function.
>
> Signed-off-by: Björn Töpel <bjorn@kernel.org>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
> ---
> net/ethtool/mse.c | 1 +
> net/ethtool/netlink.c | 194 ++++++------------------------------------
> net/ethtool/netlink.h | 4 +
> net/ethtool/phy.c | 1 +
> net/ethtool/plca.c | 2 +
> net/ethtool/pse-pd.c | 1 +
> 6 files changed, 35 insertions(+), 168 deletions(-)
>
> diff --git a/net/ethtool/mse.c b/net/ethtool/mse.c
> index e91b74430f76..3f33182283ce 100644
> --- a/net/ethtool/mse.c
> +++ b/net/ethtool/mse.c
> @@ -325,4 +325,5 @@ const struct ethnl_request_ops ethnl_mse_request_ops = {
> .cleanup_data = mse_cleanup_data,
> .reply_size = mse_reply_size,
> .fill_reply = mse_fill_reply,
> + .dump_one_dev = ethnl_perphy_dump_one_dev,
> };
> diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
> index 8d161f0882d0..edeeca67918a 100644
> --- a/net/ethtool/netlink.c
> +++ b/net/ethtool/netlink.c
> @@ -399,12 +399,6 @@ static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
> return (struct ethnl_dump_ctx *)cb->ctx;
> }
>
> -static struct ethnl_perphy_dump_ctx *
> -ethnl_perphy_dump_context(struct netlink_callback *cb)
> -{
> - return (struct ethnl_perphy_dump_ctx *)cb->ctx;
> -}
> -
> /**
> * ethnl_default_parse() - Parse request message
> * @req_info: pointer to structure to put data into
> @@ -686,169 +680,33 @@ static int ethnl_default_start(struct netlink_callback *cb)
> return ret;
> }
>
> -/* per-PHY ->start() handler for GET requests */
> -static int ethnl_perphy_start(struct netlink_callback *cb)
> +/* Shared dump_one_dev for per-PHY commands (PSE, PLCA, PHY, MSE) */
> +int ethnl_perphy_dump_one_dev(struct sk_buff *skb,
> + struct ethnl_dump_ctx *ctx,
> + unsigned long *pos_sub,
> + const struct genl_info *info)
> {
> - struct ethnl_perphy_dump_ctx *phy_ctx = ethnl_perphy_dump_context(cb);
> - const struct genl_dumpit_info *info = genl_dumpit_info(cb);
> - struct ethnl_dump_ctx *ctx = &phy_ctx->ethnl_ctx;
> - struct ethnl_reply_data *reply_data;
> - const struct ethnl_request_ops *ops;
> - struct ethnl_req_info *req_info;
> - struct genlmsghdr *ghdr;
> - int ret;
> -
> - BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
> -
> - ghdr = nlmsg_data(cb->nlh);
> - ops = ethnl_default_requests[ghdr->cmd];
> - if (WARN_ONCE(!ops, "cmd %u has no ethnl_request_ops\n", ghdr->cmd))
> - return -EOPNOTSUPP;
> - req_info = kzalloc(ops->req_info_size, GFP_KERNEL);
> - if (!req_info)
> - return -ENOMEM;
> - reply_data = kmalloc(ops->reply_data_size, GFP_KERNEL);
> - if (!reply_data) {
> - ret = -ENOMEM;
> - goto free_req_info;
> - }
> -
> - /* Unlike per-dev dump, don't ignore dev. The dump handler
> - * will notice it and dump PHYs from given dev. We only keep track of
> - * the dev's ifindex, .dumpit() will grab and release the netdev itself.
> - */
> - ret = ethnl_default_parse(req_info, &info->info, ops, false);
> - if (ret < 0)
> - goto free_reply_data;
> - if (req_info->dev) {
> - phy_ctx->ifindex = req_info->dev->ifindex;
> - netdev_put(req_info->dev, &req_info->dev_tracker);
> - req_info->dev = NULL;
> - }
> -
> - ctx->ops = ops;
> - ctx->req_info = req_info;
> - ctx->reply_data = reply_data;
> - ctx->pos_ifindex = 0;
> -
> - return 0;
> -
> -free_reply_data:
> - kfree(reply_data);
> -free_req_info:
> - kfree(req_info);
> -
> - return ret;
> -}
> -
> -static int ethnl_perphy_dump_one_dev(struct sk_buff *skb,
> - struct ethnl_perphy_dump_ctx *ctx,
> - const struct genl_info *info)
> -{
> - struct ethnl_dump_ctx *ethnl_ctx = &ctx->ethnl_ctx;
> - struct net_device *dev = ethnl_ctx->req_info->dev;
> + struct net_device *dev = ctx->req_info->dev;
> struct phy_device_node *pdn;
> int ret;
>
> if (!dev->link_topo)
> return 0;
>
> - xa_for_each_start(&dev->link_topo->phys, ctx->pos_phyindex, pdn,
> - ctx->pos_phyindex) {
> - ethnl_ctx->req_info->phy_index = ctx->pos_phyindex;
> + xa_for_each_start(&dev->link_topo->phys, *pos_sub, pdn,
> + *pos_sub) {
> + ctx->req_info->phy_index = *pos_sub;
>
> /* We can re-use the original dump_one as ->prepare_data in
> * commands use ethnl_req_get_phydev(), which gets the PHY from
> * the req_info->phy_index
> */
> - ret = ethnl_default_dump_one(skb, dev, ethnl_ctx, info);
> + ret = ethnl_default_dump_one(skb, dev, ctx, info);
> if (ret)
> return ret;
> }
>
> - ctx->pos_phyindex = 0;
> -
> - return 0;
> -}
> -
> -static int ethnl_perphy_dump_all_dev(struct sk_buff *skb,
> - struct ethnl_perphy_dump_ctx *ctx,
> - const struct genl_info *info)
> -{
> - struct ethnl_dump_ctx *ethnl_ctx = &ctx->ethnl_ctx;
> - struct net *net = sock_net(skb->sk);
> - netdevice_tracker dev_tracker;
> - struct net_device *dev;
> - int ret = 0;
> -
> - rcu_read_lock();
> - for_each_netdev_dump(net, dev, ethnl_ctx->pos_ifindex) {
> - netdev_hold(dev, &dev_tracker, GFP_ATOMIC);
> - rcu_read_unlock();
> -
> - /* per-PHY commands use ethnl_req_get_phydev(), which needs the
> - * net_device in the req_info
> - */
> - ethnl_ctx->req_info->dev = dev;
> - ret = ethnl_perphy_dump_one_dev(skb, ctx, info);
> -
> - rcu_read_lock();
> - netdev_put(dev, &dev_tracker);
> - ethnl_ctx->req_info->dev = NULL;
> -
> - if (ret < 0 && ret != -EOPNOTSUPP) {
> - if (likely(skb->len))
> - ret = skb->len;
> - break;
> - }
> - ret = 0;
> - }
> - rcu_read_unlock();
> -
> - return ret;
> -}
> -
> -/* per-PHY ->dumpit() handler for GET requests. */
> -static int ethnl_perphy_dumpit(struct sk_buff *skb,
> - struct netlink_callback *cb)
> -{
> - struct ethnl_perphy_dump_ctx *ctx = ethnl_perphy_dump_context(cb);
> - const struct genl_dumpit_info *info = genl_dumpit_info(cb);
> - struct ethnl_dump_ctx *ethnl_ctx = &ctx->ethnl_ctx;
> - int ret = 0;
> -
> - if (ctx->ifindex) {
> - netdevice_tracker dev_tracker;
> - struct net_device *dev;
> -
> - dev = netdev_get_by_index(genl_info_net(&info->info),
> - ctx->ifindex, &dev_tracker,
> - GFP_KERNEL);
> - if (!dev)
> - return -ENODEV;
> -
> - ethnl_ctx->req_info->dev = dev;
> - ret = ethnl_perphy_dump_one_dev(skb, ctx, genl_info_dump(cb));
> -
> - if (ret < 0 && ret != -EOPNOTSUPP && likely(skb->len))
> - ret = skb->len;
> -
> - netdev_put(dev, &dev_tracker);
> - } else {
> - ret = ethnl_perphy_dump_all_dev(skb, ctx, genl_info_dump(cb));
> - }
> -
> - return ret;
> -}
> -
> -/* per-PHY ->done() handler for GET requests */
> -static int ethnl_perphy_done(struct netlink_callback *cb)
> -{
> - struct ethnl_perphy_dump_ctx *ctx = ethnl_perphy_dump_context(cb);
> - struct ethnl_dump_ctx *ethnl_ctx = &ctx->ethnl_ctx;
> -
> - kfree(ethnl_ctx->reply_data);
> - kfree(ethnl_ctx->req_info);
> + *pos_sub = 0;
>
> return 0;
> }
> @@ -1410,9 +1268,9 @@ static const struct genl_ops ethtool_genl_ops[] = {
> {
> .cmd = ETHTOOL_MSG_PSE_GET,
> .doit = ethnl_default_doit,
> - .start = ethnl_perphy_start,
> - .dumpit = ethnl_perphy_dumpit,
> - .done = ethnl_perphy_done,
> + .start = ethnl_default_start,
> + .dumpit = ethnl_default_dumpit,
> + .done = ethnl_default_done,
> .policy = ethnl_pse_get_policy,
> .maxattr = ARRAY_SIZE(ethnl_pse_get_policy) - 1,
> },
> @@ -1434,9 +1292,9 @@ static const struct genl_ops ethtool_genl_ops[] = {
> {
> .cmd = ETHTOOL_MSG_PLCA_GET_CFG,
> .doit = ethnl_default_doit,
> - .start = ethnl_perphy_start,
> - .dumpit = ethnl_perphy_dumpit,
> - .done = ethnl_perphy_done,
> + .start = ethnl_default_start,
> + .dumpit = ethnl_default_dumpit,
> + .done = ethnl_default_done,
> .policy = ethnl_plca_get_cfg_policy,
> .maxattr = ARRAY_SIZE(ethnl_plca_get_cfg_policy) - 1,
> },
> @@ -1450,9 +1308,9 @@ static const struct genl_ops ethtool_genl_ops[] = {
> {
> .cmd = ETHTOOL_MSG_PLCA_GET_STATUS,
> .doit = ethnl_default_doit,
> - .start = ethnl_perphy_start,
> - .dumpit = ethnl_perphy_dumpit,
> - .done = ethnl_perphy_done,
> + .start = ethnl_default_start,
> + .dumpit = ethnl_default_dumpit,
> + .done = ethnl_default_done,
> .policy = ethnl_plca_get_status_policy,
> .maxattr = ARRAY_SIZE(ethnl_plca_get_status_policy) - 1,
> },
> @@ -1482,9 +1340,9 @@ static const struct genl_ops ethtool_genl_ops[] = {
> {
> .cmd = ETHTOOL_MSG_PHY_GET,
> .doit = ethnl_default_doit,
> - .start = ethnl_perphy_start,
> - .dumpit = ethnl_perphy_dumpit,
> - .done = ethnl_perphy_done,
> + .start = ethnl_default_start,
> + .dumpit = ethnl_default_dumpit,
> + .done = ethnl_default_done,
> .policy = ethnl_phy_get_policy,
> .maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
> },
> @@ -1528,9 +1386,9 @@ static const struct genl_ops ethtool_genl_ops[] = {
> {
> .cmd = ETHTOOL_MSG_MSE_GET,
> .doit = ethnl_default_doit,
> - .start = ethnl_perphy_start,
> - .dumpit = ethnl_perphy_dumpit,
> - .done = ethnl_perphy_done,
> + .start = ethnl_default_start,
> + .dumpit = ethnl_default_dumpit,
> + .done = ethnl_default_done,
> .policy = ethnl_mse_get_policy,
> .maxattr = ARRAY_SIZE(ethnl_mse_get_policy) - 1,
> },
> diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
> index e01adc5db02f..dda2f5593ed9 100644
> --- a/net/ethtool/netlink.h
> +++ b/net/ethtool/netlink.h
> @@ -546,6 +546,10 @@ int ethnl_tsinfo_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
> int ethnl_tsinfo_done(struct netlink_callback *cb);
> int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info);
> int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info);
> +int ethnl_perphy_dump_one_dev(struct sk_buff *skb,
> + struct ethnl_dump_ctx *ctx,
> + unsigned long *pos_sub,
> + const struct genl_info *info);
>
> extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
> extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
> diff --git a/net/ethtool/phy.c b/net/ethtool/phy.c
> index d4e6887055ab..4bb23a5d6ad5 100644
> --- a/net/ethtool/phy.c
> +++ b/net/ethtool/phy.c
> @@ -162,4 +162,5 @@ const struct ethnl_request_ops ethnl_phy_request_ops = {
> .reply_size = phy_reply_size,
> .fill_reply = phy_fill_reply,
> .cleanup_data = phy_cleanup_data,
> + .dump_one_dev = ethnl_perphy_dump_one_dev,
> };
> diff --git a/net/ethtool/plca.c b/net/ethtool/plca.c
> index 91f0c4233298..84e902532617 100644
> --- a/net/ethtool/plca.c
> +++ b/net/ethtool/plca.c
> @@ -188,6 +188,7 @@ const struct ethnl_request_ops ethnl_plca_cfg_request_ops = {
> .prepare_data = plca_get_cfg_prepare_data,
> .reply_size = plca_get_cfg_reply_size,
> .fill_reply = plca_get_cfg_fill_reply,
> + .dump_one_dev = ethnl_perphy_dump_one_dev,
>
> .set = ethnl_set_plca,
> .set_ntf_cmd = ETHTOOL_MSG_PLCA_NTF,
> @@ -268,4 +269,5 @@ const struct ethnl_request_ops ethnl_plca_status_request_ops = {
> .prepare_data = plca_get_status_prepare_data,
> .reply_size = plca_get_status_reply_size,
> .fill_reply = plca_get_status_fill_reply,
> + .dump_one_dev = ethnl_perphy_dump_one_dev,
> };
> diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
> index 2eb9bdc2dcb9..83f0205053a3 100644
> --- a/net/ethtool/pse-pd.c
> +++ b/net/ethtool/pse-pd.c
> @@ -338,6 +338,7 @@ const struct ethnl_request_ops ethnl_pse_request_ops = {
> .reply_size = pse_reply_size,
> .fill_reply = pse_fill_reply,
> .cleanup_data = pse_cleanup_data,
> + .dump_one_dev = ethnl_perphy_dump_one_dev,
>
> .set = ethnl_set_pse,
> /* PSE has no notification */
next prev parent reply other threads:[~2026-03-25 18:21 UTC|newest]
Thread overview: 21+ 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 [this message]
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-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 ` [PATCH net-next v2 07/12] ethtool: Add MAC loopback support via ethtool_ops Björn Töpel
2026-03-26 9:49 ` 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=b826daeb-e7af-42fc-bb18-0113e84b3891@bootlin.com \
--to=maxime.chevallier@bootlin.com \
--cc=andrew+netdev@lunn.ch \
--cc=bjorn@kernel.org \
--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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox