* 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/CHANGELOG b/CHANGELOG
index d9aed9e..788ea84 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,23 @@
 Changes since U-Boot 1.1.1:
 ======================================================================
 
+* 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.
+
 * Patch by Shlomo Kut, 29 Mar 2004:
   Add support for MKS Instruments "Quantum" board
 
diff --git a/board/xilinx/common/xipif_v1_23_b.c b/board/xilinx/common/xipif_v1_23_b.c
new file mode 100644
index 0000000..c7311ab
--- /dev/null
+++ b/board/xilinx/common/xipif_v1_23_b.c
@@ -0,0 +1,331 @@
+/* $Id: xipif_v1_23_b.c,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  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 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.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* FILENAME:
+*
+* xipif.c
+*
+* DESCRIPTION:
+*
+* This file contains the implementation of the XIpIf component. The
+* XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.  This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.  Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.  The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.  The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* The interrupt registers of the IPIF are parameterizable such that the only
+* the number of bits necessary for the device are implemented. The functions
+* of this component do not attempt to validate that the passed in arguments are
+* valid based upon the number of implemented bits.  This is necessary to
+* maintain the level of performance required for the common components.  Bits
+* of the registers are assigned starting at the least significant bit of the
+* registers.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Mutual Exclusion
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* NOTES:
+*
+* None.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to reduce size
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xipif_v1_23_b.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constant is used to generate bit masks for register testing
+ * in the self test functions, it defines the starting bit mask that is to be
+ * shifted from the LSB to MSB in creating a register test mask
+ */
+#define XIIF_V123B_FIRST_BIT_MASK     1UL
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XIpIf_SelfTest
+*
+* DESCRIPTION:
+*
+* This function performs a self test on the specified IPIF component.  Many
+* of the registers in the IPIF are tested to ensure proper operation.  This
+* function is destructive because the IPIF is reset at the start of the test
+* and at the end of the test to ensure predictable results.  The IPIF reset
+* also resets the entire device that uses the IPIF.  This function exits with
+* all interrupts for the device disabled.
+*
+* ARGUMENTS:
+*
+* InstancePtr points to the XIpIf to operate on.
+*
+* DeviceRegistersWidth contains the number of bits in the device interrupt
+* registers. The hardware is parameterizable such that only the number of bits
+* necessary to support a device are implemented.  This value must be between 0
+* and 32 with 0 indicating there are no device interrupt registers used.
+*
+* IpRegistersWidth contains the number of bits in the IP interrupt registers
+* of the device.  The hardware is parameterizable such that only the number of
+* bits necessary to support a device are implemented.  This value must be
+* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
+*
+* RETURN VALUE:
+*
+* A value of XST_SUCCESS indicates the test was successful with no errors.
+* Any one of the following error values may also be returned.
+*
+*   XST_IPIF_RESET_REGISTER_ERROR       The value of a register at reset was
+*                                       not valid
+*   XST_IPIF_IP_STATUS_ERROR            A write to the IP interrupt status
+*                                       register did not read back correctly
+*   XST_IPIF_IP_ACK_ERROR               One or more bits in the IP interrupt
+*                                       status register did not reset when acked
+*   XST_IPIF_IP_ENABLE_ERROR            The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/* the following constant defines the maximum number of bits which may be
+ * used in the registers at the device and IP levels, this is based upon the
+ * number of bits available in the registers
+ */
+#define XIIF_V123B_MAX_REG_BIT_COUNT 32
+
+XStatus
+XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
+{
+	XStatus Status;
+
+	/* assert to verify arguments are valid */
+
+	XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
+
+	/* reset the IPIF such that it's in a known state before the test
+	 * and interrupts are globally disabled
+	 */
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* perform the self test on the IP interrupt registers, if
+	 * it is not successful exit with the status
+	 */
+	Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	/* reset the IPIF such that it's in a known state before exiting test */
+
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* reaching this point means there were no errors, return success */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* IpIntrSelfTest
+*
+* DESCRIPTION:
+*
+* Perform a self test on the IP interrupt registers of the IPIF. This
+* function modifies registers of the IPIF such that they are not guaranteed
+* to be in the same state when it returns.  Any bits in the IP interrupt
+* status register which are set are assumed to be set by default after a reset
+* and are not tested in the test.
+*
+* ARGUMENTS:
+*
+* InstancePtr points to the XIpIf to operate on.
+*
+* IpRegistersWidth contains the number of bits in the IP interrupt registers
+* of the device.  The hardware is parameterizable such that only the number of
+* bits necessary to support a device are implemented.  This value must be
+* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if the test was successful.  Otherwise, one
+* of the following values is returned.
+*
+*   XST_IPIF_RESET_REGISTER_ERROR       The value of a register at reset was
+*                                       not valid
+*   XST_IPIF_IP_STATUS_ERROR            A write to the IP interrupt status
+*                                       register did not read back correctly
+*   XST_IPIF_IP_ACK_ERROR               One or more bits in the IP status
+*                                       register did not reset when acked
+*   XST_IPIF_IP_ENABLE_ERROR            The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
+{
+	/* ensure that the IP interrupt interrupt enable register is  zero
+	 * as it should be at reset, the interrupt status is dependent upon the
+	 * IP such that it's reset value is not known
+	 */
+	if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+		return XST_IPIF_RESET_REGISTER_ERROR;
+	}
+
+	/* if there are any used IP interrupts, then test all of the interrupt
+	 * bits in all testable registers
+	 */
+	if (IpRegistersWidth > 0) {
+		u32 BitCount;
+		u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
+		u32 Mask = XIIF_V123B_FIRST_BIT_MASK;	/* bits assigned MSB to LSB */
+		u32 InterruptStatus;
+
+		/* generate the register masks to be used for IP register tests, the
+		 * number of bits supported by the hardware is parameterizable such
+		 * that only that number of bits are implemented in the registers, the
+		 * bits are allocated starting at the MSB of the registers
+		 */
+		for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
+			Mask = Mask << 1;
+			IpInterruptMask |= Mask;
+		}
+
+		/* get the current IP interrupt status register contents, any bits
+		 * already set must default to 1 at reset in the device and these
+		 * bits can't be tested in the following test, remove these bits from
+		 * the mask that was generated for the test
+		 */
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		IpInterruptMask &= ~InterruptStatus;
+
+		/* set the bits in the device status register and verify them by reading
+		 * the register again, all bits of the register are latched
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
+		{
+			return XST_IPIF_IP_STATUS_ERROR;
+		}
+
+		/* test to ensure that the bits set in the IP interrupt status register
+		 * can be cleared by acknowledging them in the IP interrupt status
+		 * register then read it again and verify it was cleared
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != 0) {
+			return XST_IPIF_IP_ACK_ERROR;
+		}
+
+		/* set the IP interrupt enable set register and then read the IP
+		 * interrupt enable register and verify the interrupts were enabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+
+		/* clear the IP interrupt enable register and then read the
+		 * IP interrupt enable register and verify the interrupts were disabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+	}
+	return XST_SUCCESS;
+}
diff --git a/board/xilinx/common/xipif_v1_23_b.h b/board/xilinx/common/xipif_v1_23_b.h
index b1520e9..3ce1fff 100644
--- a/board/xilinx/common/xipif_v1_23_b.h
+++ b/board/xilinx/common/xipif_v1_23_b.h
@@ -1,39 +1,22 @@
+/* $Id: xipif_v1_23_b.h,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
 /******************************************************************************
 *
-*     Author: Xilinx, Inc.
+*	XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*	AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*	SOLUTIONS FOR XILINX DEVICES.  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 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.
 *
-*
-*     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.
+*	(c) Copyright 2002 Xilinx Inc.
+*	All rights reserved.
 *
 ******************************************************************************/
 /******************************************************************************
@@ -575,7 +558,7 @@
 *
 * RETURN VALUE:
 *
-* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
+* XTRUE if interrupts are enabled for the IPIF, XFALSE otherwise.
 *
 * NOTES:
 *
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"
-#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
-   TMPFILE = $ {
-   FILE}
+if [ $# -ne 1 ]
+then
+    echo "usage: Ltypes filename" >&2
+    exit 2
+fi
 
-   . ` date "+%s" ` touch $TMPFILE || exit 1
+FILE="$1"
+#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
+TMPFILE=${FILE}.`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
-
-/******************************************************************/
diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c
index a3c37ba..bf8cf0b 100644
--- a/board/xilinx/xilinx_enet/emac_adapter.c
+++ b/board/xilinx/xilinx_enet/emac_adapter.c
@@ -56,8 +56,10 @@
 static XEmac Emac;
 static char etherrxbuff[PKTSIZE_ALIGN];	/* Receive buffer */
 
-/* hardcoded MAC address for the Xilinx EMAC Core */
+/* hardcoded MAC address for the Xilinx EMAC Core when env is nowhere*/
+#ifdef CFG_ENV_IS_NOWHERE
 static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
+#endif
 
 static int initialized = 0;
 
@@ -86,8 +88,11 @@
 	/* make sure the Emac is stopped before it is started */
 	(void) XEmac_Stop(&Emac);
 
+#ifdef CFG_ENV_IS_NOWHERE
 	memcpy(bis->bi_enetaddr, EMACAddr, 6);
-	Result = XEmac_SetMacAddress(&Emac, EMACAddr);
+#endif
+
+	Result = XEmac_SetMacAddress(&Emac, bis->bi_enetaddr);
 	if (Result != XST_SUCCESS) {
 		return 0;
 	}
diff --git a/board/xilinx/xilinx_iic/iic_adapter.c b/board/xilinx/xilinx_iic/iic_adapter.c
new file mode 100644
index 0000000..8ddba6a
--- /dev/null
+++ b/board/xilinx/xilinx_iic/iic_adapter.c
@@ -0,0 +1,529 @@
+/******************************************************************************
+*
+*     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.
+*
+******************************************************************************/
+
+#include <common.h>
+#include <environment.h>
+#include <net.h>
+#include <configs/ml300.h>
+#include "xparameters.h"
+
+#ifdef CFG_ENV_IS_IN_EEPROM
+#include <i2c.h>
+#include "xiic_l.h"
+
+#define IIC_DELAY     5000
+
+static u8 envStep = 0;		/* 0 means crc has not been read */
+const u8 hex[] = "0123456789ABCDEF"; /* lookup table for ML300 CRC */
+
+/************************************************************************
+ * Use Xilinx provided driver to send data to EEPROM using iic bus.
+ */
+static void
+send(u32 adr, u8 * data, u32 len)
+{
+	u8 sendBuf[34];		/* first 2-bit is address and others are data */
+	u32 pos, wlen;
+	u32 ret;
+
+	wlen = 32;
+	for (pos = 0; pos < len; pos += 32) {
+		if ((len - pos) < 32)
+			wlen = len - pos;
+
+		/* Put address and data bits together */
+		sendBuf[0] = (u8) ((adr + pos) >> 8);
+		sendBuf[1] = (u8) (adr + pos);
+		memcpy(&sendBuf[2], &data[pos], wlen);
+
+		/* Send to EEPROM through iic bus */
+		ret = XIic_Send(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1,
+				sendBuf, wlen + 2);
+
+		udelay(IIC_DELAY);
+	}
+}
+
+/************************************************************************
+ * Use Xilinx provided driver to read data from EEPROM using the iic bus.
+ */
+static void
+receive(u32 adr, u8 * data, u32 len)
+{
+	u8 address[2];
+	u32 ret;
+
+	address[0] = (u8) (adr >> 8);
+	address[1] = (u8) adr;
+
+	/* Provide EEPROM address */
+	ret =
+	    XIic_Send(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1, address,
+		      2);
+	/* Receive data from EEPROM */
+	ret =
+	    XIic_Recv(XPAR_IIC_0_BASEADDR, CFG_I2C_EEPROM_ADDR >> 1, data, len);
+}
+
+/************************************************************************
+ * Convert a hexadecimal string to its equivalent integer value.
+ */
+static u8
+axtoi(u8 * hexStg)
+{
+	u8 n;			/* position in string */
+	u8 m;			/* position in digit[] to shift */
+	u8 count;		/* loop index */
+	u8 intValue;		/* integer value of hex string */
+	u8 digit[2];		/* hold values to convert */
+
+	for (n = 0; n < 2; n++) {
+		if (hexStg[n] == '\0')
+			break;
+		if (hexStg[n] > 0x29 && hexStg[n] < 0x40)
+			digit[n] = hexStg[n] & 0x0f;
+		else if (hexStg[n] >= 'a' && hexStg[n] <= 'f')
+			digit[n] = (hexStg[n] & 0x0f) + 9;
+		else if (hexStg[n] >= 'A' && hexStg[n] <= 'F')
+			digit[n] = (hexStg[n] & 0x0f) + 9;
+		else
+			break;
+	}
+
+	intValue = 0;
+	count = n;
+	m = n - 1;
+	n = 0;
+	while (n < count) {
+		intValue = intValue | (digit[n] << (m << 2));
+		m--;		/* adjust the position to set */
+		n++;		/* next digit to process */
+	}
+
+	return (intValue);
+}
+
+/************************************************************************
+ * Convert an integer string to its equivalent value.
+ */
+static u8
+atoi(uchar * string)
+{
+	u8 res = 0;
+	while (*string >= '0' && *string <= '9') {
+		res *= 10;
+		res += *string - '0';
+		string++;
+	}
+
+	return res;
+}
+
+/************************************************************************
+ * Key-value pairs are separated by "=" sign.
+ */
+static void
+findKey(uchar * buffer, int *loc, u8 len)
+{
+	u32 i;
+
+	for (i = 0; i < len; i++)
+		if (buffer[i] == '=') {
+			*loc = i;
+			return;
+		}
+
+	/* return -1 is no "=" sign found */
+	*loc = -1;
+}
+
+/************************************************************************
+ * Compute a new ML300 CRC when user calls the saveenv command.
+ * Also update EEPROM with new CRC value.
+ */
+static u8
+update_crc(u32 len, uchar * data)
+{
+	uchar temp[6] = { 'C', '=', 0x00, 0x00, 0x00, 0x00 };
+	u32 crc;		/* new crc value */
+	u32 i;
+
+	crc = 0;
+
+	/* calculate new CRC */
+	for (i = 0; i < len; i++)
+		crc += data[i];
+
+	/* CRC includes key for check sum */
+	crc += 'C' + '=';
+
+	/* compose new CRC to be updated */
+	temp[2] = hex[(crc >> 4) & 0xf];
+	temp[3] = hex[crc & 0xf];
+
+	/* check to see if env size exceeded */
+	if (len + 6 > ENV_SIZE) {
+		printf("ERROR: not enough space to store CRC on EEPROM");
+		return 1;
+	}
+
+	memcpy(data + len, temp, 6);
+	return 0;
+}
+
+/************************************************************************
+ * Read out ML300 CRC and compare it with a runtime calculated ML300 CRC.
+ * If equal, then pass back a u-boot CRC value, otherwise pass back
+ * junk to indicate CRC error.
+*/
+static void
+read_crc(uchar * buffer, int len)
+{
+	u32 addr, n;
+	u32 crc;		/* runtime crc */
+	u8 old[2] = { 0xff, 0xff };	/* current CRC in EEPROM */
+	u8 stop;		/* indication of end of env data */
+	u8 pre;			/* previous EEPROM data bit */
+	int i, loc;
+
+	addr = CFG_ENV_OFFSET;	/* start from first env address */
+	n = 0;
+	pre = 1;
+	stop = 1;
+	crc = 0;
+
+	/* calculate runtime CRC according to ML300 and read back
+	   old CRC stored in the EEPROM */
+	while (n < CFG_ENV_SIZE) {
+		receive(addr, buffer, len);
+
+		/* found two null chars, end of env */
+		if ((pre || buffer[0]) == 0)
+			break;
+
+		findKey(buffer, &loc, len);
+
+		/* found old check sum, read and store old CRC */
+		if ((loc == 0 && pre == 'C')
+		    || (loc > 0 && buffer[loc - 1] == 'C'))
+			receive(addr + loc + 1, old, 2);
+
+		pre = buffer[len - 1];
+
+		/* calculate runtime ML300 CRC */
+		crc += buffer[0];
+		i = 1;
+		do {
+			crc += buffer[i];
+			stop = buffer[i] || buffer[i - 1];
+			i++;
+		} while (stop && (i < len));
+
+		if (stop == 0)
+			break;
+
+		n += len;
+		addr += len;
+	}
+
+	/* exclude old CRC from runtime calculation */
+	crc -= (old[0] + old[1]);
+
+	/* match CRC values, send back u-boot CRC */
+	if ((old[0] == hex[(crc >> 4) & 0xf])
+	    && (old[1] == hex[crc & 0xf])) {
+		crc = 0;
+		n = 0;
+		addr =
+		    CFG_ENV_OFFSET - offsetof(env_t, crc) + offsetof(env_t,
+								     data);
+		/* calculate u-boot crc */
+		while (n < ENV_SIZE) {
+			receive(addr, buffer, len);
+			crc = crc32(crc, buffer, len);
+			n += len;
+			addr += len;
+		}
+
+		memcpy(buffer, &crc, 4);
+	}
+}
+
+/************************************************************************
+ * Convert IP address to hexadecimals.
+ */
+static void
+ip_ml300(uchar * s, uchar * res)
+{
+	uchar temp[2];
+	u8 i;
+
+	res[0] = 0x00;
+
+	for (i = 0; i < 4; i++) {
+		sprintf(temp, "%02x", atoi(s));
+		s = strchr(s, '.') + 1;
+		strcat(res, temp);
+	}
+}
+
+/************************************************************************
+ * Change 0xff (255), a dummy null char to 0x00.
+ */
+static void
+change_null(uchar * s)
+{
+	if (s != NULL) {
+		change_null(strchr(s + 1, 255));
+		*(strchr(s, 255)) = '\0';
+	}
+}
+
+/************************************************************************
+ * Update environment variable name and values to u-boot standard.
+ */
+void
+convert_env(void)
+{
+	uchar *s;		/* pointer to env value */
+	uchar temp[20];		/* temp storage for addresses */
+
+	/* E -> ethaddr */
+	s = getenv("E");
+	if (s != NULL) {
+		sprintf(temp, "%c%c.%c%c.%c%c.%c%c.%c%c.%c%c",
+			*s++, *s++, *s++, *s++, *s++, *s++,
+			*s++, *s++, *s++, *s++, *s++, *s);
+		setenv("ethaddr", temp);
+		setenv("E", NULL);
+	}
+
+	/* L -> serial# */
+	s = getenv("L");
+	if (s != NULL) {
+		setenv("serial#", s);
+		setenv("L", NULL);
+	}
+
+	/* I -> ipaddr */
+	s = getenv("I");
+	if (s != NULL) {
+		sprintf(temp, "%d.%d.%d.%d", axtoi(s), axtoi(s + 2),
+			axtoi(s + 4), axtoi(s + 6));
+		setenv("ipaddr", temp);
+		setenv("I", NULL);
+	}
+
+	/* S -> serverip */
+	s = getenv("S");
+	if (s != NULL) {
+		sprintf(temp, "%d.%d.%d.%d", axtoi(s), axtoi(s + 2),
+			axtoi(s + 4), axtoi(s + 6));
+		setenv("serverip", temp);
+		setenv("S", NULL);
+	}
+
+	/* A -> bootargs */
+	s = getenv("A");
+	if (s != NULL) {
+		setenv("bootargs", s);
+		setenv("A", NULL);
+	}
+
+	/* F -> bootfile */
+	s = getenv("F");
+	if (s != NULL) {
+		setenv("bootfile", s);
+		setenv("F", NULL);
+	}
+
+	/* M -> bootcmd */
+	s = getenv("M");
+	if (s != NULL) {
+		setenv("bootcmd", s);
+		setenv("M", NULL);
+	}
+
+	/* Don't include C (CRC) */
+	setenv("C", NULL);
+}
+
+/************************************************************************
+ * Save user modified environment values back to EEPROM.
+ */
+static void
+save_env(void)
+{
+	uchar eprom[ENV_SIZE];	/* buffer to be written back to EEPROM */
+	uchar *s, temp[20];
+	uchar ff[] = { 0xff, 0x00 };	/* dummy null value */
+	u32 len;		/* length of env to be written to EEPROM */
+
+	eprom[0] = 0x00;
+
+	/* ethaddr -> E */
+	s = getenv("ethaddr");
+	if (s != NULL) {
+		strcat(eprom, "E=");
+		sprintf(temp, "%c%c%c%c%c%c%c%c%c%c%c%c",
+			*s, *(s + 1), *(s + 3), *(s + 4), *(s + 6), *(s + 7),
+			*(s + 9), *(s + 10), *(s + 12), *(s + 13), *(s + 15),
+			*(s + 16));
+		strcat(eprom, temp);
+		strcat(eprom, ff);
+	}
+
+	/* serial# -> L */
+	s = getenv("serial#");
+	if (s != NULL) {
+		strcat(eprom, "L=");
+		strcat(eprom, s);
+		strcat(eprom, ff);
+	}
+
+	/* ipaddr -> I */
+	s = getenv("ipaddr");
+	if (s != NULL) {
+		strcat(eprom, "I=");
+		ip_ml300(s, temp);
+		strcat(eprom, temp);
+		strcat(eprom, ff);
+	}
+
+	/* serverip -> S */
+	s = getenv("serverip");
+	if (s != NULL) {
+		strcat(eprom, "S=");
+		ip_ml300(s, temp);
+		strcat(eprom, temp);
+		strcat(eprom, ff);
+	}
+
+	/* bootargs -> A */
+	s = getenv("bootargs");
+	if (s != NULL) {
+		strcat(eprom, "A=");
+		strcat(eprom, s);
+		strcat(eprom, ff);
+	}
+
+	/* bootfile -> F */
+	s = getenv("bootfile");
+	if (s != NULL) {
+		strcat(eprom, "F=");
+		strcat(eprom, s);
+		strcat(eprom, ff);
+	}
+
+	/* bootcmd -> M */
+	s = getenv("bootcmd");
+	if (s != NULL) {
+		strcat(eprom, "M=");
+		strcat(eprom, s);
+		strcat(eprom, ff);
+	}
+
+	len = strlen(eprom);	/* find env length without crc */
+	change_null(eprom);	/* change 0xff to 0x00 */
+
+	/* update EEPROM env values if there is enough space */
+	if (update_crc(len, eprom) == 0)
+		send(CFG_ENV_OFFSET, eprom, len + 6);
+}
+
+/************************************************************************
+ * U-boot call for EEPROM read associated activities.
+ */
+int
+i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+
+	if (envStep == 0) {
+		/* first read call is for crc */
+		read_crc(buffer, len);
+		++envStep;
+		return 0;
+	} else if (envStep == 1) {
+		/* then read out EEPROM content for runtime u-boot CRC calculation */
+		receive(addr, buffer, len);
+
+		if (addr + len - CFG_ENV_OFFSET == CFG_ENV_SIZE)
+			/* end of runtime crc read */
+			++envStep;
+		return 0;
+	}
+
+	if (len < 2) {
+		/* when call getenv_r */
+		receive(addr, buffer, len);
+	} else if (addr + len < CFG_ENV_OFFSET + CFG_ENV_SIZE) {
+		/* calling env_relocate(), but don't read out
+		   crc value from EEPROM */
+		receive(addr, buffer + 4, len);
+	} else {
+		receive(addr, buffer + 4, len - 4);
+	}
+
+	return 0;
+
+}
+
+/************************************************************************
+ * U-boot call for EEPROM write acativities.
+ */
+int
+i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+	/* save env on last page write called by u-boot */
+	if (addr + len >= CFG_ENV_OFFSET + CFG_ENV_SIZE)
+		save_env();
+
+	return 0;
+}
+
+/************************************************************************
+ * Dummy function.
+ */
+int
+i2c_probe(uchar chip)
+{
+	return 1;
+}
+
+#endif
diff --git a/board/xilinx/xilinx_iic/xiic_l.c b/board/xilinx/xilinx_iic/xiic_l.c
new file mode 100644
index 0000000..6b78163
--- /dev/null
+++ b/board/xilinx/xilinx_iic/xiic_l.c
@@ -0,0 +1,484 @@
+/* $Id: xiic_l.c,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */
+/******************************************************************************
+*
+*	XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*	AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*	SOLUTIONS FOR XILINX DEVICES.  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 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.
+*
+*	(c) Copyright 2002 Xilinx Inc.
+*	All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic_l.c
+*
+* This file contains low-level driver functions that can be used to access the
+* device.  The user should refer to the hardware device specification for more
+* details of the device operation.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver	Who  Date     Changes
+* ----- --- -------  -----------------------------------------------
+* 1.01b jhl 5/13/02  First release
+* 1.01b jhl 10/14/02 Corrected bug in the receive function, the setup of the
+*		     interrupt status mask was not being done in the loop such
+*		     that a read would sometimes fail on the last byte because
+*		     the transmit error which should have been ignored was
+*		     being used.  This would leave an extra byte in the FIFO
+*		     and the bus throttled such that the next operation would
+*		     also fail.	 Also updated the receive function to not
+*		     disable the device after the last byte until after the
+*		     bus transitions to not busy which is more consistent
+*		     with the expected behavior.
+* 1.01c ecm 12/05/02 new rev
+* </pre>
+*
+****************************************************************************/
+
+/***************************** Include Files *******************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"
+#include "xiic_l.h"
+
+/************************** Constant Definitions ***************************/
+
+/**************************** Type Definitions *****************************/
+
+
+/***************** Macros (Inline Functions) Definitions *******************/
+
+
+/******************************************************************************
+*
+* This macro clears the specified interrupt in the IPIF interrupt status
+* register.  It is non-destructive in that the register is read and only the
+* interrupt specified is cleared.  Clearing an interrupt acknowledges it.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @param    InterruptMask contains the interrupts to be disabled
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mClearIisr(u32 BaseAddress,
+*				  u32 InterruptMask);
+*
+******************************************************************************/
+#define XIic_mClearIisr(BaseAddress, InterruptMask)		    \
+    XIIF_V123B_WRITE_IISR((BaseAddress),			    \
+	XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask))
+
+/******************************************************************************
+*
+* This macro sends the address for a 7 bit address during both read and write
+* operations. It takes care of the details to format the address correctly.
+* This macro is designed to be called internally to the drivers.
+*
+* @param    SlaveAddress contains the address of the slave to send to.
+*
+* @param    Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation);
+*
+******************************************************************************/
+#define XIic_mSend7BitAddress(BaseAddress, SlaveAddress, Operation)	    \
+{									    \
+    u8 LocalAddr = (u8)(SlaveAddress << 1);			    \
+    LocalAddr = (LocalAddr & 0xFE) | (Operation);			    \
+    XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr);		    \
+}
+
+/************************** Function Prototypes ****************************/
+
+static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr,
+			  unsigned ByteCount);
+static unsigned SendData (u32 BaseAddress, u8 * BufferPtr,
+			  unsigned ByteCount);
+
+/************************** Variable Definitions **************************/
+
+
+/****************************************************************************/
+/**
+* Receive data as a master on the IIC bus.  This function receives the data
+* using polled I/O and blocks until the data has been received.	 It only
+* supports 7 bit addressing and non-repeated start modes of operation.	The
+* user is responsible for ensuring the bus is not busy if multiple masters
+* are present on the bus.
+*
+* @param    BaseAddress contains the base address of the IIC device.
+* @param    Address contains the 7 bit IIC address of the device to send the
+*	    specified data to.
+* @param    BufferPtr points to the data to be sent.
+* @param    ByteCount is the number of bytes to be sent.
+*
+* @return
+*
+* The number of bytes received.
+*
+* @note
+*
+* None
+*
+******************************************************************************/
+unsigned XIic_Recv (u32 BaseAddress, u8 Address,
+		    u8 * BufferPtr, unsigned ByteCount)
+{
+	u8 CntlReg;
+	unsigned RemainingByteCount;
+
+	/* Tx error is enabled incase the address (7 or 10) has no device to answer
+	 * with Ack. When only one byte of data, must set NO ACK before address goes
+	 * out therefore Tx error must not be enabled as it will go off immediately
+	 * and the Rx full interrupt will be checked.  If full, then the one byte
+	 * was received and the Tx error will be disabled without sending an error
+	 * callback msg.
+	 */
+	XIic_mClearIisr (BaseAddress,
+			 XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
+			 XIIC_INTR_ARB_LOST_MASK);
+
+	/* Set receive FIFO occupancy depth for 1 byte (zero based)
+	 */
+	XIo_Out8 (BaseAddress + XIIC_RFD_REG_OFFSET, 0);
+
+	/* 7 bit slave address, send the address for a read operation
+	 * and set the state to indicate the address has been sent
+	 */
+	XIic_mSend7BitAddress (BaseAddress, Address, XIIC_READ_OPERATION);
+
+	/* MSMS gets set after putting data in FIFO. Start the master receive
+	 * operation by setting CR Bits MSMS to Master, if the buffer is only one
+	 * byte, then it should not be acknowledged to indicate the end of data
+	 */
+	CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
+	if (ByteCount == 1) {
+		CntlReg |= XIIC_CR_NO_ACK_MASK;
+	}
+
+	/* Write out the control register to start receiving data and call the
+	 * function to receive each byte into the buffer
+	 */
+	XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
+
+	/* Clear the latched interrupt status for the bus not busy bit which must
+	 * be done while the bus is busy
+	 */
+	XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
+
+	/* Try to receive the data from the IIC bus */
+
+	RemainingByteCount = RecvData (BaseAddress, BufferPtr, ByteCount);
+	/*
+	 * The receive is complete, disable the IIC device and return the number of
+	 * bytes that was received
+	 */
+	XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
+
+	/* Return the number of bytes that was received */
+
+	return ByteCount - RemainingByteCount;
+}
+
+/******************************************************************************
+*
+* Receive the specified data from the device that has been previously addressed
+* on the IIC bus.  This function assumes that the 7 bit address has been sent
+* and it should wait for the transmit of the address to complete.
+*
+* @param    BaseAddress contains the base address of the IIC device.
+* @param    BufferPtr points to the buffer to hold the data that is received.
+* @param    ByteCount is the number of bytes to be received.
+*
+* @return
+*
+* The number of bytes remaining to be received.
+*
+* @note
+*
+* This function does not take advantage of the receive FIFO because it is
+* designed for minimal code space and complexity.  It contains loops that
+* that could cause the function not to return if the hardware is not working.
+*
+* This function assumes that the calling function will disable the IIC device
+* after this function returns.
+*
+******************************************************************************/
+static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
+{
+	u8 CntlReg;
+	u32 IntrStatusMask;
+	u32 IntrStatus;
+
+	/* Attempt to receive the specified number of bytes on the IIC bus */
+
+	while (ByteCount > 0) {
+		/* Setup the mask to use for checking errors because when receiving one
+		 * byte OR the last byte of a multibyte message an error naturally
+		 * occurs when the no ack is done to tell the slave the last byte
+		 */
+		if (ByteCount == 1) {
+			IntrStatusMask =
+				XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
+		} else {
+			IntrStatusMask =
+				XIIC_INTR_ARB_LOST_MASK |
+				XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK;
+		}
+
+		/* Wait for the previous transmit and the 1st receive to complete
+		 * by checking the interrupt status register of the IPIF
+		 */
+		while (1) {
+			IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
+			if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
+				break;
+			}
+			/* Check the transmit error after the receive full because when
+			 * sending only one byte transmit error will occur because of the
+			 * no ack to indicate the end of the data
+			 */
+			if (IntrStatus & IntrStatusMask) {
+				return ByteCount;
+			}
+		}
+
+		CntlReg = XIo_In8 (BaseAddress + XIIC_CR_REG_OFFSET);
+
+		/* Special conditions exist for the last two bytes so check for them
+		 * Note that the control register must be setup for these conditions
+		 * before the data byte which was already received is read from the
+		 * receive FIFO (while the bus is throttled
+		 */
+		if (ByteCount == 1) {
+			/* For the last data byte, it has already been read and no ack
+			 * has been done, so clear MSMS while leaving the device enabled
+			 * so it can get off the IIC bus appropriately with a stop.
+			 */
+			XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
+				  XIIC_CR_ENABLE_DEVICE_MASK);
+		}
+
+		/* Before the last byte is received, set NOACK to tell the slave IIC
+		 * device that it is the end, this must be done before reading the byte
+		 * from the FIFO
+		 */
+		if (ByteCount == 2) {
+			/* Write control reg with NO ACK allowing last byte to
+			 * have the No ack set to indicate to slave last byte read.
+			 */
+			XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
+				  CntlReg | XIIC_CR_NO_ACK_MASK);
+		}
+
+		/* Read in data from the FIFO and unthrottle the bus such that the
+		 * next byte is read from the IIC bus
+		 */
+		*BufferPtr++ = XIo_In8 (BaseAddress + XIIC_DRR_REG_OFFSET);
+
+		/* Clear the latched interrupt status so that it will be updated with
+		 * the new state when it changes, this must be done after the receive
+		 * register is read
+		 */
+		XIic_mClearIisr (BaseAddress, XIIC_INTR_RX_FULL_MASK |
+				 XIIC_INTR_TX_ERROR_MASK |
+				 XIIC_INTR_ARB_LOST_MASK);
+		ByteCount--;
+	}
+
+	/* Wait for the bus to transition to not busy before returning, the IIC
+	 * device cannot be disabled until this occurs.	 It should transition as
+	 * the MSMS bit of the control register was cleared before the last byte
+	 * was read from the FIFO.
+	 */
+	while (1) {
+		if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
+			break;
+		}
+	}
+
+	return ByteCount;
+}
+
+/****************************************************************************/
+/**
+* Send data as a master on the IIC bus.	 This function sends the data
+* using polled I/O and blocks until the data has been sent.  It only supports
+* 7 bit addressing and non-repeated start modes of operation.  The user is
+* responsible for ensuring the bus is not busy if multiple masters are present
+* on the bus.
+*
+* @param    BaseAddress contains the base address of the IIC device.
+* @param    Address contains the 7 bit IIC address of the device to send the
+*	    specified data to.
+* @param    BufferPtr points to the data to be sent.
+* @param    ByteCount is the number of bytes to be sent.
+*
+* @return
+*
+* The number of bytes sent.
+*
+* @note
+*
+* None
+*
+******************************************************************************/
+unsigned XIic_Send (u32 BaseAddress, u8 Address,
+		    u8 * BufferPtr, unsigned ByteCount)
+{
+	unsigned RemainingByteCount;
+
+	/* Put the address into the FIFO to be sent and indicate that the operation
+	 * to be performed on the bus is a write operation
+	 */
+	XIic_mSend7BitAddress (BaseAddress, Address, XIIC_WRITE_OPERATION);
+
+	/* Clear the latched interrupt status so that it will be updated with the
+	 * new state when it changes, this must be done after the address is put
+	 * in the FIFO
+	 */
+	XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK |
+			 XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK);
+
+	/* MSMS must be set after putting data into transmit FIFO, indicate the
+	 * direction is transmit, this device is master and enable the IIC device
+	 */
+	XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
+		  XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK |
+		  XIIC_CR_ENABLE_DEVICE_MASK);
+
+	/* Clear the latched interrupt
+	 * status for the bus not busy bit which must be done while the bus is busy
+	 */
+	XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
+
+	/* Send the specified data to the device on the IIC bus specified by the
+	 * the address
+	 */
+	RemainingByteCount = SendData (BaseAddress, BufferPtr, ByteCount);
+
+	/*
+	 * The send is complete, disable the IIC device and return the number of
+	 * bytes that was sent
+	 */
+	XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
+
+	return ByteCount - RemainingByteCount;
+}
+
+/******************************************************************************
+*
+* Send the specified buffer to the device that has been previously addressed
+* on the IIC bus.  This function assumes that the 7 bit address has been sent
+* and it should wait for the transmit of the address to complete.
+*
+* @param    BaseAddress contains the base address of the IIC device.
+* @param    BufferPtr points to the data to be sent.
+* @param    ByteCount is the number of bytes to be sent.
+*
+* @return
+*
+* The number of bytes remaining to be sent.
+*
+* @note
+*
+* This function does not take advantage of the transmit FIFO because it is
+* designed for minimal code space and complexity.  It contains loops that
+* that could cause the function not to return if the hardware is not working.
+*
+******************************************************************************/
+static unsigned SendData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
+{
+	u32 IntrStatus;
+
+	/* Send the specified number of bytes in the specified buffer by polling
+	 * the device registers and blocking until complete
+	 */
+	while (ByteCount > 0) {
+		/* Wait for the transmit to be empty before sending any more data
+		 * by polling the interrupt status register
+		 */
+		while (1) {
+			IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
+
+			if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK |
+					  XIIC_INTR_ARB_LOST_MASK |
+					  XIIC_INTR_BNB_MASK)) {
+				return ByteCount;
+			}
+
+			if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
+				break;
+			}
+		}
+		/* If there is more than one byte to send then put the next byte to send
+		 * into the transmit FIFO
+		 */
+		if (ByteCount > 1) {
+			XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
+				  *BufferPtr++);
+		} else {
+			/* Set the stop condition before sending the last byte of data so that
+			 * the stop condition will be generated immediately following the data
+			 * This is done by clearing the MSMS bit in the control register.
+			 */
+			XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
+				  XIIC_CR_ENABLE_DEVICE_MASK |
+				  XIIC_CR_DIR_IS_TX_MASK);
+
+			/* Put the last byte to send in the transmit FIFO */
+
+			XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
+				  *BufferPtr++);
+		}
+
+		/* Clear the latched interrupt status register and this must be done after
+		 * the transmit FIFO has been written to or it won't clear
+		 */
+		XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK);
+
+		/* Update the byte count to reflect the byte sent and clear the latched
+		 * interrupt status so it will be updated for the new state
+		 */
+		ByteCount--;
+	}
+
+	/* Wait for the bus to transition to not busy before returning, the IIC
+	 * device cannot be disabled until this occurs.
+	 * Note that this is different from a receive operation because the stop
+	 * condition causes the bus to go not busy.
+	 */
+	while (1) {
+		if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
+			break;
+		}
+	}
+
+	return ByteCount;
+}
diff --git a/board/xilinx/xilinx_iic/xiic_l.h b/board/xilinx/xilinx_iic/xiic_l.h
new file mode 100644
index 0000000..a2c4c49
--- /dev/null
+++ b/board/xilinx/xilinx_iic/xiic_l.h
@@ -0,0 +1,150 @@
+/* $Id: xiic_l.h,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */
+/*****************************************************************************
+*
+*	XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*	AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*	SOLUTIONS FOR XILINX DEVICES.  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 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.
+*
+*	(c) Copyright 2002 Xilinx Inc.
+*	All rights reserved.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+*
+* @file xiic_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xiic.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver	Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b jhl  05/07/02 First release
+* 1.01c ecm  12/05/02 new rev
+* </pre>
+*
+*****************************************************************************/
+
+#ifndef XIIC_L_H /* prevent circular inclusions */
+#define XIIC_L_H /* by using protection macros */
+
+/***************************** Include Files ********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions ****************************/
+
+#define XIIC_MSB_OFFSET		       3
+
+#define XIIC_REG_OFFSET 0x100 + XIIC_MSB_OFFSET
+
+/*
+ * Register offsets in bytes from RegisterBase. Three is added to the
+ * base offset to access LSB (IBM style) of the word
+ */
+#define XIIC_CR_REG_OFFSET   0x00+XIIC_REG_OFFSET   /* Control Register	  */
+#define XIIC_SR_REG_OFFSET   0x04+XIIC_REG_OFFSET   /* Status Register	  */
+#define XIIC_DTR_REG_OFFSET  0x08+XIIC_REG_OFFSET   /* Data Tx Register	  */
+#define XIIC_DRR_REG_OFFSET  0x0C+XIIC_REG_OFFSET   /* Data Rx Register	  */
+#define XIIC_ADR_REG_OFFSET  0x10+XIIC_REG_OFFSET   /* Address Register	  */
+#define XIIC_TFO_REG_OFFSET  0x14+XIIC_REG_OFFSET   /* Tx FIFO Occupancy  */
+#define XIIC_RFO_REG_OFFSET  0x18+XIIC_REG_OFFSET   /* Rx FIFO Occupancy  */
+#define XIIC_TBA_REG_OFFSET  0x1C+XIIC_REG_OFFSET   /* 10 Bit Address reg */
+#define XIIC_RFD_REG_OFFSET  0x20+XIIC_REG_OFFSET   /* Rx FIFO Depth reg  */
+
+/* Control Register masks */
+
+#define XIIC_CR_ENABLE_DEVICE_MASK	  0x01	/* Device enable = 1	  */
+#define XIIC_CR_TX_FIFO_RESET_MASK	  0x02	/* Transmit FIFO reset=1  */
+#define XIIC_CR_MSMS_MASK		  0x04	/* Master starts Txing=1  */
+#define XIIC_CR_DIR_IS_TX_MASK		  0x08	/* Dir of tx. Txing=1	  */
+#define XIIC_CR_NO_ACK_MASK		  0x10	/* Tx Ack. NO ack = 1	  */
+#define XIIC_CR_REPEATED_START_MASK	  0x20	/* Repeated start = 1	  */
+#define XIIC_CR_GENERAL_CALL_MASK	  0x40	/* Gen Call enabled = 1	  */
+
+/* Status Register masks */
+
+#define XIIC_SR_GEN_CALL_MASK		  0x01	/* 1=a mstr issued a GC	  */
+#define XIIC_SR_ADDR_AS_SLAVE_MASK	  0x02	/* 1=when addr as slave	  */
+#define XIIC_SR_BUS_BUSY_MASK		  0x04	/* 1 = bus is busy	  */
+#define XIIC_SR_MSTR_RDING_SLAVE_MASK	  0x08	/* 1=Dir: mstr <-- slave  */
+#define XIIC_SR_TX_FIFO_FULL_MASK	  0x10	/* 1 = Tx FIFO full	  */
+#define XIIC_SR_RX_FIFO_FULL_MASK	  0x20	/* 1 = Rx FIFO full	  */
+#define XIIC_SR_RX_FIFO_EMPTY_MASK	  0x40	/* 1 = Rx FIFO empty	  */
+
+/* IPIF Interrupt Status Register masks	   Interrupt occurs when...	  */
+
+#define XIIC_INTR_ARB_LOST_MASK		  0x01	/* 1 = arbitration lost	  */
+#define XIIC_INTR_TX_ERROR_MASK		  0x02	/* 1=Tx error/msg complete*/
+#define XIIC_INTR_TX_EMPTY_MASK		  0x04	/* 1 = Tx FIFO/reg empty  */
+#define XIIC_INTR_RX_FULL_MASK		  0x08	/* 1=Rx FIFO/reg=OCY level*/
+#define XIIC_INTR_BNB_MASK		  0x10	/* 1 = Bus not busy	  */
+#define XIIC_INTR_AAS_MASK		  0x20	/* 1 = when addr as slave */
+#define XIIC_INTR_NAAS_MASK		  0x40	/* 1 = not addr as slave  */
+#define XIIC_INTR_TX_HALF_MASK		  0x80	/* 1 = TX FIFO half empty */
+
+/* IPIF Device Interrupt Register masks */
+
+#define XIIC_IPIF_IIC_MASK	    0x00000004UL    /* 1=inter enabled */
+#define XIIC_IPIF_ERROR_MASK	    0x00000001UL    /* 1=inter enabled */
+#define XIIC_IPIF_INTER_ENABLE_MASK  (XIIC_IPIF_IIC_MASK |  \
+				      XIIC_IPIF_ERROR_MASK)
+
+#define XIIC_TX_ADDR_SENT	      0x00
+#define XIIC_TX_ADDR_MSTR_RECV_MASK   0x02
+
+/* The following constants specify the depth of the FIFOs */
+
+#define IIC_RX_FIFO_DEPTH	  16   /* Rx fifo capacity		 */
+#define IIC_TX_FIFO_DEPTH	  16   /* Tx fifo capacity		 */
+
+/* The following constants specify groups of interrupts that are typically
+ * enabled or disables at the same time
+ */
+#define XIIC_TX_INTERRUPTS					    \
+	    (XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK |    \
+	     XIIC_INTR_TX_HALF_MASK)
+
+#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
+
+/* The following constants are used with the following macros to specify the
+ * operation, a read or write operation.
+ */
+#define XIIC_READ_OPERATION  1
+#define XIIC_WRITE_OPERATION 0
+
+/* The following constants are used with the transmit FIFO fill function to
+ * specify the role which the IIC device is acting as, a master or a slave.
+ */
+#define XIIC_MASTER_ROLE     1
+#define XIIC_SLAVE_ROLE	     0
+
+/**************************** Type Definitions ******************************/
+
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+
+/************************** Function Prototypes *****************************/
+
+unsigned XIic_Recv(u32 BaseAddress, u8 Address,
+		   u8 *BufferPtr, unsigned ByteCount);
+
+unsigned XIic_Send(u32 BaseAddress, u8 Address,
+		   u8 *BufferPtr, unsigned ByteCount);
+
+#endif		  /* end of protection macro */
diff --git a/cpu/ppc4xx/440gx_enet.c b/cpu/ppc4xx/440gx_enet.c
index 54b25a5..1fa84be 100644
--- a/cpu/ppc4xx/440gx_enet.c
+++ b/cpu/ppc4xx/440gx_enet.c
@@ -167,8 +167,6 @@
 	/* EMAC RESET */
 	out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
 
