* Fix SDRAM timings for LITE5200 / IceCube board

* Handle Auti-MDIX / connection status for INCA-IP

* Fix USB problems when attempting to read 0 bytes
diff --git a/CHANGELOG b/CHANGELOG
index 606e5ee..0a130aa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,12 @@
 Changes for U-Boot 1.0.2:
 ======================================================================
 
+* Fix SDRAM timings for LITE5200 / IceCube board
+
+* Handle Auti-MDIX / connection status for INCA-IP
+
+* Fix USB problems when attempting to read 0 bytes
+
 * Patch by Travis Sawyer, 26 Feb 2004:
   Fix broken compile for XPEDITE1K target.
 
diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c
index 3c9e4ee..59431db 100644
--- a/board/icecube/icecube.c
+++ b/board/icecube/icecube.c
@@ -54,16 +54,16 @@
 	*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
 	/* set mode register */
 #if defined(CONFIG_MPC5200)
-	*(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000;
+	*(vu_long *)MPC5XXX_SDRAM_MODE = 0x00cd0000;
 #elif defined(CONFIG_MGT5100)
 	*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
 #endif
-	/* precharge all banks */
-	*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
+	/* auto refresh */
+	*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
 	/* auto refresh */
 	*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
 	/* set mode register */
-	*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
+	*(vu_long *)MPC5XXX_SDRAM_MODE = 0x00cd0000;
 	/* normal operation */
 	*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
 #endif
@@ -93,8 +93,8 @@
 	*(vu_long *)MPC5XXX_CDM_PORCFG = 0x10000000;
 #else
 	/* setup config registers */
-	*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
-	*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xd2322800;
+	*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x8ad70000;
 #endif
 
 #elif defined(CONFIG_MGT5100)
diff --git a/common/usb_storage.c b/common/usb_storage.c
index dbe9cd9..fd116be 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -899,8 +899,12 @@
 	unsigned short smallblks;
 	struct usb_device *dev;
 	int retry,i;
-	ccb *srb=&usb_ccb;
-	device&=0xff;
+	ccb *srb = &usb_ccb;
+
+	if (blkcnt == 0)
+		return 0;
+
+	device &= 0xff;
 	/* Setup  device
 	 */
 	USB_STOR_PRINTF("\nusb_read: dev %d \n",device);
diff --git a/drivers/inca-ip_sw.c b/drivers/inca-ip_sw.c
index 88bc813..3b6397d 100644
--- a/drivers/inca-ip_sw.c
+++ b/drivers/inca-ip_sw.c
@@ -1,7 +1,7 @@
 /*
  * INCA-IP internal switch ethernet driver.
  *
- * (C) Copyright 2003
+ * (C) Copyright 2003-2004
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -67,6 +67,11 @@
 #define INCA_DMA_RX_SOP 0x40000000
 #define INCA_DMA_RX_EOP 0x20000000
 
+#define INCA_SWITCH_PHY_SPEED_10H	0x1
+#define INCA_SWITCH_PHY_SPEED_10F	0x5
+#define INCA_SWITCH_PHY_SPEED_100H	0x2
+#define INCA_SWITCH_PHY_SPEED_100F	0x6
+
 /************************ Auto MDIX settings ************************/
 #define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR      INCA_IP_Ports_P1_DIR
 #define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL   INCA_IP_Ports_P1_ALTSEL
@@ -221,8 +226,7 @@
 
 	/* Initialize the descriptor rings.
 	 */
-	for (i = 0; i < NUM_RX_DESC; i++)
-	{
+	for (i = 0; i < NUM_RX_DESC; i++) {
 		inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]);
 		memset(rx_desc, 0, sizeof(rx_ring[i]));
 
@@ -330,8 +334,7 @@
 }
 
 
