Message ID | 20250308155440.267782-5-maxime.chevallier@bootlin.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | net: ethtool: Introduce ethnl dump helpers | expand |
On Sat, 8 Mar 2025 16:54:36 +0100 Maxime Chevallier <maxime.chevallier@bootlin.com> wrote: > As there are multiple ethnl commands that report messages based on > phy_device information, let's introduce a set of ethnl generic dump > helpers to allow DUMP support for each PHY on a given netdev. > > This logic iterates over the phy_link_topology of each netdev (or a > single netdev for filtered DUMP), and call ethnl_default_dump_one() with > the req_info populated with ifindex + phyindex. > > This allows re-using all the existing infra for phy-targetting commands > that already use ethnl generic helpers. > > Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> > --- > V2: Rebase > > net/ethtool/netlink.c | 53 +++++++++++++++++++++++++++++++++++++++++++ > net/ethtool/netlink.h | 6 +++++ > 2 files changed, 59 insertions(+) > > diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c > index ae06b72239a8..a09bcd67b38f 100644 > --- a/net/ethtool/netlink.c > +++ b/net/ethtool/netlink.c > @@ -559,6 +559,59 @@ static int ethnl_default_dump_one(struct sk_buff *skb, > return ret; > } > > +/* Specific context for phy-targeting command DUMP operatins. We keep in > context > + * the latest phy_index we dumped, in case of an interrupted DUMP. > + */ > +struct ethnl_dump_ctx_perphy { > + unsigned long phy_index; > +}; > + > +int ethnl_dump_start_perphy(struct ethnl_dump_ctx *ctx) Could you add comments or event better, kdoc for non static function to explain their purpose. > +{ > + struct ethnl_dump_ctx_perphy *dump_ctx; > + > + dump_ctx = kzalloc(sizeof(*dump_ctx), GFP_KERNEL); > + if (!dump_ctx) > + return -ENOMEM; > + > + ctx->cmd_ctx = dump_ctx; > + > + return 0; > +} > + > +void ethnl_dump_done_perphy(struct ethnl_dump_ctx *ctx) same. > +{ > + kfree(ctx->cmd_ctx); > +} > + > +int ethnl_dump_one_dev_perphy(struct sk_buff *skb, > + struct ethnl_dump_ctx *ctx, > + const struct genl_info *info) same. > +{ > + struct ethnl_dump_ctx_perphy *dump_ctx = ctx->cmd_ctx; > + struct net_device *dev = ctx->reply_data->dev; > + struct phy_device_node *pdn; > + int ret = 0; > + > + if (!dev->link_topo) > + return 0; > + > + xa_for_each_start(&dev->link_topo->phys, dump_ctx->phy_index, > + pdn, dump_ctx->phy_index) { > + ctx->req_info->phy_index = dump_ctx->phy_index; > + > + /* We can re-use the original dump_one as ->prepare_data in > + * commands use ethnl_req_get_phydev(), which gets the PHY > from > + * what's in req_info > + */ > + ret = ethnl_default_dump_one(skb, ctx, info); > + if (ret) > + break; > + } > + > + return ret; > +} Regards, --- Köry Maincent, Bootlin Embedded Linux and kernel engineering https://bootlin.com
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index ae06b72239a8..a09bcd67b38f 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -559,6 +559,59 @@ static int ethnl_default_dump_one(struct sk_buff *skb, return ret; } +/* Specific context for phy-targeting command DUMP operatins. We keep in context + * the latest phy_index we dumped, in case of an interrupted DUMP. + */ +struct ethnl_dump_ctx_perphy { + unsigned long phy_index; +}; + +int ethnl_dump_start_perphy(struct ethnl_dump_ctx *ctx) +{ + struct ethnl_dump_ctx_perphy *dump_ctx; + + dump_ctx = kzalloc(sizeof(*dump_ctx), GFP_KERNEL); + if (!dump_ctx) + return -ENOMEM; + + ctx->cmd_ctx = dump_ctx; + + return 0; +} + +void ethnl_dump_done_perphy(struct ethnl_dump_ctx *ctx) +{ + kfree(ctx->cmd_ctx); +} + +int ethnl_dump_one_dev_perphy(struct sk_buff *skb, + struct ethnl_dump_ctx *ctx, + const struct genl_info *info) +{ + struct ethnl_dump_ctx_perphy *dump_ctx = ctx->cmd_ctx; + struct net_device *dev = ctx->reply_data->dev; + struct phy_device_node *pdn; + int ret = 0; + + if (!dev->link_topo) + return 0; + + xa_for_each_start(&dev->link_topo->phys, dump_ctx->phy_index, + pdn, dump_ctx->phy_index) { + ctx->req_info->phy_index = dump_ctx->phy_index; + + /* We can re-use the original dump_one as ->prepare_data in + * commands use ethnl_req_get_phydev(), which gets the PHY from + * what's in req_info + */ + ret = ethnl_default_dump_one(skb, ctx, info); + if (ret) + break; + } + + return ret; +} + static int ethnl_default_dump_one_dev(struct sk_buff *skb, struct net_device *dev, struct ethnl_dump_ctx *ctx, const struct genl_info *info) diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h index 79fe98190c64..530a9b5c8b39 100644 --- a/net/ethtool/netlink.h +++ b/net/ethtool/netlink.h @@ -327,6 +327,12 @@ struct ethnl_dump_ctx { void *cmd_ctx; }; +/* Generic callbacks to be used by PHY targeting commands */ +int ethnl_dump_start_perphy(struct ethnl_dump_ctx *ctx); +int ethnl_dump_one_dev_perphy(struct sk_buff *skb, struct ethnl_dump_ctx *ctx, + const struct genl_info *info); +void ethnl_dump_done_perphy(struct ethnl_dump_ctx *ctx); + int ethnl_ops_begin(struct net_device *dev); void ethnl_ops_complete(struct net_device *dev);
As there are multiple ethnl commands that report messages based on phy_device information, let's introduce a set of ethnl generic dump helpers to allow DUMP support for each PHY on a given netdev. This logic iterates over the phy_link_topology of each netdev (or a single netdev for filtered DUMP), and call ethnl_default_dump_one() with the req_info populated with ifindex + phyindex. This allows re-using all the existing infra for phy-targetting commands that already use ethnl generic helpers. Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> --- V2: Rebase net/ethtool/netlink.c | 53 +++++++++++++++++++++++++++++++++++++++++++ net/ethtool/netlink.h | 6 +++++ 2 files changed, 59 insertions(+)