ramips: ethernet: fix to interrupt handling
authorNeilBrown <neil@brown.name>
Tue, 29 Oct 2019 17:23:28 +0000 (10:23 -0700)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 6 Sep 2020 15:11:34 +0000 (17:11 +0200)
The current code acknowledged interrupts *after* polling.
This is the wrong way around, and could cause an interrupt to
be missed.
This is not likely to be fatal as another packet, and so another
interrupt, should come along soon.  But maybe it is causing
problems, so let's fix it anyway.

Signed-off-by: NeilBrown <neil@brown.name>
(Note that this matches the upstream driver.)
Signed-off-by: Rosen Penev <rosenp@gmail.com>
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c

index b2c3d32c5549b6fd8ea4c76dc224b9b4b41130d8..3541b1124000d1d65bfe5fdb9fc464bffe5a1c1d 100644 (file)
@@ -876,6 +876,8 @@ static int fe_poll_rx(struct napi_struct *napi, int budget,
        struct fe_rx_dma *rxd, trxd;
        int done = 0, pad;
 
+       fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
+
        if (netdev->features & NETIF_F_RXCSUM)
                checksum_bit = soc->checksum_bit;
        else
@@ -968,9 +970,6 @@ release_desc:
                done++;
        }
 
-       if (done < budget)
-               fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
-
        return done;
 }
 
@@ -986,6 +985,8 @@ static int fe_poll_tx(struct fe_priv *priv, int budget, u32 tx_intr,
        u32 idx, hwidx;
        struct fe_tx_ring *ring = &priv->tx_ring;
 
+       fe_reg_w32(tx_intr, FE_REG_FE_INT_STATUS);
+
        idx = ring->tx_free_idx;
        hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);
 
@@ -1009,9 +1010,7 @@ static int fe_poll_tx(struct fe_priv *priv, int budget, u32 tx_intr,
        if (idx == hwidx) {
                /* read hw index again make sure no new tx packet */
                hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);
-               if (idx == hwidx)
-                       fe_reg_w32(tx_intr, FE_REG_FE_INT_STATUS);
-               else
+               if (idx != hwidx)
                        *tx_again = 1;
        } else {
                *tx_again = 1;