[PATCH net-next v2 2/2] net: stmmac: align real_num_tx_queues to mqprio configuration
From: Lorenzo Bianconi
Date: Thu Sep 24 2026 - 07:09:07 EST
stmmac_hw_setup() unconditionally sets the number of real TX queues to
plat->tx_queues_to_use on every device open. When a tc-mqprio qdisc is
offloaded the driver reduces netif_set_real_num_tx_queues() to the number
of queues enabled by the offload, but the next device open reverts it to
the devicetree value while the netdev TC map is still the one programmed
by the qdisc, leaving the two inconsistent.
Store the number of TX queues enabled by the current qdisc configuration
in the per-qdisc state (priv->xmit_qdisc.num_tx_queues) and use it in
stmmac_hw_setup() in place of the devicetree value.
The field defaults to plat->tx_queues_to_use at probe time and is restored
to it when the mqprio qdisc is destroyed or its setup fails, so a device
without an active mqprio offload keeps the devicetree configured queue
count across reopens.
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 3 +++
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 69b400e9b138..a8f06192d696 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -302,6 +302,7 @@ struct stmmac_priv {
struct {
u32 prio[MTL_MAX_TX_QUEUES];
+ u32 num_tx_queues;
u8 algo;
} xmit_qdisc;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0c9083f8846e..ad6be5166b95 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3772,7 +3772,7 @@ static int stmmac_hw_setup(struct net_device *dev)
/* Configure real RX and TX queues */
netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
- netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
+ netif_set_real_num_tx_queues(dev, priv->xmit_qdisc.num_tx_queues);
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
@@ -7923,6 +7923,7 @@ static int __stmmac_dvr_probe(struct device *device,
priv->xmit_qdisc.prio[i] = priv->plat->tx_queues_cfg[i].prio;
}
priv->xmit_qdisc.algo = priv->plat->tx_sched_algorithm;
+ priv->xmit_qdisc.num_tx_queues = priv->plat->tx_queues_to_use;
if (priv->plat->flags & STMMAC_FLAG_MULTI_MSI_EN) {
ret = stmmac_msi_init(priv, res);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 54242461a860..1accc8e962d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -1285,6 +1285,7 @@ static int stmmac_reset_tc_mqprio(struct net_device *ndev,
stmmac_prog_mtl_tx_algorithms(priv, priv->hw,
priv->plat->tx_sched_algorithm);
priv->xmit_qdisc.algo = priv->plat->tx_sched_algorithm;
+ priv->xmit_qdisc.num_tx_queues = priv->plat->tx_queues_to_use;
netdev_reset_tc(ndev);
netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
@@ -1427,6 +1428,8 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
if (mode == TC_MQPRIO_MODE_CHANNEL)
tc_mqprio_config_queue_prio(priv, qopt);
+ priv->xmit_qdisc.num_tx_queues = num_tx_queues;
+
return 0;
error_reset_num_tx_queues:
--
2.55.0