[PATCH net-next] net: libwx: Add ethtool -L support for VF drivers
From: Mengyuan Lou <mengyuanlou@net-swift.com>
Date: 2026-09-15 09:38:55
Subsystem:
networking drivers, the rest, wangxun ethernet driver · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Jiawen Wu, Mengyuan Lou
Implement get_channels and set_channels ethtool operations for Wangxun VF net_device instances in libwx. This allows users to query and dynamically reconfigure the number of RX/TX channels on VF interfaces via `ethtool -l/ -L`. Specifically: - Add wx_get_channels_vf() and wx_set_channels_vf() to report and update channel limits and combined queue counts. - Re-evaluate RSS limits in txgbevf_set_num_queues() based on user settings stored in wx->ring_feature[RING_F_RSS].limit. - Adjust VF MRQC RSS hash mask logic in wx_setup_vfmrqc_vf() to correctly match queue configuration thresholds. Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com> --- .../net/ethernet/wangxun/libwx/wx_ethtool.c | 64 +++++++++++++++++++ .../net/ethernet/wangxun/libwx/wx_vf_lib.c | 2 +- .../ethernet/wangxun/txgbevf/txgbevf_main.c | 3 + 3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index 940d2e59876c..d24370790941 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c@@ -564,6 +564,68 @@ int wx_set_channels(struct net_device *dev, } EXPORT_SYMBOL(wx_set_channels); +static void wx_get_channels_vf(struct net_device *dev, + struct ethtool_channels *ch) +{ + struct wx *wx = netdev_priv(dev); + + /* report maximum channels */ + ch->max_combined = wx->mac.max_rx_queues; + + ch->max_other = 1; + ch->other_count = 1; + + /* record current channels */ + ch->combined_count = wx->num_rx_queues; +} + +static int wx_set_channels_vf(struct net_device *dev, + struct ethtool_channels *ch) +{ + struct wx *wx = netdev_priv(dev); + u16 rss_limit; + int ret; + + rss_limit = wx->ring_feature[RING_F_RSS].limit; + + /* verify other_count has not changed */ + if (ch->other_count != 1) + return -EINVAL; + + /* verify the number of channels does not exceed hardware limits */ + if (ch->combined_count > wx->mac.max_rx_queues) + return -EINVAL; + + /* if device is resetting, do nothing */ + if (test_bit(WX_STATE_RESETTING, wx->state)) + return -EBUSY; + + wx->ring_feature[RING_F_RSS].limit = ch->combined_count; + + if (netif_running(dev)) + wxvf_close(dev); + + wx_clear_interrupt_scheme(wx); + + ret = wx_init_interrupt_scheme(wx); + if (ret) + goto err_out; + + if (netif_running(dev)) { + ret = wxvf_open(dev); + if (ret) + goto err_close; + } + + return 0; + +err_close: + wx_clear_interrupt_scheme(wx); +err_out: + wx->ring_feature[RING_F_RSS].limit = rss_limit; + return ret; +} + u32 wx_rss_indir_size(struct net_device *netdev) { struct wx *wx = netdev_priv(netdev);
@@ -852,6 +914,8 @@ static const struct ethtool_ops wx_ethtool_ops_vf = { .set_coalesce = wx_set_coalesce, .get_ts_info = ethtool_op_get_ts_info, .get_link_ksettings = wx_get_link_ksettings_vf, + .get_channels = wx_get_channels_vf, + .set_channels = wx_set_channels_vf, }; void wx_set_ethtool_ops_vf(struct net_device *netdev)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c
index 7325b475ee10..6fec3ab5e4e4 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c@@ -237,7 +237,7 @@ void wx_setup_vfmrqc_vf(struct wx *wx) vfmrqc |= WX_VXMRQC_RSS_EN; - if (wx->num_rx_queues > 3) + if (wx->num_rx_queues >= 3) vfmrqc |= WX_VXMRQC_RSS_HASH(2); else if (wx->num_rx_queues > 1) vfmrqc |= WX_VXMRQC_RSS_HASH(1);
diff --git a/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c b/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c
index 8b16b900820a..6e8659082051 100644
--- a/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c
+++ b/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c@@ -72,6 +72,9 @@ static void txgbevf_set_num_queues(struct wx *wx) queue = min_t(u16, wx->mac.max_rx_queues, wx->mac.max_tx_queues); rss = min_t(u16, queue, rss); + if (wx->ring_feature[RING_F_RSS].limit) + rss = min_t(u16, rss, wx->ring_feature[RING_F_RSS].limit); + if (wx->vfinfo->vf_api >= wx_mbox_api_13) { wx->num_rx_queues = rss; wx->num_tx_queues = rss;
--
2.30.1