Index: linux-2.6.23.16/drivers/net/sl351x_gmac.c
===================================================================
--- linux-2.6.23.16.orig/drivers/net/sl351x_gmac.c	2008-03-15 17:00:32.365389612 +0200
+++ linux-2.6.23.16/drivers/net/sl351x_gmac.c	2008-03-15 17:00:55.366700383 +0200
@@ -127,6 +127,7 @@
 static int	gmac_initialized = 0;
 TOE_INFO_T toe_private_data;
 static int		do_again = 0;
+static int rx_poll_enabled;
 spinlock_t gmac_fq_lock;
 unsigned int FLAG_SWITCH;
 
@@ -1065,7 +1066,8 @@
 	    tp->intr3_enabled = 	0xffffffff;
 	    tp->intr4_selected = 	GMAC0_INT_BITS | CLASS_RX_FULL_INT_BITS |
 	    						HWFQ_EMPTY_INT_BIT | SWFQ_EMPTY_INT_BIT;
-	    tp->intr4_enabled = 	GMAC0_INT_BITS | SWFQ_EMPTY_INT_BIT;
+	    tp->intr4_enabled = 	GMAC0_INT_BITS | SWFQ_EMPTY_INT_BIT| GMAC0_RX_OVERRUN_INT_BIT;
+	    // GMAC0_TX_PAUSE_OFF_INT_BIT| GMAC0_MIB_INT_BIT;
 
 	    data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) & ~tp->intr0_selected;
 	    writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
@@ -1115,7 +1117,7 @@
 	    	tp->intr3_enabled	|= 	0xffffffff;
 	    	tp->intr4_selected 	|= 	CLASS_RX_FULL_INT_BITS |
 	    							HWFQ_EMPTY_INT_BIT | SWFQ_EMPTY_INT_BIT;
-	    	tp->intr4_enabled	|= 	SWFQ_EMPTY_INT_BIT;
+	    	tp->intr4_enabled	|= 	SWFQ_EMPTY_INT_BIT | GMAC1_RX_OVERRUN_INT_BIT;
 		}
 	    data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) | tp->intr0_selected;
 	    writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
@@ -2408,7 +2410,7 @@
 	// unsigned short max_cnt=TOE_SW_FREEQ_DESC_NUM>>1;
 
 	fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
-	spin_lock_irqsave(&gmac_fq_lock, flags);
+	// spin_lock_irqsave(&gmac_fq_lock, flags);
 	//while ((max_cnt--) && (unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
 	//				TOE_SW_FREEQ_DESC_NUM) != fq_rwptr.bits.rptr) {
 	while ((unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
@@ -2428,10 +2430,47 @@
 		SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, fq_rwptr.bits.wptr);
 		toe_private_data.fq_rx_rwptr.bits32 = fq_rwptr.bits32;
 	}
-	spin_unlock_irqrestore(&gmac_fq_lock, flags);
+	// spin_unlock_irqrestore(&gmac_fq_lock, flags);
 }
 // EXPORT_SYMBOL(toe_gmac_fill_free_q);
 
+static void gmac_registers(const char *message)
+{
+	unsigned int		status0;
+	unsigned int		status1;
+	unsigned int		status2;
+	unsigned int		status3;
+	unsigned int		status4;
+
+	printk("%s\n", message);
+
+	status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
+	status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
+	status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
+	status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
+	status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
+
+	printk("status: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
+		   status0, status1, status2, status3, status4);
+
+	status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_0_REG);
+	status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+	status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_2_REG);
+	status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_3_REG);
+	status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+
+	printk("mask  : s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
+		   status0, status1, status2, status3, status4);
+
+	status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
+	status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG);
+	status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG);
+	status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG);
+	status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+
+	printk("select: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
+		   status0, status1, status2, status3, status4);
+}
 /*----------------------------------------------------------------------
 * toe_gmac_interrupt
 *----------------------------------------------------------------------*/
