[PATCH v1 17/18] ibmveth: Wire ethtool set_channels to MQ RX queue resize
From: Mingming Cao <hidden>
Date: 2026-06-30 14:55:42
Also in:
netdev
Subsystem:
ibm power virtual ethernet device driver, linux for powerpc (32-bit and 64-bit), networking drivers, the rest · Maintainers:
Nick Child, Madhavan Srinivasan, Michael Ellerman, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Expose incremental RX resize through ethtool channel control. get_channels() reports rx_count from adapter->num_rx_queues and max_rx as IBMVETH_MAX_RX_QUEUES when MQ firmware is enabled, else 1. set_channels() validates rx_count is within 1..IBMVETH_MAX_RX_QUEUES. When rx_count changes and the interface is up, call ibmveth_resize_rx_queues_incremental(). When the interface is down, store the requested rx_count in adapter->num_rx_queues so the next open registers that many queues. Non-MQ firmware returns -EOPNOTSUPP for rx > 1. TX queue changes keep existing stop/wake behavior when tx_count changes. Signed-off-by: Mingming Cao <redacted> Reviewed-by: Dave Marquardt <redacted> --- drivers/net/ethernet/ibm/ibmveth.c | 58 +++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index ac4d89a66a8d..50a332ab83fd 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c@@ -2534,19 +2534,69 @@ static int ibmveth_set_channels(struct net_device *netdev, struct ethtool_channels *channels) { struct ibmveth_adapter *adapter = netdev_priv(netdev); - unsigned int old = netdev->real_num_tx_queues, - goal = channels->tx_count; + unsigned int old_rx = adapter->num_rx_queues; + unsigned int goal_rx = channels->rx_count; + unsigned int old = netdev->real_num_tx_queues; + unsigned int goal = channels->tx_count; + int rxq_entries = adapter->rx_queue[0].num_slots; int rc, i; /* If ndo_open has not been called yet then don't allocate, just set * desired netdev_queue's and return */ - if (!(netdev->flags & IFF_UP)) + if (!(netdev->flags & IFF_UP)) { + if (goal_rx > 1 && !adapter->multi_queue) { + netdev_err(netdev, + "Cannot resize to %u RX queues: multi-queue mode not supported by firmware\n", + goal_rx); + return -EOPNOTSUPP; + } + + if (goal_rx < 1 || goal_rx > IBMVETH_MAX_RX_QUEUES) { + netdev_err(netdev, + "Invalid RX queue count %u (must be 1-%d)\n", + goal_rx, IBMVETH_MAX_RX_QUEUES); + return -EINVAL; + } + + /* Stash desired RX count; open() publishes it via + * netif_set_real_num_rx_queues() after queue registration. + */ + if (goal_rx != adapter->num_rx_queues) + adapter->num_rx_queues = goal_rx; + return netif_set_real_num_tx_queues(netdev, goal); + } + + if (goal_rx > 1 && !adapter->multi_queue) { + netdev_err(netdev, + "Cannot resize to %u RX queues: multi-queue mode not supported by firmware\n", + goal_rx); + return -EOPNOTSUPP; + } + + if (goal_rx < 1 || goal_rx > IBMVETH_MAX_RX_QUEUES) { + netdev_err(netdev, + "Invalid RX queue count %u (must be 1-%d)\n", + goal_rx, IBMVETH_MAX_RX_QUEUES); + return -EINVAL; + } + + if (goal_rx != old_rx) { + rc = ibmveth_resize_rx_queues_incremental(adapter, goal_rx, + rxq_entries); + if (rc) { + netdev_err(netdev, "Failed to resize RX queues: %d\n", rc); + return rc; + } + } /* We have IBMVETH_MAX_QUEUES netdev_queue's allocated * but we may need to alloc/free the ltb's. */ + if (goal == old) + return 0; + netif_tx_stop_all_queues(netdev); /* Allocate any queue that we need */
@@ -2580,7 +2630,7 @@ static int ibmveth_set_channels(struct net_device *netdev, netif_tx_wake_all_queues(netdev); - return rc; + return 0; } static const struct ethtool_ops netdev_ethtool_ops = {
--
2.39.3 (Apple Git-146)