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 <ros...@gmail.com> 於 2019年10月30日 週三 上午12:51寫道: > > On Wed, Mar 6, 2019 at 12:37 AM Mingyu Li <igv...@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 <ros...@gmail.com> 於 2019年3月6日 週三 下午12:08寫道: > > > > > > From: NeilBrown <n...@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 <n...@brown.name> > > > Signed-off-by: Rosen Penev <ros...@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 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel