aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-08-23 20:45:32 -0400
committerLennert Buytenhek <buytenh@marvell.com>2008-08-23 21:32:56 -0400
commit819ddcafb33136f2ba18018a22edcf857f640528 (patch)
treee9cffe7c32e761da3a495bd51d1a9d5929a803dc /drivers/net
parent6a55617ed5d1aa62b850de2cf66f5ede2eef4825 (diff)
mv643xx_eth: fix NAPI 'rotting packet' issue
When a receive interrupt occurs, mv643xx_eth would first process the receive descriptors and then ACK the receive interrupt, instead of the other way round. This would leave a small race window between processing the last receive descriptor and clearing the receive interrupt status in which a new packet could come in, which would then 'rot' in the receive ring until the next receive interrupt would come in. Fix this by ACKing (clearing) the receive interrupt condition before processing the receive descriptors. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/mv643xx_eth.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 46819af3b062..af279f26c407 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -650,8 +650,6 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
650 650
651 if (rx < budget) { 651 if (rx < budget) {
652 netif_rx_complete(mp->dev, napi); 652 netif_rx_complete(mp->dev, napi);
653 wrl(mp, INT_CAUSE(mp->port_num), 0);
654 wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
655 wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT); 653 wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
656 } 654 }
657 655
@@ -1796,6 +1794,7 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
1796 */ 1794 */
1797#ifdef MV643XX_ETH_NAPI 1795#ifdef MV643XX_ETH_NAPI
1798 if (int_cause & INT_RX) { 1796 if (int_cause & INT_RX) {
1797 wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_RX));
1799 wrl(mp, INT_MASK(mp->port_num), 0x00000000); 1798 wrl(mp, INT_MASK(mp->port_num), 0x00000000);
1800 rdl(mp, INT_MASK(mp->port_num)); 1799 rdl(mp, INT_MASK(mp->port_num));
1801 1800