-static int inca_switch_send(struct eth_device *dev, volatile void *packet,
-						  int length)
+static int inca_switch_send(struct eth_device *dev, volatile void *packet, int length)
 {
 	int                    i;
 	int                    res         = -1;
@@ -628,7 +631,12 @@
 #if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
 static int inca_amdix(void)
 {
-	u32 regValue = 0;
+	u32 phyReg1 = 0;
+	u32 phyReg4 = 0;
+	u32 phyReg5 = 0;
+	u32 phyReg6 = 0;
+	u32 phyReg31 = 0;
+	u32 regEphy = 0;
 	int mdi_flag;
 	int retries;
 
@@ -637,31 +645,29 @@
 	*INCA_IP_AUTO_MDIX_LAN_PORTS_DIR    |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
 	*INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
 
+#if 0
 	/* Wait for signal.
 	 */
 	retries = WAIT_SIGNAL_RETRIES;
-	while (--retries)
-	{
+	while (--retries) {
 		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
 				(0x1 << 31) |	/* RA		*/
 				(0x0 << 30) |	/* Read		*/
 				(0x6 << 21) |	/* LAN		*/
 				(17  << 16));	/* PHY_MCSR	*/
-		do
-		{
-			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, regValue);
-		}
-		while (regValue & (1 << 31));
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
 
-		if (regValue & (1 << 1))
-		{
+		if (phyReg1 & (1 << 1)) {
 			/* Signal detected */
 			break;
 		}
 	}
 
 	if (!retries)
-		return -1;
+		goto Fail;
+#endif
 
 	/* Set MDI mode.
 	 */
@@ -671,43 +677,135 @@
 	/* Wait for link.
 	 */
 	retries = WAIT_LINK_RETRIES;
-	while (--retries)
-	{
+	while (--retries) {
 		udelay(LINK_RETRY_DELAY * 1000);
 		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
 				(0x1 << 31) |	/* RA		*/
 				(0x0 << 30) |	/* Read		*/
 				(0x6 << 21) |	/* LAN		*/
 				(1   << 16));	/* PHY_BSR	*/
-		do
-		{
-			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, regValue);
-		}
-		while (regValue & (1 << 31));
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
 
-		if (regValue & (1 << 2))
-		{
+		if (phyReg1 & (1 << 2)) {
 			/* Link is up */
 			break;
-		}
-		else if (mdi_flag)
-		{
+		} else if (mdi_flag) {
 			/* Set MDIX mode */
 			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
 			mdi_flag = 0;
-		}
-		else
-		{
+		} else {
 			/* Set MDI mode */
 			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
 			mdi_flag = 1;
 		}
 	}
 
-	if (!retries)
-		return -1;
+	if (!retries) {
+		goto Fail;
+	} else {
+		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(1   << 16));	/* PHY_BSR	*/
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
+
+		/* Auto-negotiation / Parallel detection complete
+		 */
+		if (phyReg1 & (1 << 5)) {
+			SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(31  << 16));	/* PHY_SCSR	*/
+			do {
+        	                SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31);
+			} while (phyReg31 & (1 << 31));
+
+			switch ((phyReg31 >> 2) & 0x7) {
+			case INCA_SWITCH_PHY_SPEED_10H:
+				/* 10Base-T Half-duplex */
+				regEphy = 0;
+				break;
+			case INCA_SWITCH_PHY_SPEED_10F:
+				/* 10Base-T Full-duplex */
+				regEphy = INCA_IP_Switch_EPHY_DL;
+				break;
+			case INCA_SWITCH_PHY_SPEED_100H:
+				/* 100Base-TX Half-duplex */
+				regEphy = INCA_IP_Switch_EPHY_SL;
+				break;
+			case INCA_SWITCH_PHY_SPEED_100F:
+				/* 100Base-TX Full-duplex */
+				regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL;
+				break;
+			}
+
+			/* In case of Auto-negotiation,
+			 * update the negotiated PAUSE support status
+			 */
+			if (phyReg1 & (1 << 3)) {
+				SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+					(0x1 << 31) |	/* RA		*/
+					(0x0 << 30) |	/* Read		*/
+					(0x6 << 21) |	/* LAN		*/
+					(6   << 16));	/* PHY_ANER	*/
+				do {
+        		                SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6);
+				} while (phyReg6 & (1 << 31));
+
+				/* We are Autoneg-able.
+				 * Is Link partner also able to autoneg?
+				 */
+				if (phyReg6 & (1 << 0)) {
+					SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+						(0x1 << 31) |	/* RA		*/
+						(0x0 << 30) |	/* Read		*/
+						(0x6 << 21) |	/* LAN		*/
+						(4   << 16));	/* PHY_ANAR	*/
+					do {
+        			                SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4);
+					} while (phyReg4 & (1 << 31));
+
+					/* We advertise PAUSE capab.
+					 * Does link partner also advertise it?
+					 */
+					if (phyReg4 & (1 << 10)) {
+						SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+							(0x1 << 31) |	/* RA		*/
+							(0x0 << 30) |	/* Read		*/
+							(0x6 << 21) |	/* LAN		*/
+							(5   << 16));	/* PHY_ANLPAR	*/
+						do {
+			        	                SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5);
+						} while (phyReg5 & (1 << 31));
+
+						/* Link partner is PAUSE capab.
+						 */
+						if (phyReg5 & (1 << 10)) {
+							regEphy |= INCA_IP_Switch_EPHY_PL;
+						}
+					}
+				}
+
+			}
+
+			/* Link is up */
+			regEphy |= INCA_IP_Switch_EPHY_LL;
+
+			SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy);
+		}
+	}
 
 	return 0;
+
+Fail:
+	printf("No Link on LAN port\n");
+	return -1;
 }
 #endif /* CONFIG_INCA_IP_SWITCH_AMDIX */