* Patch by Sean Chang, 9 Aug 2004:
  - Added I2C support for ML300.
  - Added support for ML300 to read out its environment information
    stored on the EEPROM.
  - Added support to use board specific parameters as part of
    U-Boot's environment information.
  - Updated MLD files to support configuration for new features
    above.

* Patches by Travis Sawyer, 5 Aug 2004:
  - Remove incorrect bridge settings for eth group 6
  - Add call to setup bridge in ppc_440x_eth_initialize
  - Fix ppc_440x_eth_init to reset the phy only if its the
    first time through, otherwise, just check the phy for the
    autonegotiated speed/duplex.  This allows the use of netconsole
  - only print the speed/duplex the first time the phy is reset.
diff --git a/board/xilinx/ml300/Makefile b/board/xilinx/ml300/Makefile
index d9007c0..880c494 100644
--- a/board/xilinx/ml300/Makefile
+++ b/board/xilinx/ml300/Makefile
@@ -19,22 +19,23 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 # MA 02111-1307 USA
-#
 
 include $(TOPDIR)/config.mk
 
-CFLAGS   += -I../ml300 -I../common -I../xilinx_enet
+CFLAGS   += -I../ml300 -I../common -I../xilinx_enet -I../xilinx_iic
 
 LIB	= lib$(BOARD).a
 
-OBJS	= $(BOARD).o serial.o \
-	  ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
+OBJS	= $(BOARD).o \
+	  serial.o \
+	  ../xilinx_enet/emac_adapter.o  ../xilinx_enet/xemac.o \
 	  ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
 	  ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
-	  ../xilinx_enet/xemac_intr_dma.o \
+	  ../xilinx_enet/xemac_intr_dma.o ../xilinx_iic/iic_adapter.o \
+	  ../xilinx_iic/xiic_l.o ../common/xipif_v1_23_b.o \
 	  ../common/xbasic_types.o ../common/xdma_channel.o \
 	  ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
-	  ../common/xversion.o
+	  ../common/xversion.o \
 
 SOBJS	= init.o
 
diff --git a/board/xilinx/ml300/ml300.c b/board/xilinx/ml300/ml300.c
index dbe8a8a..f335fc1 100644
--- a/board/xilinx/ml300/ml300.c
+++ b/board/xilinx/ml300/ml300.c
@@ -42,6 +42,10 @@
 #include <asm/processor.h>
 #include "xparameters.h"
 
