--- fec_a.c	2008-03-03 09:12:26.000000000 +0100
+++ fec.c	2008-03-03 09:10:52.000000000 +0100
@@ -159,6 +159,8 @@
 #define FEC_ENET_MII	((uint)0x00800000)	/* MII interrupt */
 #define FEC_ENET_EBERR	((uint)0x00400000)	/* SDMA bus error */
 
+#define FEC_NOTUSED   ((uint)0xF5400000)	/* Not used */
+
 /* The FEC stores dest/src/type, data, and checksum for receive packets.
  */
 #define PKT_MAXBUF_SIZE		1518
@@ -230,7 +232,10 @@
 static int fec_enet_open(struct net_device *dev);
 static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void fec_enet_mii(struct net_device *dev);
-static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
+static irqreturn_t fec_enet_interrupt_NULL(int irq, void * dev_id);
+static irqreturn_t fec_enet_interrupt_TXF(int irq, void * dev_id);
+static irqreturn_t fec_enet_interrupt_RXF(int irq, void * dev_id);
+static irqreturn_t fec_enet_interrupt_MII(int irq, void * dev_id);
 static void fec_enet_tx(struct net_device *dev);
 static void fec_enet_rx(struct net_device *dev);
 static int fec_enet_close(struct net_device *dev);
@@ -450,8 +455,9 @@
 /* The interrupt handler.
  * This is called from the MPC core interrupt.
  */
+
 static irqreturn_t
-fec_enet_interrupt(int irq, void * dev_id)
+fec_enet_interrupt_MII(int irq, void * dev_id)
 {
 	struct	net_device *dev = dev_id;
 	volatile fec_t	*fecp;
@@ -459,37 +465,77 @@
 	int handled = 0;
 
 	fecp = (volatile fec_t*)dev->base_addr;
+	int_events = fecp->fec_ievent;
 
-	/* Get the interrupt events that caused us to be here.
-	*/
-	while ((int_events = fecp->fec_ievent) != 0) {
-		fecp->fec_ievent = int_events;
+	fecp->fec_ievent = (int_events & (FEC_NOTUSED | FEC_ENET_MII));
 
-		/* Handle receive event in its own function.
-		 */
-		if (int_events & FEC_ENET_RXF) {
-			handled = 1;
-			fec_enet_rx(dev);
-		}
+        if(int_events & FEC_ENET_MII) {
+        	handled = 1;
+		fec_enet_mii(dev);
+        }
 
-		/* Transmit OK, or non-fatal error. Update the buffer
-		   descriptors. FEC handles all errors, we just discover
-		   them as part of the transmit process.
-		*/
-		if (int_events & FEC_ENET_TXF) {
-			handled = 1;
-			fec_enet_tx(dev);
-		}
+        return IRQ_RETVAL(handled);
+}
 
-		if (int_events & FEC_ENET_MII) {
-			handled = 1;
-			fec_enet_mii(dev);
-		}
+static irqreturn_t
+fec_enet_interrupt_NULL(int irq, void * dev_id)
+{
+	struct	net_device *dev = dev_id;
+	volatile fec_t	*fecp;
+	uint	int_events;
+	int handled = 0;
+
+	fecp = (volatile fec_t*)dev->base_addr;
+	int_events = fecp->fec_ievent;
+
+	fecp->fec_ievent = (int_events & FEC_NOTUSED);
+
+        return IRQ_RETVAL(handled);
+}
+static irqreturn_t
+fec_enet_interrupt_RXF(int irq, void * dev_id)
+{
+	struct	net_device *dev = dev_id;
+	volatile fec_t	*fecp;
+	uint	int_events;
+	int handled = 0;
+
+	fecp = (volatile fec_t*)dev->base_addr;
+	int_events = fecp->fec_ievent;
+
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_MII);
+	fecp->fec_ievent = (int_events & (FEC_NOTUSED | FEC_ENET_RXF));
+
+        if(int_events & FEC_ENET_RXF) {
+        	handled = 1;
+		fec_enet_rx(dev);
+        }
+
+        fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
 
-	}
 	return IRQ_RETVAL(handled);
 }
 
+static irqreturn_t
+fec_enet_interrupt_TXF(int irq, void * dev_id)
+{
+	struct	net_device *dev = dev_id;
+	volatile fec_t	*fecp;
+	uint	int_events;
+	int handled = 0;
+
+	fecp = (volatile fec_t*)dev->base_addr;
+	int_events = fecp->fec_ievent;
+
+	fecp->fec_ievent = (int_events & (FEC_NOTUSED | FEC_ENET_TXF));
+
+        if(int_events & FEC_ENET_TXF) {
+        	handled = 1;
+		fec_enet_tx(dev);
+        }
+
+	return IRQ_RETVAL(handled);
+}
 
 static void
 fec_enet_tx(struct net_device *dev)
@@ -1384,8 +1430,26 @@
 
 	/* Setup interrupt handlers. */
 	for (idp = id; idp->name; idp++) {
-		if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0)
-			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+		if ((idp->irq != 23) && (idp->irq != 27) && (idp->irq != 29)) {
+			if (request_irq(b+idp->irq, fec_enet_interrupt_NULL, 0, idp->name, dev) != 0)
+				printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+		}
+
+		if (idp->irq == 23) {
+			if (request_irq(b+idp->irq, fec_enet_interrupt_TXF, 0, idp->name, dev) != 0)
+				printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+		}
+
+		if (idp->irq == 27) {
+			if (request_irq(b+idp->irq, fec_enet_interrupt_RXF, 0, idp->name, dev) != 0)
+				printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+		}
+
+		if (idp->irq == 29) {
+			if (request_irq(b+idp->irq, fec_enet_interrupt_MII, 0, idp->name, dev) != 0)
+				printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+		}
+
 	}
 
 	/* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
@@ -1397,7 +1461,7 @@
 		b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0;
 		icrp = (volatile unsigned char *) (MCF_IPSBAR + b +
 			MCFINTC_ICR0);
-		for (i = 23, ilip = 0x28; (i < 36); i++)
+		for (i = 23, ilip = 0x27; (i < 36); i++)
 			icrp[i] = ilip--;
 
 		imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
@@ -2465,8 +2529,7 @@
 
 	/* Clear and enable interrupts */
 	fecp->fec_ievent = 0xffc00000;
-	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
 
 	/* Queue up command to detect the PHY and initialize the
 	 * remainder of the interface.
@@ -2593,8 +2656,7 @@
 
 	/* Enable interrupts we wish to service.
 	*/
-	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
 }
 
 static void