-	hw_p->print_speed = 1;	/* print speed message again next time */
-
 	return;
 }
 
@@ -241,11 +239,9 @@
 		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0);
 		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1);
 		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
-		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3);
 		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
 		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
 		bis->bi_phymode[2] = BI_PHYMODE_RGMII;
-		bis->bi_phymode[3] = BI_PHYMODE_RGMII;
 		break;
 	case 0:
 	default:
@@ -426,8 +422,12 @@
 
 	bis->bi_phynum[devnum] = reg;
 
-	/* Reset the phy */
-	miiphy_reset (reg);
+	/*
+	 * Reset the phy, only if its the first time through
+	 * otherwise, just check the speeds & feeds
+	 */
+	if (hw_p->first_init == 0) {
+		miiphy_reset (reg);
 
 #if defined(CONFIG_440_GX)
 #if defined(CONFIG_CIS8201_PHY)
@@ -456,9 +456,10 @@
 	}
 #endif
 #endif
-	/* Start/Restart autonegotiation */
-	phy_setup_aneg (reg);
-	udelay (1000);
+		/* Start/Restart autonegotiation */
+		phy_setup_aneg (reg);
+		udelay (1000);
+	}
 
 	miiphy_read (reg, PHY_BMSR, &reg_short);
 
@@ -1167,6 +1168,10 @@
 	bis->bi_phymode[2] = 2;
 	bis->bi_phymode[3] = 2;
 
