[OpenWrt-Devel] [PATCH] ramips: ethernet: fix to interrupt handling

Mingyu Li igvtee at gmail.com
Wed Mar 6 03:37:04 EST 2019


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 at gmail.com> 於 2019年3月6日 週三 下午12:08寫道:
>
> From: NeilBrown <neil at 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 at brown.name>
> Signed-off-by: Rosen Penev <rosenp at 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 at lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list