diff -Naur linux-2.6.25.maxim/drivers/net/macb.c linux-2.6.25.at91-20080908/drivers/net/macb.c
--- linux-2.6.25.maxim/drivers/net/macb.c	2008-04-16 21:49:44.000000000 -0500
+++ linux-2.6.25.at91-20080908/drivers/net/macb.c	2008-09-03 16:58:59.000000000 -0500
@@ -455,10 +455,9 @@
 	int received = 0;
 	unsigned int tail = bp->rx_tail;
 	int first_frag = -1;
+	u32 addr, ctrl;
 
 	for (; budget > 0; tail = NEXT_RX(tail)) {
-		u32 addr, ctrl;
-
 		rmb();
 		addr = bp->rx_ring[tail].addr;
 		ctrl = bp->rx_ring[tail].ctrl;
@@ -497,47 +496,57 @@
 {
 	struct macb *bp = container_of(napi, struct macb, napi);
 	struct net_device *dev = bp->dev;
-	int work_done;
+	int work_done, orig_budget, pass_work_done;
 	u32 status;
 
 	status = macb_readl(bp, RSR);
-	macb_writel(bp, RSR, status);
 
 	work_done = 0;
+	pass_work_done = 0;
+	orig_budget = budget;
 	if (!status) {
 		/*
 		 * This may happen if an interrupt was pending before
 		 * this function was called last time, and no packets
 		 * have been received since.
 		 */
-		netif_rx_complete(dev, napi);
-		goto out;
-	}
-
-	dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
-		(unsigned long)status, budget);
-
-	if (!(status & MACB_BIT(REC))) {
-		dev_warn(&bp->pdev->dev,
-			 "No RX buffers complete, status = %02lx\n",
-			 (unsigned long)status);
-		netif_rx_complete(dev, napi);
 		goto out;
 	}
+restart_poll:
+	do {
+		macb_writel(bp, RSR, status);
+		dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
+			(unsigned long)status, budget);
+
+		if (unlikely(!(status & MACB_BIT(REC)))) {
+			dev_warn(&bp->pdev->dev,
+			 	"No RX buffers complete, status = %02lx\n",
+			 	(unsigned long)status);
+			goto out;
+		}
 
-	work_done = macb_rx(bp, budget);
-	if (work_done < budget)
-		netif_rx_complete(dev, napi);
-
-	/*
-	 * We've done what we can to clean the buffers. Make sure we
-	 * get notified when new packets arrive.
-	 */
+		pass_work_done = macb_rx(bp, budget);
+		work_done += pass_work_done;
+		budget -= pass_work_done;
+		if (unlikely(work_done >= orig_budget)) {
+			goto hitquota;
+		}
+	} while ((status = macb_readl(bp, RSR)));
 out:
+	netif_rx_complete(dev, napi);
 	macb_writel(bp, IER, MACB_RX_INT_FLAGS);
 
-	/* TODO: Handle errors */
+	/* check status again now that ints are re-enabled */
+	if (unlikely(status = macb_readl(bp, RSR))) {
+		/* reschedule polling to prevent rotting packets */
+		if (likely(netif_rx_reschedule(dev, napi))) {
+			macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
+			goto restart_poll;
+		}
+	}
 
+	/* TODO: Handle errors */
+hitquota:
 	return work_done;
 }
 
@@ -547,7 +556,7 @@
 	struct macb *bp = netdev_priv(dev);
 	u32 status;
 
-	status = macb_readl(bp, ISR);
+	status = macb_readl(bp, ISR) & ~macb_readl(bp, IMR);
 
 	if (unlikely(!status))
 		return IRQ_NONE;
@@ -562,7 +571,7 @@
 		}
 
 		if (status & MACB_RX_INT_FLAGS) {
-			if (netif_rx_schedule_prep(dev, &bp->napi)) {
+			if (likely(netif_rx_schedule_prep(dev, &bp->napi))) {
 				/*
 				 * There's no point taking any more interrupts
 				 * until we have processed the buffers
@@ -582,7 +591,7 @@
 		 * add that if/when we get our hands on a full-blown MII PHY.
 		 */
 
-		if (status & MACB_BIT(HRESP)) {
+		if (unlikely(status & MACB_BIT(HRESP))) {
 			/*
 			 * TODO: Reset the hardware, and maybe move the printk
 			 * to a lower-priority context as well (work queue?)
@@ -590,10 +599,8 @@
 			printk(KERN_ERR "%s: DMA bus error: HRESP not OK\n",
 			       dev->name);
 		}
-
-		status = macb_readl(bp, ISR);
+		status = macb_readl(bp, ISR) & ~macb_readl(bp, IMR);
 	}
-
 	spin_unlock(&bp->lock);
 
 	return IRQ_HANDLED;
@@ -1200,6 +1207,8 @@
 #endif
 
 	bp->tx_pending = DEF_TX_RING_PENDING;
+	/* clear statistics from transfers before Linux booted (i.e. u-boot) */
+	macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
 
 	err = register_netdev(dev);
 	if (err) {