+#if defined (CONFIG_440_GX)
+	ppc_440x_eth_setup_bridge(0, bis);
+#endif
+
 	for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) {
 
 		/* See if we can actually bring up the interface, otherwise, skip it */
diff --git a/include/configs/ml300.h b/include/configs/ml300.h
index d93925e..bcd5c17 100644
--- a/include/configs/ml300.h
+++ b/include/configs/ml300.h
@@ -38,7 +38,7 @@
  *     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.
-  *
+ *
  */
 
 #ifndef __CONFIG_H
@@ -56,9 +56,21 @@
 #define CONFIG_4xx		1	/* ...member of PPC4xx family	*/
 #define CONFIG_XILINX_ML300	1	/* ...on a Xilinx ML300 board	*/
 
-#define CFG_ENV_IS_NOWHERE	1	/* environment is in RAM */
+#define CFG_ENV_IS_IN_EEPROM	1	/* environment is in EEPROM */
+
+/* following are used only if env is in EEPROM */
+#ifdef	CFG_ENV_IS_IN_EEPROM
+#define CFG_I2C_EEPROM_ADDR	XPAR_PERSISTENT_0_IIC_0_EEPROMADDR
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CFG_ENV_OFFSET		XPAR_PERSISTENT_0_IIC_0_BASEADDR
+#define CONFIG_MISC_INIT_R	1	/* used to call out convert_env() */
+#define CONFIG_ENV_OVERWRITE	1	/* allow users to update ethaddr and serial# */
+#endif
+
+#include "../board/xilinx/ml300/xparameters.h"
+
 #define CFG_NO_FLASH		1	/* no flash */
-#define CFG_ENV_SIZE		0x2000
+#define CFG_ENV_SIZE		XPAR_PERSISTENT_0_IIC_0_HIGHADDR - XPAR_PERSISTENT_0_IIC_0_BASEADDR + 1
 #define CONFIG_BAUDRATE		9600
 #define CONFIG_BOOTDELAY	3	/* autoboot after 3 seconds	*/