+#ifdef CFG_ENV_IS_IN_EEPROM
+extern void convert_env(void);
+#endif
+
 int
 board_pre_init(void)
 {
@@ -51,22 +55,25 @@
 int
 checkboard(void)
 {
-	unsigned char *s = getenv("serial#");
-	unsigned char *e;
+	uchar tmp[64];		/* long enough for environment variables */
+	uchar *s, *e;
+	int i = getenv_r("L", tmp, sizeof (tmp));
 
-	if (!s || strncmp(s, "ML300", 9)) {
+	if (i < 0) {
 		printf("### No HW ID - assuming ML300");
 	} else {
-		for (e = s; *e; ++e) {
+		for (e = tmp; *e; ++e) {
 			if (*e == ' ')
 				break;
 		}
 
-		for (; s < e; ++s) {
+		printf("### Board Serial# is ");
+
+		for (s = tmp; s < e; ++s) {
 			putc(*s);
 		}
-	}
 
+	}
 	putc('\n');
 
 	return (0);
@@ -107,3 +114,15 @@
 	val = sys_info.freqPCI;
 	return val;
 }
+
+#ifdef CONFIG_MISC_INIT_R
+
+int
+misc_init_r()
+{
+	/* convert env name and value to u-boot standard */
+	convert_env();
+	return 0;
+}
+
+#endif
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
index 319b925..9daf147 100644
--- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
+++ b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
@@ -1,41 +1,55 @@
 #!/bin/bash
 
-if[$
-# -ne 1 ]
-   then echo "usage: Ltypes filename" > &2 exit 2 fi FILE = "$1"
+if [ $# -ne 1 ]
+then
+    echo "usage: Ltypes filename" >&2
+    exit 2
+fi
+
+FILE="$1"
 #TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
-   TMPFILE = $ {
-   FILE}
+TMPFILE=${FILE}.`date "+%s"`
+touch $TMPFILE || exit 1
 
-   . ` date "+%s" ` touch $TMPFILE || exit 1
 # Change all the Xilinx types to Linux types and put the result into a temp file
-   sed
-   - e 's/\bXTRUE\b/TRUE/g'
-   - e 's/\bXFALSE\b/FALSE/g'
-   - e 's/\bXNULL\b/NULL/g'
-   - e 's/<asm/delay.h>/<asm\/delay.h>/g'
-   - e 's/\bXENV_USLEEP\b/udelay/g'
-   - e 's/\bXuint8\b/u8/g'
-   - e 's/\bXuint16\b/u16/g'
-   - e 's/\bXuint32\b/u32/g'
-   - e 's/\bXint8\b/s8/g'
-   - e 's/\bXint16\b/s16/g'
-   - e 's/\bXint32\b/s32/g' - e 's/\bXboolean\b/u32/g' "${FILE}" > "${TMPFILE}"
+sed	\
+	-e 's/\bXTRUE\b/TRUE/g' \
+	-e 's/\bXFALSE\b/FALSE/g' \
+	-e 's/\bXNULL\b/NULL/g' \
+	-e 's/"xenv.h"/<asm\/delay.h>/g' \
+	-e 's/\bXENV_USLEEP\b/udelay/g' \
+	-e 's/\bXuint8\b/u8/g' \
+	-e 's/\bXuint16\b/u16/g' \
+	-e 's/\bXuint32\b/u32/g' \
+	-e 's/\bXint8\b/s8/g' \
+	-e 's/\bXint16\b/s16/g' \
+	-e 's/\bXint32\b/s32/g' \
+	-e 's/\bXboolean\b/u32/g' \
+	"${FILE}" > "${TMPFILE}"
+
 # Overlay the original file with the temp file
-   mv "${TMPFILE}" "${FILE}"
+mv "${TMPFILE}" "${FILE}"
+
 # Are we doing xbasic_types.h?
-   if["${FILE##*/}" = xbasic_types.h]
-   then
-# Remember as you're reading this that we've already gone through the prior
-# sed script.  We need to do some other things to xbasic_types.h:
-#   1) Add ifndefs around TRUE and FALSE defines
-#   2) Remove definition of NULL as NULL
-#   3) Replace most of the primitive types section with a #include
-   sed - e '/u32 true/,/#define false/Ic\
+if [ "${FILE##*/}" = xbasic_types.h ]
+then
+    # Remember as you're reading this that we've already gone through the prior
+    # sed script.  We need to do some other things to xbasic_types.h:
+    #   1) Add ifndefs around TRUE and FALSE defines
+    #   2) Remove definition of NULL as NULL
+    #   3) Replace most of the primitive types section with a #include
+    sed \
+	-e '/u32 true/,/#define false/Ic\
 #ifndef TRUE\
 #define TRUE 1\
 #endif\
 #ifndef FALSE\
 #define FALSE 0\
-#endif' - e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' - e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\
-#include <linux/types.h>' "${FILE}" > "${TMPFILE}" mv "${TMPFILE}" "${FILE}" fi
+#endif' \
+	-e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' \
+	-e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\
+#include <linux/types.h>' \
+	"${FILE}" > "${TMPFILE}"
+
+    mv "${TMPFILE}" "${FILE}"
+fi
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld
index e1aa7fd..5169241 100644
--- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld
+++ b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld
@@ -42,7 +42,11 @@
 PROPERTY size = 0;
 PARAM name = periph_name, desc = "Name of Peripheral connected", type = string;
 END ARRAY
-    PARAMETER name = TARGET_DIR, desc =
-    "Target Directory for U-Boot BSP", type = string;
+    PARAMETER name = TARGET_DIR, desc = "Target Directory for U-Boot BSP", type = string;
+
+# location of persistent storage in the IIC EEPROM (defaults are set for ML300)
+PARAMETER name = IIC_PERSISTENT_BASEADDR, desc = "Start of persistent storage block in the EEPROM address space", type = int, default = 1024;
+PARAMETER name = IIC_PERSISTENT_HIGHADDR, desc = "End of persistent storage block in the EEPROM address space", type = int, default = 2047;
+PARAMETER name = IIC_PERSISTENT_EEPROMADDR, desc = "Address of the EEPROM on the IIC bus", type = int, default = 0xA0;
 
 END LIBRARY
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl
index 8d939b4..9d44f44 100644
--- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl
+++ b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl
@@ -76,12 +76,18 @@
 		xredefine_uartns550 $drv "xparameters.h"
 	    }  elseif {[string compare -nocase $drvname "emac"] == 0} {
 		xredefine_emac $drv "xparameters.h"
+	    }  elseif {[string compare -nocase $drvname "iic"] == 0} {
+		xredefine_iic $drv "xparameters.h"
 	    }
 	}
     }
     
     # define core_clock
     xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ"
+
+    # define the values for the persistent storage in IIC
+    xredefine_params $libname "xparameters.h" "IIC_PERSISTENT_BASEADDR" "IIC_PERSISTENT_HIGHADDR" "IIC_PERSISTENT_EEPROMADDR"
+
 }
 
 proc xget_corefreq {} {
@@ -117,7 +123,16 @@
 	
 	if {$value != ""} {
 	    set value [xformat_addr_string $value $arg]
-	    set name [string toupper $arg]
+
+	    if {[string compare -nocase $arg "IIC_PERSISTENT_BASEADDR"] == 0} {
+		set name "PERSISTENT_0_IIC_0_BASEADDR"
+	    } elseif {[string compare -nocase $arg "IIC_PERSISTENT_HIGHADDR"] == 0} {
+		set name "PERSISTENT_0_IIC_0_HIGHADDR"
+	    } elseif {[string compare -nocase $arg "IIC_PERSISTENT_EEPROMADDR"] == 0} {
+		set name "PERSISTENT_0_IIC_0_EEPROMADDR"
+	    } else {
+		set name [string toupper $arg]
+	    }
 	    set name [format "XPAR_%s" $name]
 	    puts $file_handle "#define $name $value"
 	}
@@ -140,6 +155,11 @@
     
 }
 
+proc xredefine_iic {drvhandle file_name} {
+    xredefine_include_file $drvhandle $file_name "iic" "C_BASEADDR" "C_HIGHADDR" "C_TEN_BIT_ADR" "DEVICE_ID"
+
+}
+
 #######################
 
 proc xredefine_include_file {drv_handle file_name drv_string args} {
@@ -221,6 +241,8 @@
 	
 	if {[string compare -nocase $drvname "emac"] == 0} {
 	    xcopy_emac $drv $dirname
+	} elseif {[string compare -nocase $drvname "iic"] == 0} {
+	    xcopy_iic $drv $dirname
 	}
     }
     
@@ -267,6 +289,11 @@
     xcopy_dir $dirname $emac
 }
 
