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

Mingyu Li igvtee at gmail.com
Thu Oct 31 11:23:57 EDT 2019


the upstream kernel. the function mtk_napi_rx always be called if it have
packet to receive. it doesn't check status register.
but on openwrt code. check the status register first. then call fe_poll_rx.
if you clear status register. fe_poll_rx will will not be called next time.

Rosen Penev <rosenp at gmail.com> 於 2019年10月30日 週三 上午12:51寫道:
>
> On Wed, Mar 6, 2019 at 12:37 AM Mingyu Li <igvtee at gmail.com> wrote:
> >
> > 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.
> I took a look at this again. The upstream kernel driver does the same
> as this patch: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/mediatek/mtk_eth_soc.c?h=v4.14.151#n1189
> >
> > 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