Add a new optional get_rxrings callback in ethtool_ops to allow drivers to provide the number of RX rings directly without going through the full get_rxnfc flow classification interface. Modify ethtool_get_rxrings() to use get_rxrings() if available, falling back to get_rxnfc() otherwise. Signed-off-by: Breno Leitao --- include/linux/ethtool.h | 1 + net/ethtool/ioctl.c | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index de5bd76a400ca..4f6da35a77eb1 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -1141,6 +1141,7 @@ struct ethtool_ops { struct ethtool_ringparam *, struct kernel_ethtool_ringparam *, struct netlink_ext_ack *); + int (*get_rxrings)(struct net_device *dev); void (*get_pause_stats)(struct net_device *dev, struct ethtool_pause_stats *pause_stats); void (*get_pauseparam)(struct net_device *, diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 1a9ad47f60313..2f3dbef9eb712 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1208,6 +1208,22 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, return 0; } +static int get_num_rxrings(struct net_device *dev) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + struct ethtool_rxnfc rx_rings; + int ret; + + if (ops->get_rxrings) + return ops->get_rxrings(dev); + + ret = ops->get_rxnfc(dev, &rx_rings, NULL); + if (ret < 0) + return ret; + + return rx_rings.data; +} + static noinline_for_stack int ethtool_get_rxrings(struct net_device *dev, u32 cmd, void __user *useraddr) @@ -1217,16 +1233,17 @@ static noinline_for_stack int ethtool_get_rxrings(struct net_device *dev, const struct ethtool_ops *ops = dev->ethtool_ops; int ret; - if (!ops->get_rxnfc) + if (!ops->get_rxnfc && !ops->get_rxrings) return -EOPNOTSUPP; ret = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr); if (ret) return ret; - ret = ops->get_rxnfc(dev, &info, NULL); - if (ret < 0) - return ret; + if (WARN_ON_ONCE(info.cmd != ETHTOOL_GRXRINGS)) + return -EOPNOTSUPP; + + info.data = get_num_rxrings(dev); return ethtool_rxnfc_copy_to_user(useraddr, &info, info_size, NULL); } -- 2.47.3