+proc xcopy_iic {drv_handle dirname} {
+    set iic "board/xilinx/xilinx_iic"
+    xcopy_dir $dirname $iic
+}
+
 proc xcopy_dir {srcdir dstdir} {
     
     set dstdirname [format "%s%s" "uboot/" $dstdir]
diff --git a/board/xilinx/ml300/xparameters.h b/board/xilinx/ml300/xparameters.h
index c636256..2c56737 100644
--- a/board/xilinx/ml300/xparameters.h
+++ b/board/xilinx/ml300/xparameters.h
@@ -1,48 +1,58 @@
 /*******************************************************************
 *
 * CAUTION: This file is automatically generated by libgen.
-* Version: Xilinx EDK 6.1.2 EDK_G.14
+* Version: Xilinx EDK 6.2 EDK_Gm.11
 * DO NOT EDIT.
 *
-*     Author: Xilinx, Inc.
-*
-*
-*     This program is free software; you can redistribute it and/or modify it
-*     under the terms of the GNU General Public License as published by the
-*     Free Software Foundation; either version 2 of the License, or (at your
-*     option) any later version.
-*
-*
-*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
-*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
-*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
-*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
-*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
-*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
-*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
-*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
-*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
-*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
-*     FITNESS FOR A PARTICULAR PURPOSE.
-*
-*
-*     Xilinx hardware products are not intended for use in life support
-*     appliances, devices, or systems. Use in such applications is
-*     expressly prohibited.
-*
-*
-*     (c) Copyright 2002-2004 Xilinx Inc.
-*     All rights reserved.
-*
-*
-*     You should have received a copy of the GNU General Public License along
-*     with this program; if not, write to the Free Software Foundation, Inc.,
-*     675 Mass Ave, Cambridge, MA 02139, USA.
+* Copyright (c) 2003 Xilinx, Inc.  All rights reserved.
 *
 * Description: Driver parameters
 *
 *******************************************************************/
 
+/******************************************************************/
+
+/* U-Boot Redefines */
+
+/******************************************************************/
+
+#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
+#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
+#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
+#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
+#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
+#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
+#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
+#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_IIC_0_BASEADDR XPAR_OPB_IIC_0_BASEADDR
+#define XPAR_IIC_0_HIGHADDR XPAR_OPB_IIC_0_HIGHADDR
+#define XPAR_IIC_0_TEN_BIT_ADR XPAR_OPB_IIC_0_TEN_BIT_ADR
+#define XPAR_IIC_0_DEVICE_ID XPAR_OPB_IIC_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
+#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
+#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
+#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
+#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
+#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
+
+/******************************************************************/
+
+#define XPAR_PERSISTENT_0_IIC_0_BASEADDR 0x00000400
+#define XPAR_PERSISTENT_0_IIC_0_HIGHADDR 0x000007FF
+#define XPAR_PERSISTENT_0_IIC_0_EEPROMADDR 0xA0
+
+/******************************************************************/
+
 #define XPAR_XPCI_NUM_INSTANCES 1
 #define XPAR_XPCI_CLOCK_HZ 33333333
 #define XPAR_OPB_PCI_REF_0_DEVICE_ID 0
@@ -181,36 +191,6 @@
 
 /******************************************************************/
 
-#define STDIN_BASEADDRESS 0xA0000000
-#define STDOUT_BASEADDRESS 0xA0000000
 #define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
 
 /******************************************************************/
-
-/* U-Boot Redefines */
-
-/******************************************************************/
-
-#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
-#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
-#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
-#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
-#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
-#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
-#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
-#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
-
-/******************************************************************/
-
-#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
-#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
-#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
-#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
-#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
-#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
-
-/******************************************************************/
-
-#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
-
-/******************************************************************/