[OpenWrt-Devel] ramips: ethernet: fix to interrupt handling
diff mbox series

Message ID 20190306040846.21746-1-rosenp@gmail.com
State New
Headers show
Series
  • [OpenWrt-Devel] ramips: ethernet: fix to interrupt handling
Related show

Commit Message

Rosen Penev March 6, 2019, 4:08 a.m. UTC
From: NeilBrown <neil@brown.name>

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>
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 .../drivers/net/ethernet/mediatek/mtk_eth_soc.c       | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Comments

Mingyu Li March 6, 2019, 8:37 a.m. UTC | #1
the original code use status register to keep there still have some
pkts in buffer.
need next napi call to receive it.

if 128 packets in buffer. you clear status first. because napi max
handle 64 packets in buffer.
so 64 packets need to handle in next napi poll. if no new packet
comming. the status register will not set.
so fe_poll function will not call fe_poll_tx or fe_poll_rx. that would
be a problem.

the status register also use to control napi interrupt enable. must
make sure no packets need to
handle then enable interrupt.

Rosen Penev <rosenp@gmail.com> 於 2019年3月6日 週三 下午12:08寫道:
>
> From: NeilBrown <neil@brown.name>
>
> 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>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  .../drivers/net/ethernet/mediatek/mtk_eth_soc.c       | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index e0bc0ab818..2e0c8f94ca 100644
> --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -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
> @@ -963,9 +965,6 @@ release_desc:
>                 done++;
>         }
>
> -       if (done < budget)
> -               fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
> -
>         return done;
>  }
>
> @@ -981,6 +980,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);
>
> @@ -1004,9 +1005,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;
> --
> 2.17.1
>
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Patch
diff mbox series

diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e0bc0ab818..2e0c8f94ca 100644
--- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -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
@@ -963,9 +965,6 @@  release_desc:
 		done++;
 	}
 
-	if (done < budget)
-		fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
-
 	return done;
 }
 
@@ -981,6 +980,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);
 
@@ -1004,9 +1005,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;