korina: rework korina_rx() for use with napi
This function needs an early exit condition to function properly, or else caller assumes napi workload wasn't enough to handle all received packets and korina_rx is called again (and again and again and ...). Signed-off-by: Phil Sutter <n0-1@freewrt.org> Acked-by: Florian Fainelli <florian@openwrt.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
beb0babfb7
commit
4cf83b664f
@@ -353,15 +353,20 @@ static int korina_rx(struct net_device *dev, int limit)
|
|||||||
struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done];
|
struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done];
|
||||||
struct sk_buff *skb, *skb_new;
|
struct sk_buff *skb, *skb_new;
|
||||||
u8 *pkt_buf;
|
u8 *pkt_buf;
|
||||||
u32 devcs, pkt_len, dmas, rx_free_desc;
|
u32 devcs, pkt_len, dmas;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
dma_cache_inv((u32)rd, sizeof(*rd));
|
dma_cache_inv((u32)rd, sizeof(*rd));
|
||||||
|
|
||||||
for (count = 0; count < limit; count++) {
|
for (count = 0; count < limit; count++) {
|
||||||
|
skb = lp->rx_skb[lp->rx_next_done];
|
||||||
|
skb_new = NULL;
|
||||||
|
|
||||||
devcs = rd->devcs;
|
devcs = rd->devcs;
|
||||||
|
|
||||||
|
if ((KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Update statistics counters */
|
/* Update statistics counters */
|
||||||
if (devcs & ETH_RX_CRC)
|
if (devcs & ETH_RX_CRC)
|
||||||
dev->stats.rx_crc_errors++;
|
dev->stats.rx_crc_errors++;
|
||||||
@@ -384,16 +389,9 @@ static int korina_rx(struct net_device *dev, int limit)
|
|||||||
* in Rc32434 (errata ref #077) */
|
* in Rc32434 (errata ref #077) */
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
} else if ((devcs & ETH_RX_ROK)) {
|
||||||
|
|
||||||
while ((rx_free_desc = KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) {
|
|
||||||
/* init the var. used for the later
|
|
||||||
* operations within the while loop */
|
|
||||||
skb_new = NULL;
|
|
||||||
pkt_len = RCVPKT_LENGTH(devcs);
|
pkt_len = RCVPKT_LENGTH(devcs);
|
||||||
skb = lp->rx_skb[lp->rx_next_done];
|
|
||||||
|
|
||||||
if ((devcs & ETH_RX_ROK)) {
|
|
||||||
/* must be the (first and) last
|
/* must be the (first and) last
|
||||||
* descriptor then */
|
* descriptor then */
|
||||||
pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
|
pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
|
||||||
@@ -441,7 +439,6 @@ static int korina_rx(struct net_device *dev, int limit)
|
|||||||
rd = &lp->rd_ring[lp->rx_next_done];
|
rd = &lp->rd_ring[lp->rx_next_done];
|
||||||
writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas);
|
writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dmas = readl(&lp->rx_dma_regs->dmas);
|
dmas = readl(&lp->rx_dma_regs->dmas);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user