diff mbox series

[03/20] net: stmmac: Fix false MTL RX overflow handling for higher queues

Message ID 20210208140341.9271-4-Sergey.Semin@baikalelectronics.ru (mailing list archive)
State New, archived
Headers show
Series net: stmmac: Obvious cleanups and several fixes | expand

Commit Message

Serge Semin Feb. 8, 2021, 2:03 p.m. UTC
Judging by the MAC/MTL-related part of the ISR implementation if MTL IRQs
status handler returns MTL Rx overflow bit set, the
stmmac_set_rx_tail_ptr() method will be called for all subsequent queues.
That most likely isn't what we want. Fix it by just overriding the status
variable on each loop iteration. Note we can freely break the loop at the
very beginning if the stmmac_host_mtl_irq_status() method returns -EINVAL,
because that error means the MTL IRQ status handler isn't available for
the detected hardware.

Fixes: 7bac4e1ec3ca ("net: stmmac: stmmac interrupt treatment prepared for multiple queues")
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>

---

Folks, I haven't seen an effect of that bug. The patch has been created
purely based on the code visual perception. If you think the handler is
supposed to work like that and I am missing something (though I have much
doubt about that), just drop this patch.
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5ee840525824..d45af1ea2565 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4149,7 +4149,6 @@  static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 	/* To handle GMAC own interrupts */
 	if ((priv->plat->has_gmac) || xmac) {
 		int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats);
-		int mtl_status;
 
 		if (unlikely(status)) {
 			/* For LPI we need to save the tx status */
@@ -4162,10 +4161,10 @@  static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
 		for (queue = 0; queue < queues_count; queue++) {
 			struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
 
-			mtl_status = stmmac_host_mtl_irq_status(priv, priv->hw,
-								queue);
-			if (mtl_status != -EINVAL)
-				status |= mtl_status;
+			status = stmmac_host_mtl_irq_status(priv, priv->hw,
+							    queue);
+			if (status == -EINVAL)
+				break;
 
 			if (status & CORE_IRQ_MTL_RX_OVERFLOW)
 				stmmac_set_rx_tail_ptr(priv, priv->ioaddr,