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

Serge Semin Sergey.Semin at baikalelectronics.ru
Mon Feb 8 09:03:24 EST 2021


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 at 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 --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,
-- 
2.29.2




More information about the linux-arm-kernel mailing list