diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index b8ad98d..ce2d97a 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -58,6 +58,7 @@
 #define DM9000_ID		0x90000A46
 #define DM9000_PKT_MAX		1536	/* Received packet max size */
 #define DM9000_PKT_RDY		0x01	/* Packet ready to receive */
+#define DM9000_PKT_ERR      0x02
 
 #define DM9000_NCR             0x00
 #define DM9000_NSR             0x01
@@ -163,6 +164,7 @@
 #define IMR_ROM			(1<<2)
 #define IMR_PTM			(1<<1)
 #define IMR_PRM			(1<<0)
+#define IMR_LNKCHNG     (1<<5)
 
 struct dm9000_priv {
 	unsigned long iobase;
@@ -351,75 +353,82 @@ static int dm9000_eth_rx (struct eth_device *edev)
 	u32 tmplen, i;
 	u32 tmpdata;
 
+	udelay(2500); // we called in a loop to quick .. give me some time
+
 	/* Check packet ready or not */
 	DM9000_ior(priv, DM9000_MRCMDX);	/* Dummy read */
+	udelay(100);
 	rxbyte = readb(priv->iodata);	/* Got most updated data */
-	if (rxbyte == 0)
-		return 0;
 
 	/* Status check: this byte must be 0 or 1 */
-	if (rxbyte > 1) {
-		DM9000_iow(priv, DM9000_RCR, 0x00);	/* Stop Device */
-		DM9000_iow(priv, DM9000_ISR, 0x80);	/* Stop INT request */
-		debug("rx status check: %d\n", rxbyte);
+	if (rxbyte & DM9000_PKT_ERR) {
+		debug("rx status check failed: %d\n", rxbyte);
+		DM9000_iow(priv, DM9000_RCR, 0x00);  /* Stop Device */
+		DM9000_iow(priv, DM9000_ISR, IMR_PAR);   /* Stop INT request */
+		dm9000_reset(priv);
+		/* re-enable the interupt, rx */
+		DM9000_iow(priv, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
+		DM9000_iow(priv, DM9000_ISR, 0x0f);	
 	}
-	debug("receiving packet\n");
-
-	/* A packet ready now  & Get status/length */
-	writeb(DM9000_MRCMD, priv->iobase);
-
-	/* Move data from DM9000 */
-	/* Read received packet from RX SRAM */
-	switch (priv->buswidth) {
-	case DM9000_WIDTH_8:
-		RxStatus = readb(priv->iodata) + (readb(priv->iodata) << 8);
-		RxLen = readb(priv->iodata) + (readb(priv->iodata) << 8);
-		for (i = 0; i < RxLen; i++)
-			rdptr[i] = readb(priv->iodata);
-		break;
-	case DM9000_WIDTH_16:
-		RxStatus = readw(priv->iodata);
-		RxLen = readw(priv->iodata);
-		tmplen = (RxLen + 1) / 2;
-		for (i = 0; i < tmplen; i++)
-			((u16 *) rdptr)[i] = readw(priv->iodata);
-		break;
-	case DM9000_WIDTH_32:
-		tmpdata = readl(priv->iodata);
-		RxStatus = tmpdata;
-		RxLen = tmpdata >> 16;
-		tmplen = (RxLen + 3) / 4;
-		for (i = 0; i < tmplen; i++)
-			((u32 *) rdptr)[i] = readl(priv->iodata);
-		break;
-	default:
-		/* dm9000_probe makes sure this cannot happen */
-		return -EINVAL;
-	}
-
-	if ((RxStatus & 0xbf00) || (RxLen < 0x40)
-	    || (RxLen > DM9000_PKT_MAX)) {
-		if (RxStatus & 0x100) {
-			printf("rx fifo error\n");
-		}
-		if (RxStatus & 0x200) {
-			printf("rx crc error\n");
+	else if ((rxbyte & DM9000_PKT_RDY)) {
+			debug("receiving packet\n");
+
+			/* A packet ready now  & Get status/length */
+			writeb(DM9000_MRCMD, priv->iobase);
+			udelay(100);
+
+			/* Move data from DM9000 */
+			/* Read received packet from RX SRAM */
+			switch (priv->buswidth) {
+				case DM9000_WIDTH_8:
+					RxStatus = readb(priv->iodata) + (readb(priv->iodata) << 8);
+					RxLen = readb(priv->iodata) + (readb(priv->iodata) << 8);
+					for (i = 0; i < RxLen; i++)
+						rdptr[i] = readb(priv->iodata);
+					break;
+				case DM9000_WIDTH_16:
+					RxStatus = readw(priv->iodata);
+					RxLen = readw(priv->iodata);
+					tmplen = (RxLen + 1) / 2;
+					for (i = 0; i < tmplen; i++)
+						((u16 *) rdptr)[i] = readw(priv->iodata);
+					break;
+				case DM9000_WIDTH_32:
+					tmpdata = readl(priv->iodata);
+					RxStatus = tmpdata;
+					RxLen = tmpdata >> 16;
+					tmplen = (RxLen + 3) / 4;
+					for (i = 0; i < tmplen; i++)
+						((u32 *) rdptr)[i] = readl(priv->iodata);
+					break;
+				default:
+					/* dm9000_probe makes sure this cannot happen */
+					return -EINVAL;
+			}
+
+			if ((RxStatus & 0xbf00) || (RxLen < 0x40)
+					|| (RxLen > DM9000_PKT_MAX)) {
+				if (RxStatus & 0x100) {
+					printf("rx fifo error\n");
+				}
+				if (RxStatus & 0x200) {
+					printf("rx crc error\n");
+				}
+				if (RxStatus & 0x8000) {
+					printf("rx length error\n");
+				}
+				if (RxLen > DM9000_PKT_MAX) {
+					printf("rx length too big\n");
+				}
+				dm9000_reset(priv);
+				RxLen = 0;
+			} else {
+				/* Pass to upper layer */
+				debug("passing packet to upper layer\n");
+				NetReceive(NetRxPackets[0], RxLen);
+			}
 		}
-		if (RxStatus & 0x8000) {
-			printf("rx length error\n");
-		}
-		if (RxLen > DM9000_PKT_MAX) {
-			printf("rx length too big\n");
-			dm9000_reset(priv);
-		}
-	} else {
-
-		/* Pass to upper layer */
-		debug("passing packet to upper layer\n");
-		NetReceive(NetRxPackets[0], RxLen);
-		return RxLen;
-	}
-	return 0;
+	return RxLen;
 }
 
 static u16 read_srom_word(struct dm9000_priv *priv, int offset)
@@ -511,7 +520,7 @@ static int dm9000_probe(struct device_d *dev)
 	DM9000_iow(priv, DM9000_TCR, 0);	/* TX Polling clear */
 	DM9000_iow(priv, DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
 	DM9000_iow(priv, DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));	/* Flow Control : High/Low Water */
-	DM9000_iow(priv, DM9000_FCR, 0x0);	/* SH FIXME: This looks strange! Flow Control */
+	DM9000_iow(priv, DM9000_FCR, 0xFF);	/* Flow Control */
 	DM9000_iow(priv, DM9000_SMCR, 0);	/* Special Mode */
 	DM9000_iow(priv, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* clear TX status */
 	DM9000_iow(priv, DM9000_ISR, 0x0f);	/* Clear interrupt status */
@@ -520,7 +529,7 @@ static int dm9000_probe(struct device_d *dev)
 	DM9000_iow(priv, DM9000_GPCR, 0x01);	/* Let GPIO0 output */
 	DM9000_iow(priv, DM9000_GPR, 0x00);	/* Enable PHY */
 	DM9000_iow(priv, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* RX enable */
-	DM9000_iow(priv, DM9000_IMR, IMR_PAR);	/* Enable TX/RX interrupt mask */
+	DM9000_iow(priv, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM | IMR_LNKCHNG );	/* Enable TX/RX interrupt mask */
 
 	priv->miiphy.read = dm9000_phy_read;
 	priv->miiphy.write = dm9000_phy_write;