@@ -2492,6 +2531,7 @@
 		writel(status3 & tp->intr3_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_3_REG);
 	if (status4)
 		writel(status4 & tp->intr4_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
+
 #if 0
 	/* handle freeq interrupt first */
 	if (status4 & tp->intr4_enabled) {
@@ -2536,10 +2576,31 @@
 			}
 				if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
 				{
-					if (likely(netif_rx_schedule_prep(dev)))
+					if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
         			{
-        				// unsigned int data32;
-        				// disable GMAC-0 rx interrupt
+        				unsigned int data32;
+
+						if (rx_poll_enabled)
+								gmac_registers("check #1");
+
+						BUG_ON(rx_poll_enabled == 1);
+
+#if 0
+        				/* Masks GMAC-0 rx interrupt */
+						data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+						data32 &= ~(DEFAULT_Q0_INT_BIT);
+						writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+
+        				/* Masks GMAC-0 queue empty interrupt */
+						data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+						data32 &= ~DEFAULT_Q0_INT_BIT;
+						writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+
+						data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+						data32 &= ~DEFAULT_Q0_INT_BIT;
+						writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+#endif
+
         				// class-Q & TOE-Q are implemented in future
         				//data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
         				//data32 &= ~DEFAULT_Q0_INT_BIT;
@@ -2549,7 +2610,8 @@
 						//tp->total_q_cnt_napi=0;
 						//rx_time = jiffies;
 						//rx_old_bytes = isPtr->rx_bytes;
-            			__netif_rx_schedule(dev);
+						__netif_rx_schedule(dev);
+						rx_poll_enabled = 1;
         			}
 			}
 		}
@@ -2569,9 +2631,31 @@
 
 			if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
 			{
-				if (likely(netif_rx_schedule_prep(dev)))
+				if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
         		{
-        			// unsigned int data32;
+        			unsigned int data32;
+
+					if (rx_poll_enabled)
+							gmac_registers("check #2");
+
+					BUG_ON(rx_poll_enabled == 1);
+
+#if 0
+					/* Masks GMAC-1 rx interrupt */
+					data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+					data32 &= ~(DEFAULT_Q1_INT_BIT);
+					writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+
+        			/* Masks GMAC-1 queue empty interrupt */
+					data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+					data32 &= ~DEFAULT_Q1_INT_BIT;
+					writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+
+					data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+					data32 &= ~DEFAULT_Q1_INT_BIT;
+					writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+#endif
+
          			// disable GMAC-0 rx interrupt
         			// class-Q & TOE-Q are implemented in future
         			//data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
@@ -2583,9 +2667,13 @@
 					//rx_time = jiffies;
 					//rx_old_bytes = isPtr->rx_bytes;
            			__netif_rx_schedule(dev);
+				rx_poll_enabled = 1;
         		}
 			}
 		}
+	} else {
+
+		gmac_registers("check #3");
 	}
 
 	// Interrupt Status 0
@@ -3306,8 +3394,10 @@
 		SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
      	tp->rx_rwptr.bits32 = rwptr.bits32;
 
-		toe_gmac_fill_free_q();
 	}
+
+	/* Handles first available packets only then refill the queue. */
+	toe_gmac_fill_free_q();
 }
 
 /*----------------------------------------------------------------------
@@ -4217,6 +4307,7 @@
     GMAC_RXDESC_T   	*curr_desc;
 	struct sk_buff 		*skb;
     DMA_RWPTR_T			rwptr;
+    unsigned int data32;
 	unsigned int 		pkt_size;
 	unsigned int        desc_count;
 	unsigned int        good_frame, chksum_status, rx_status;
@@ -4231,7 +4322,7 @@
 	//unsigned long long	rx_time;
 
 
-
+	BUG_ON(rx_poll_enabled == 0);
 #if 1
 	if (do_again)
 	{
@@ -4516,6 +4607,30 @@
 #endif
         //toe_gmac_fill_free_q();
         netif_rx_complete(dev);
+
+		rx_poll_enabled = 0;
+
+		data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+		if (tp->port_id == 0)
+				data32 |= DEFAULT_Q0_INT_BIT;
+		else
+				data32 |= DEFAULT_Q1_INT_BIT;
+		writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+
+		data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+		if (tp->port_id == 0)
+				data32 |= DEFAULT_Q0_INT_BIT;
+		else
+				data32 |= DEFAULT_Q1_INT_BIT;
+		writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+
+		data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+		if (tp->port_id == 0)
+				data32 |= DEFAULT_Q0_INT_BIT;
+		else
+				data32 |= DEFAULT_Q1_INT_BIT;
+		writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+
         // enable GMAC-0 rx interrupt
         // class-Q & TOE-Q are implemented in future
         //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);