Merge branch 'master' of git://git.denx.de/u-boot-net
diff --git a/Makefile b/Makefile
index 956eaaa..a40d4cc 100644
--- a/Makefile
+++ b/Makefile
@@ -238,7 +238,7 @@
 LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
 endif
 ifeq ($(CPU),ixp)
-LIBS-y += arch/arm/cpu/ixp/npe/libnpe.o
+LIBS-y += drivers/net/npe/libnpe.o
 endif
 LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
 LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 45e726a..83fa5d7 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -564,6 +564,13 @@
 			break;
 		case BOOTM_STATE_OS_GO:
 			disable_interrupts();
+#ifdef CONFIG_NETCONSOLE
+			/*
+			 * Stop the ethernet stack if NetConsole could have
+			 * left it up
+			 */
+			eth_halt();
+#endif
 			arch_preboot_os();
 			boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
 			break;
@@ -622,6 +629,11 @@
 	 */
 	iflag = disable_interrupts();
 
+#ifdef CONFIG_NETCONSOLE
+	/* Stop the ethernet stack if NetConsole could have left it up */
+	eth_halt();
+#endif
+
 #if defined(CONFIG_CMD_USB)
 	/*
 	 * turn off USB to prevent the host controller from writing to the
@@ -1599,6 +1611,11 @@
 	 */
 	disable_interrupts();
 
+#ifdef CONFIG_NETCONSOLE
+	/* Stop the ethernet stack if NetConsole could have left it up */
+	eth_halt();
+#endif
+
 #if defined(CONFIG_CMD_USB)
 	/*
 	 * turn off USB to prevent the host controller from writing to the
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index 6b31dea..ee75db9 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -450,6 +450,7 @@
 	char *kernel;
 	char *append;
 	char *initrd;
+	char *fdt;
 	int attempted;
 	int localboot;
 	struct list_head list;
@@ -517,6 +518,9 @@
 	if (label->initrd)
 		free(label->initrd);
 
+	if (label->fdt)
+		free(label->fdt);
+
 	free(label);
 }
 
@@ -541,6 +545,9 @@
 
 	if (label->initrd)
 		printf("\t\tinitrd: %s\n", label->initrd);
+
+	if (label->fdt)
+		printf("\tfdt: %s\n", label->fdt);
 }
 
 /*
@@ -628,10 +635,29 @@
 	bootm_argv[1] = getenv("kernel_addr_r");
 
 	/*
-	 * fdt usage is optional.  If there is an fdt_addr specified, we will
-	 * pass it along to bootm, and adjust argc appropriately.
+	 * fdt usage is optional:
+	 * It handles the following scenarios. All scenarios are exclusive
+	 *
+	 * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in
+	 * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm,
+	 * and adjust argc appropriately.
+	 *
+	 * Scenario 2: If there is an fdt_addr specified, pass it along to
+	 * bootm, and adjust argc appropriately.
+	 *
+	 * Scenario 3: fdt blob is not available.
 	 */
-	bootm_argv[3] = getenv("fdt_addr");
+	bootm_argv[3] = getenv("fdt_addr_r");
+
+	/* if fdt label is defined then get fdt from server */
+	if (bootm_argv[3] && label->fdt) {
+		if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) {
+			printf("Skipping %s for failure retrieving fdt\n",
+					label->name);
+			return;
+		}
+	} else
+		bootm_argv[3] = getenv("fdt_addr");
 
 	if (bootm_argv[3])
 		bootm_argc = 4;
@@ -658,6 +684,7 @@
 	T_DEFAULT,
 	T_PROMPT,
 	T_INCLUDE,
+	T_FDT,
 	T_INVALID
 };
 
@@ -685,6 +712,7 @@
 	{"append", T_APPEND},
 	{"initrd", T_INITRD},
 	{"include", T_INCLUDE},
+	{"fdt", T_FDT},
 	{NULL, T_INVALID}
 };
 
@@ -1074,6 +1102,11 @@
 				err = parse_sliteral(c, &label->initrd);
 			break;
 
+		case T_FDT:
+			if (!label->fdt)
+				err = parse_sliteral(c, &label->fdt);
+			break;
+
 		case T_LOCALBOOT:
 			err = parse_integer(c, &label->localboot);
 			break;
diff --git a/doc/README.NetConsole b/doc/README.NetConsole
index c8bcb90..af7fc60 100644
--- a/doc/README.NetConsole
+++ b/doc/README.NetConsole
@@ -6,11 +6,16 @@
 set either of these variables to "nc". Input and output can be
 switched independently.
 
+CONFIG_NETCONSOLE_BUFFER_SIZE - Override the default buffer size
+
 We use an environment variable 'ncip' to set the IP address and the
 port of the destination. The format is <ip_addr>:<port>. If <port> is
 omitted, the value of 6666 is used. If the env var doesn't exist, the
 broadcast address and port 6666 are used. If it is set to an IP
 address of 0 (or 0.0.0.0) then no messages are sent to the network.
+The source / listening port can be configured separately by setting
+the 'ncinport' environment variable and the destination port can be
+configured by setting the 'ncoutport' environment variable.
 
 For example, if your server IP is 192.168.1.1, you could use:
 
diff --git a/doc/README.pxe b/doc/README.pxe
index 2bbf53d..f00f280 100644
--- a/doc/README.pxe
+++ b/doc/README.pxe
@@ -93,8 +93,13 @@
      be passed to the bootm command to boot the kernel. These environment
      variables are required to be set.
 
-     fdt_addr - the location of a fdt blob. If this is set, it will be passed
-     to bootm when booting a kernel.
+     fdt_addr_r - location in RAM at which 'pxe boot' will store the fdt blob it
+     retrieves from tftp. The retrieval is possible if 'fdt' label is defined in
+     pxe file and 'fdt_addr_r' is set. If retrieval is possible, 'fdt_addr_r'
+     will be passed to bootm command to boot the kernel.
+
+     fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm
+     command if it is set and 'fdt_addr_r' is not passed to bootm command.
 
 pxe file format
 ===============
@@ -156,6 +161,11 @@
 		      the initrd_addr_r environment variable, and that address
 		      will be passed to bootm.
 
+fdt <path>	    - if this label is chosen, use tftp to retrieve the fdt blob
+		      at <path>. it will be stored at the address indicated in
+		      the fdt_addr_r environment variable, and that address will
+		      be passed to bootm.
+
 localboot <flag>    - Run the command defined by "localcmd" in the environment.
 		      <flag> is ignored and is only here to match the syntax of
 		      PXELINUX config files.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 011cd51..e4abac7 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -80,6 +80,7 @@
 COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
 		xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
+COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
 
 COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c
index d318a36..ed7cf20 100644
--- a/drivers/net/armada100_fec.c
+++ b/drivers/net/armada100_fec.c
@@ -565,7 +565,7 @@
 	struct tx_desc *p_txdesc = darmdfec->p_txdesc;
 	void *p = (void *)dataptr;
 	int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS;
-	u32 cmd_sts;
+	u32 cmd_sts, temp;
 
 	/* Copy buffer if it's misaligned */
 	if ((u32)dataptr & 0x07) {
@@ -586,7 +586,8 @@
 	p_txdesc->byte_cnt = datasize;
 
 	/* Apply send command using high priority TX queue */
-	writel((u32)p_txdesc, &regs->txcdp[TXQ]);
+	temp = (u32)&regs->txcdp[TXQ];
+	writel((u32)p_txdesc, temp);
 	writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, &regs->sdma_cmd);
 
 	/*
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index fbfc842..3e232c7 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -31,9 +31,16 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
 #include <asm/errno.h>
+#include <linux/compiler.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * Timeout the transfer after 5 mS. This is usually a bit more, since
+ * the code in the tightloops this timeout is used in adds some overhead.
+ */
+#define FEC_XFER_TIMEOUT	5000
+
 #ifndef CONFIG_MII
 #error "CONFIG_MII has to be defined!"
 #endif
@@ -249,7 +256,7 @@
 
 static int fec_rx_task_enable(struct fec_priv *fec)
 {
-	writel(1 << 24, &fec->eth->r_des_active);
+	writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
 	return 0;
 }
 
@@ -260,7 +267,7 @@
 
 static int fec_tx_task_enable(struct fec_priv *fec)
 {
-	writel(1 << 24, &fec->eth->x_des_active);
+	writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
 	return 0;
 }
 
@@ -694,8 +701,10 @@
 static int fec_send(struct eth_device *dev, void *packet, int length)
 {
 	unsigned int status;
-	uint32_t size;
+	uint32_t size, end;
 	uint32_t addr;
+	int timeout = FEC_XFER_TIMEOUT;
+	int ret = 0;
 
 	/*
 	 * This routine transmits one frame.  This routine only accepts
@@ -721,8 +730,9 @@
 #endif
 
 	addr = (uint32_t)packet;
-	size = roundup(length, ARCH_DMA_MINALIGN);
-	flush_dcache_range(addr, addr + size);
+	end = roundup(addr + length, ARCH_DMA_MINALIGN);
+	addr &= ~(ARCH_DMA_MINALIGN - 1);
+	flush_dcache_range(addr, end);
 
 	writew(length, &fec->tbd_base[fec->tbd_index].data_length);
 	writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
@@ -758,22 +768,28 @@
 	 * invalidate data cache to see what's really in RAM. Also, we need
 	 * barrier here.
 	 */
-	invalidate_dcache_range(addr, addr + size);
-	while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
-		udelay(1);
-		invalidate_dcache_range(addr, addr + size);
+	while (--timeout) {
+		if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
+			break;
 	}
 
-	debug("fec_send: status 0x%x index %d\n",
+	if (!timeout)
+		ret = -EINVAL;
+
+	invalidate_dcache_range(addr, addr + size);
+	if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
+		ret = -EINVAL;
+
+	debug("fec_send: status 0x%x index %d ret %i\n",
 			readw(&fec->tbd_base[fec->tbd_index].status),
-			fec->tbd_index);
+			fec->tbd_index, ret);
 	/* for next transmission use the other buffer */
 	if (fec->tbd_index)
 		fec->tbd_index = 0;
 	else
 		fec->tbd_index = 1;
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -789,9 +805,9 @@
 	int frame_length, len = 0;
 	struct nbuf *frame;
 	uint16_t bd_status;
-	uint32_t addr, size;
+	uint32_t addr, size, end;
 	int i;
-	uchar buff[FEC_MAX_PKT_SIZE];
+	uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN);
 
 	/*
 	 * Check if any critical events have happened
@@ -853,8 +869,9 @@
 			 * Invalidate data cache over the buffer
 			 */
 			addr = (uint32_t)frame;
-			size = roundup(frame_length, ARCH_DMA_MINALIGN);
-			invalidate_dcache_range(addr, addr + size);
+			end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
+			addr &= ~(ARCH_DMA_MINALIGN - 1);
+			invalidate_dcache_range(addr, end);
 
 			/*
 			 *  Fill the buffer and pass it to upper layers
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index 852b2e0..203285a 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -213,6 +213,9 @@
 
 #define FEC_X_WMRK_STRFWD		0x00000100
 
+#define FEC_X_DES_ACTIVE_TDAR		0x01000000
+#define FEC_R_DES_ACTIVE_RDAR		0x01000000
+
 #if defined(CONFIG_MX25) || defined(CONFIG_MX53)
 /* defines for MIIGSK */
 /* RMII frequency control: 0=50MHz, 1=5MHz */
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 14243b8..dd7032a 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -28,7 +28,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static char input_buffer[512];
+#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE
+#define CONFIG_NETCONSOLE_BUFFER_SIZE 512
+#endif
+
+static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE];
 static int input_size; /* char count in input buffer */
 static int input_offset; /* offset to valid chars in input buffer */
 static int input_recursion;
@@ -36,9 +40,15 @@
 static int net_timeout;
 static uchar nc_ether[6]; /* server enet address */
 static IPaddr_t nc_ip; /* server ip */
-static short nc_port; /* source/target port */
+static short nc_out_port; /* target output port */
+static short nc_in_port; /* source input port */
 static const char *output_packet; /* used by first send udp */
 static int output_packet_len;
+/*
+ * Start with a default last protocol.
+ * We are only interested in NETCONS or not.
+ */
+enum proto_t net_loop_last_protocol = BOOTP;
 
 static void nc_wait_arp_handler(uchar *pkt, unsigned dest,
 				 IPaddr_t sip, unsigned src,
@@ -59,8 +69,69 @@
 	net_set_state(NETLOOP_SUCCESS);
 }
 
+static int is_broadcast(IPaddr_t ip)
+{
+	static IPaddr_t netmask;
+	static IPaddr_t our_ip;
+	static int env_changed_id;
+	int env_id = get_env_id();
+
+	/* update only when the environment has changed */
+	if (env_changed_id != env_id) {
+		netmask = getenv_IPaddr("netmask");
+		our_ip = getenv_IPaddr("ipaddr");
+
+		env_changed_id = env_id;
+	}
+
+	return (ip == ~0 ||				/* 255.255.255.255 */
+	    ((netmask & our_ip) == (netmask & ip) &&	/* on the same net */
+	    (netmask | ip) == ~0));		/* broadcast to our net */
+}
+
+static int refresh_settings_from_env(void)
+{
+	const char *p;
+	static int env_changed_id;
+	int env_id = get_env_id();
+
+	/* update only when the environment has changed */
+	if (env_changed_id != env_id) {
+		if (getenv("ncip")) {
+			nc_ip = getenv_IPaddr("ncip");
+			if (!nc_ip)
+				return -1;	/* ncip is 0.0.0.0 */
+			p = strchr(getenv("ncip"), ':');
+			if (p != NULL) {
+				nc_out_port = simple_strtoul(p + 1, NULL, 10);
+				nc_in_port = nc_out_port;
+			}
+		} else
+			nc_ip = ~0; /* ncip is not set, so broadcast */
+
+		p = getenv("ncoutport");
+		if (p != NULL)
+			nc_out_port = simple_strtoul(p, NULL, 10);
+		p = getenv("ncinport");
+		if (p != NULL)
+			nc_in_port = simple_strtoul(p, NULL, 10);
+
+		if (is_broadcast(nc_ip))
+			/* broadcast MAC address */
+			memset(nc_ether, 0xff, sizeof(nc_ether));
+		else
+			/* force arp request */
+			memset(nc_ether, 0, sizeof(nc_ether));
+	}
+	return 0;
+}
+
+/**
+ * Called from NetLoop in net/net.c before each packet
+ */
 void NcStart(void)
 {
+	refresh_settings_from_env();
 	if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) {
 		/* going to check for input packet */
 		net_set_udp_handler(nc_handler);
@@ -71,18 +142,22 @@
 		net_set_arp_handler(nc_wait_arp_handler);
 		pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
 		memcpy(pkt, output_packet, output_packet_len);
-		NetSendUDPPacket(nc_ether, nc_ip, nc_port, nc_port,
+		NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port,
 			output_packet_len);
 	}
 }
 
-int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
+int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
+	unsigned src_port, unsigned len)
 {
 	int end, chunk;
 
-	if (dest != nc_port || !len)
+	if (dest_port != nc_in_port || !len)
 		return 0; /* not for us */
 
+	if (src_ip != nc_ip && !is_broadcast(nc_ip))
+		return 0; /* not from our client */
+
 	debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt);
 
 	if (input_size == sizeof(input_buffer))
@@ -131,47 +206,39 @@
 	}
 
 	if (eth->state != ETH_STATE_ACTIVE) {
-		if (eth_init(gd->bd) < 0)
-			return;
+		if (eth_is_on_demand_init()) {
+			if (eth_init(gd->bd) < 0)
+				return;
+			eth_set_last_protocol(NETCONS);
+		} else
+			eth_init_state_only(gd->bd);
+
 		inited = 1;
 	}
 	pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
 	memcpy(pkt, buf, len);
 	ether = nc_ether;
 	ip = nc_ip;
-	NetSendUDPPacket(ether, ip, nc_port, nc_port, len);
+	NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len);
 
-	if (inited)
-		eth_halt();
+	if (inited) {
+		if (eth_is_on_demand_init())
+			eth_halt();
+		else
+			eth_halt_state_only();
+	}
 }
 
 static int nc_start(void)
 {
-	int netmask, our_ip;
+	int retval;
 
-	nc_port = 6666;		/* default port */
+	nc_out_port = 6666; /* default port */
+	nc_in_port = nc_out_port;
 
-	if (getenv("ncip")) {
-		char *p;
-
-		nc_ip = getenv_IPaddr("ncip");
-		if (!nc_ip)
-			return -1;	/* ncip is 0.0.0.0 */
-		p = strchr(getenv("ncip"), ':');
-		if (p != NULL)
-			nc_port = simple_strtoul(p + 1, NULL, 10);
-	} else
-		nc_ip = ~0;		/* ncip is not set */
-
-	our_ip = getenv_IPaddr("ipaddr");
-	netmask = getenv_IPaddr("netmask");
-
-	if (nc_ip == ~0 ||				/* 255.255.255.255 */
-	    ((netmask & our_ip) == (netmask & nc_ip) &&	/* on the same net */
-	    (netmask | nc_ip) == ~0))		/* broadcast to our net */
-		memset(nc_ether, 0xff, sizeof(nc_ether));
-	else
-		memset(nc_ether, 0, sizeof(nc_ether));	/* force arp request */
+	retval = refresh_settings_from_env();
+	if (retval != 0)
+		return retval;
 
 	/*
 	 * Initialize the static IP settings and buffer pointers
@@ -203,7 +270,7 @@
 
 	len = strlen(s);
 	while (len) {
-		int send_len = min(len, 512);
+		int send_len = min(len, sizeof(input_buffer));
 		nc_send_packet(s, send_len);
 		len -= send_len;
 		s += send_len;
diff --git a/arch/arm/cpu/ixp/npe/IxEthAcc.c b/drivers/net/npe/IxEthAcc.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAcc.c
rename to drivers/net/npe/IxEthAcc.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c b/drivers/net/npe/IxEthAccCommon.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAccCommon.c
rename to drivers/net/npe/IxEthAccCommon.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c b/drivers/net/npe/IxEthAccControlInterface.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c
rename to drivers/net/npe/IxEthAccControlInterface.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c b/drivers/net/npe/IxEthAccDataPlane.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c
rename to drivers/net/npe/IxEthAccDataPlane.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMac.c b/drivers/net/npe/IxEthAccMac.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAccMac.c
rename to drivers/net/npe/IxEthAccMac.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMii.c b/drivers/net/npe/IxEthAccMii.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthAccMii.c
rename to drivers/net/npe/IxEthAccMii.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c b/drivers/net/npe/IxEthDBAPI.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBAPI.c
rename to drivers/net/npe/IxEthDBAPI.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c b/drivers/net/npe/IxEthDBAPISupport.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c
rename to drivers/net/npe/IxEthDBAPISupport.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBCore.c b/drivers/net/npe/IxEthDBCore.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBCore.c
rename to drivers/net/npe/IxEthDBCore.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c b/drivers/net/npe/IxEthDBEvents.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBEvents.c
rename to drivers/net/npe/IxEthDBEvents.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c b/drivers/net/npe/IxEthDBFeatures.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBFeatures.c
rename to drivers/net/npe/IxEthDBFeatures.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c b/drivers/net/npe/IxEthDBFirewall.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBFirewall.c
rename to drivers/net/npe/IxEthDBFirewall.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c b/drivers/net/npe/IxEthDBHashtable.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBHashtable.c
rename to drivers/net/npe/IxEthDBHashtable.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c b/drivers/net/npe/IxEthDBLearning.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBLearning.c
rename to drivers/net/npe/IxEthDBLearning.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBMem.c b/drivers/net/npe/IxEthDBMem.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBMem.c
rename to drivers/net/npe/IxEthDBMem.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/drivers/net/npe/IxEthDBNPEAdaptor.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c
rename to drivers/net/npe/IxEthDBNPEAdaptor.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c b/drivers/net/npe/IxEthDBPortUpdate.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c
rename to drivers/net/npe/IxEthDBPortUpdate.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBReports.c b/drivers/net/npe/IxEthDBReports.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBReports.c
rename to drivers/net/npe/IxEthDBReports.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c b/drivers/net/npe/IxEthDBSearch.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBSearch.c
rename to drivers/net/npe/IxEthDBSearch.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c b/drivers/net/npe/IxEthDBSpanningTree.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c
rename to drivers/net/npe/IxEthDBSpanningTree.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c b/drivers/net/npe/IxEthDBUtil.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBUtil.c
rename to drivers/net/npe/IxEthDBUtil.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c b/drivers/net/npe/IxEthDBVlan.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBVlan.c
rename to drivers/net/npe/IxEthDBVlan.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c b/drivers/net/npe/IxEthDBWiFi.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthDBWiFi.c
rename to drivers/net/npe/IxEthDBWiFi.c
diff --git a/arch/arm/cpu/ixp/npe/IxEthMii.c b/drivers/net/npe/IxEthMii.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxEthMii.c
rename to drivers/net/npe/IxEthMii.c
diff --git a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c b/drivers/net/npe/IxFeatureCtrl.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxFeatureCtrl.c
rename to drivers/net/npe/IxFeatureCtrl.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeDl.c b/drivers/net/npe/IxNpeDl.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeDl.c
rename to drivers/net/npe/IxNpeDl.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c b/drivers/net/npe/IxNpeDlImageMgr.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c
rename to drivers/net/npe/IxNpeDlImageMgr.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c b/drivers/net/npe/IxNpeDlNpeMgr.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c
rename to drivers/net/npe/IxNpeDlNpeMgr.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/drivers/net/npe/IxNpeDlNpeMgrUtils.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c
rename to drivers/net/npe/IxNpeDlNpeMgrUtils.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMh.c b/drivers/net/npe/IxNpeMh.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMh.c
rename to drivers/net/npe/IxNpeMh.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c b/drivers/net/npe/IxNpeMhConfig.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMhConfig.c
rename to drivers/net/npe/IxNpeMhConfig.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c b/drivers/net/npe/IxNpeMhReceive.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMhReceive.c
rename to drivers/net/npe/IxNpeMhReceive.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c b/drivers/net/npe/IxNpeMhSend.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMhSend.c
rename to drivers/net/npe/IxNpeMhSend.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/drivers/net/npe/IxNpeMhSolicitedCbMgr.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c
rename to drivers/net/npe/IxNpeMhSolicitedCbMgr.c
diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c
rename to drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c b/drivers/net/npe/IxOsalBufferMgt.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c
rename to drivers/net/npe/IxOsalBufferMgt.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c b/drivers/net/npe/IxOsalIoMem.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalIoMem.c
rename to drivers/net/npe/IxOsalIoMem.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c b/drivers/net/npe/IxOsalOsCacheMMU.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c
rename to drivers/net/npe/IxOsalOsCacheMMU.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c b/drivers/net/npe/IxOsalOsMsgQ.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c
rename to drivers/net/npe/IxOsalOsMsgQ.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c b/drivers/net/npe/IxOsalOsSemaphore.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c
rename to drivers/net/npe/IxOsalOsSemaphore.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c b/drivers/net/npe/IxOsalOsServices.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalOsServices.c
rename to drivers/net/npe/IxOsalOsServices.c
diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c b/drivers/net/npe/IxOsalOsThread.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxOsalOsThread.c
rename to drivers/net/npe/IxOsalOsThread.c
diff --git a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c b/drivers/net/npe/IxQMgrAqmIf.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c
rename to drivers/net/npe/IxQMgrAqmIf.c
diff --git a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c b/drivers/net/npe/IxQMgrDispatcher.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c
rename to drivers/net/npe/IxQMgrDispatcher.c
diff --git a/arch/arm/cpu/ixp/npe/IxQMgrInit.c b/drivers/net/npe/IxQMgrInit.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxQMgrInit.c
rename to drivers/net/npe/IxQMgrInit.c
diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c b/drivers/net/npe/IxQMgrQAccess.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxQMgrQAccess.c
rename to drivers/net/npe/IxQMgrQAccess.c
diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c b/drivers/net/npe/IxQMgrQCfg.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/IxQMgrQCfg.c
rename to drivers/net/npe/IxQMgrQCfg.c
diff --git a/arch/arm/cpu/ixp/npe/Makefile b/drivers/net/npe/Makefile
similarity index 95%
rename from arch/arm/cpu/ixp/npe/Makefile
rename to drivers/net/npe/Makefile
index 14ab3c7..d13391b 100644
--- a/arch/arm/cpu/ixp/npe/Makefile
+++ b/drivers/net/npe/Makefile
@@ -25,7 +25,7 @@
 
 LIB := $(obj)libnpe.o
 
-LOCAL_CFLAGS  += -I$(TOPDIR)/arch/arm/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
+LOCAL_CFLAGS  += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
 CFLAGS  += $(LOCAL_CFLAGS)
 CPPFLAGS  += $(LOCAL_CFLAGS) # needed for depend
 HOSTCFLAGS  += $(LOCAL_CFLAGS)
diff --git a/arch/arm/cpu/ixp/npe/include/IxAssert.h b/drivers/net/npe/include/IxAssert.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAssert.h
rename to drivers/net/npe/include/IxAssert.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h b/drivers/net/npe/include/IxAtmSch.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAtmSch.h
rename to drivers/net/npe/include/IxAtmSch.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h b/drivers/net/npe/include/IxAtmTypes.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAtmTypes.h
rename to drivers/net/npe/include/IxAtmTypes.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h b/drivers/net/npe/include/IxAtmdAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h
rename to drivers/net/npe/include/IxAtmdAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/drivers/net/npe/include/IxAtmdAccCtrl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h
rename to drivers/net/npe/include/IxAtmdAccCtrl.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmm.h b/drivers/net/npe/include/IxAtmm.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxAtmm.h
rename to drivers/net/npe/include/IxAtmm.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h b/drivers/net/npe/include/IxDmaAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxDmaAcc.h
rename to drivers/net/npe/include/IxDmaAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h b/drivers/net/npe/include/IxEthAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAcc.h
rename to drivers/net/npe/include/IxEthAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/drivers/net/npe/include/IxEthAccDataPlane_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h
rename to drivers/net/npe/include/IxEthAccDataPlane_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h b/drivers/net/npe/include/IxEthAccMac_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h
rename to drivers/net/npe/include/IxEthAccMac_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h b/drivers/net/npe/include/IxEthAccMii_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h
rename to drivers/net/npe/include/IxEthAccMii_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/drivers/net/npe/include/IxEthAccQueueAssign_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h
rename to drivers/net/npe/include/IxEthAccQueueAssign_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h b/drivers/net/npe/include/IxEthAcc_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h
rename to drivers/net/npe/include/IxEthAcc_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB.h b/drivers/net/npe/include/IxEthDB.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDB.h
rename to drivers/net/npe/include/IxEthDB.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h b/drivers/net/npe/include/IxEthDBLocks_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h
rename to drivers/net/npe/include/IxEthDBLocks_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h b/drivers/net/npe/include/IxEthDBLog_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h
rename to drivers/net/npe/include/IxEthDBLog_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h b/drivers/net/npe/include/IxEthDBMessages_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h
rename to drivers/net/npe/include/IxEthDBMessages_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h b/drivers/net/npe/include/IxEthDBPortDefs.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h
rename to drivers/net/npe/include/IxEthDBPortDefs.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h b/drivers/net/npe/include/IxEthDBQoS.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h
rename to drivers/net/npe/include/IxEthDBQoS.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h b/drivers/net/npe/include/IxEthDB_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthDB_p.h
rename to drivers/net/npe/include/IxEthDB_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii.h b/drivers/net/npe/include/IxEthMii.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthMii.h
rename to drivers/net/npe/include/IxEthMii.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h b/drivers/net/npe/include/IxEthMii_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthMii_p.h
rename to drivers/net/npe/include/IxEthMii_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h b/drivers/net/npe/include/IxEthNpe.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxEthNpe.h
rename to drivers/net/npe/include/IxEthNpe.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h b/drivers/net/npe/include/IxFeatureCtrl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h
rename to drivers/net/npe/include/IxFeatureCtrl.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h b/drivers/net/npe/include/IxHssAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxHssAcc.h
rename to drivers/net/npe/include/IxHssAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h b/drivers/net/npe/include/IxI2cDrv.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxI2cDrv.h
rename to drivers/net/npe/include/IxI2cDrv.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeA.h b/drivers/net/npe/include/IxNpeA.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeA.h
rename to drivers/net/npe/include/IxNpeA.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDl.h b/drivers/net/npe/include/IxNpeDl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDl.h
rename to drivers/net/npe/include/IxNpeDl.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h b/drivers/net/npe/include/IxNpeDlImageMgr_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h
rename to drivers/net/npe/include/IxNpeDlImageMgr_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h b/drivers/net/npe/include/IxNpeDlMacros_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h
rename to drivers/net/npe/include/IxNpeDlMacros_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h b/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
rename to drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h b/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h
rename to drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h b/drivers/net/npe/include/IxNpeDlNpeMgr_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h
rename to drivers/net/npe/include/IxNpeDlNpeMgr_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMh.h b/drivers/net/npe/include/IxNpeMh.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMh.h
rename to drivers/net/npe/include/IxNpeMh.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h b/drivers/net/npe/include/IxNpeMhConfig_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h
rename to drivers/net/npe/include/IxNpeMhConfig_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h b/drivers/net/npe/include/IxNpeMhMacros_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h
rename to drivers/net/npe/include/IxNpeMhMacros_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h b/drivers/net/npe/include/IxNpeMhReceive_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h
rename to drivers/net/npe/include/IxNpeMhReceive_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h b/drivers/net/npe/include/IxNpeMhSend_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h
rename to drivers/net/npe/include/IxNpeMhSend_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h b/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h
rename to drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h b/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
rename to drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h b/drivers/net/npe/include/IxNpeMicrocode.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h
rename to drivers/net/npe/include/IxNpeMicrocode.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBufLib.h b/drivers/net/npe/include/IxOsBufLib.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsBufLib.h
rename to drivers/net/npe/include/IxOsBufLib.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h b/drivers/net/npe/include/IxOsBuffMgt.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h
rename to drivers/net/npe/include/IxOsBuffMgt.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h b/drivers/net/npe/include/IxOsBuffPoolMgt.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h
rename to drivers/net/npe/include/IxOsBuffPoolMgt.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h b/drivers/net/npe/include/IxOsCacheMMU.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h
rename to drivers/net/npe/include/IxOsCacheMMU.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsPrintf.h b/drivers/net/npe/include/IxOsPrintf.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsPrintf.h
rename to drivers/net/npe/include/IxOsPrintf.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServices.h b/drivers/net/npe/include/IxOsServices.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsServices.h
rename to drivers/net/npe/include/IxOsServices.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesComponents.h b/drivers/net/npe/include/IxOsServicesComponents.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsServicesComponents.h
rename to drivers/net/npe/include/IxOsServicesComponents.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesEndianess.h b/drivers/net/npe/include/IxOsServicesEndianess.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsServicesEndianess.h
rename to drivers/net/npe/include/IxOsServicesEndianess.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemAccess.h b/drivers/net/npe/include/IxOsServicesMemAccess.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsServicesMemAccess.h
rename to drivers/net/npe/include/IxOsServicesMemAccess.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h b/drivers/net/npe/include/IxOsServicesMemMap.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h
rename to drivers/net/npe/include/IxOsServicesMemMap.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsal.h b/drivers/net/npe/include/IxOsal.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsal.h
rename to drivers/net/npe/include/IxOsal.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalAssert.h b/drivers/net/npe/include/IxOsalAssert.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalAssert.h
rename to drivers/net/npe/include/IxOsalAssert.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackward.h b/drivers/net/npe/include/IxOsalBackward.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackward.h
rename to drivers/net/npe/include/IxOsalBackward.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h b/drivers/net/npe/include/IxOsalBackwardAssert.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h
rename to drivers/net/npe/include/IxOsalBackwardAssert.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h b/drivers/net/npe/include/IxOsalBackwardBufferMgt.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h
rename to drivers/net/npe/include/IxOsalBackwardBufferMgt.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h b/drivers/net/npe/include/IxOsalBackwardCacheMMU.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h
rename to drivers/net/npe/include/IxOsalBackwardCacheMMU.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h b/drivers/net/npe/include/IxOsalBackwardMemMap.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h
rename to drivers/net/npe/include/IxOsalBackwardMemMap.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOsServices.h b/drivers/net/npe/include/IxOsalBackwardOsServices.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardOsServices.h
rename to drivers/net/npe/include/IxOsalBackwardOsServices.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h b/drivers/net/npe/include/IxOsalBackwardOssl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h
rename to drivers/net/npe/include/IxOsalBackwardOssl.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h b/drivers/net/npe/include/IxOsalBufferMgt.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h
rename to drivers/net/npe/include/IxOsalBufferMgt.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h b/drivers/net/npe/include/IxOsalBufferMgtDefault.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h
rename to drivers/net/npe/include/IxOsalBufferMgtDefault.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalConfig.h b/drivers/net/npe/include/IxOsalConfig.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalConfig.h
rename to drivers/net/npe/include/IxOsalConfig.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h b/drivers/net/npe/include/IxOsalEndianess.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h
rename to drivers/net/npe/include/IxOsalEndianess.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h b/drivers/net/npe/include/IxOsalIoMem.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h
rename to drivers/net/npe/include/IxOsalIoMem.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h b/drivers/net/npe/include/IxOsalMemAccess.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h
rename to drivers/net/npe/include/IxOsalMemAccess.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOem.h b/drivers/net/npe/include/IxOsalOem.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOem.h
rename to drivers/net/npe/include/IxOsalOem.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOs.h b/drivers/net/npe/include/IxOsalOs.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOs.h
rename to drivers/net/npe/include/IxOsalOs.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h b/drivers/net/npe/include/IxOsalOsAssert.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h
rename to drivers/net/npe/include/IxOsalOsAssert.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h b/drivers/net/npe/include/IxOsalOsBufferMgt.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h
rename to drivers/net/npe/include/IxOsalOsBufferMgt.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h b/drivers/net/npe/include/IxOsalOsIxp400.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h
rename to drivers/net/npe/include/IxOsalOsIxp400.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h b/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h
rename to drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h b/drivers/net/npe/include/IxOsalOsTypes.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h
rename to drivers/net/npe/include/IxOsalOsTypes.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h b/drivers/net/npe/include/IxOsalOsUtilitySymbols.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h
rename to drivers/net/npe/include/IxOsalOsUtilitySymbols.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalTypes.h b/drivers/net/npe/include/IxOsalTypes.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalTypes.h
rename to drivers/net/npe/include/IxOsalTypes.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h b/drivers/net/npe/include/IxOsalUtilitySymbols.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h
rename to drivers/net/npe/include/IxOsalUtilitySymbols.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxParityENAcc.h b/drivers/net/npe/include/IxParityENAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxParityENAcc.h
rename to drivers/net/npe/include/IxParityENAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h b/drivers/net/npe/include/IxPerfProfAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h
rename to drivers/net/npe/include/IxPerfProfAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgr.h b/drivers/net/npe/include/IxQMgr.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgr.h
rename to drivers/net/npe/include/IxQMgr.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h b/drivers/net/npe/include/IxQMgrAqmIf_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h
rename to drivers/net/npe/include/IxQMgrAqmIf_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h b/drivers/net/npe/include/IxQMgrDefines_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h
rename to drivers/net/npe/include/IxQMgrDefines_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h b/drivers/net/npe/include/IxQMgrDispatcher_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h
rename to drivers/net/npe/include/IxQMgrDispatcher_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h b/drivers/net/npe/include/IxQMgrLog_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h
rename to drivers/net/npe/include/IxQMgrLog_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h b/drivers/net/npe/include/IxQMgrQAccess_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h
rename to drivers/net/npe/include/IxQMgrQAccess_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h b/drivers/net/npe/include/IxQMgrQCfg_p.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h
rename to drivers/net/npe/include/IxQMgrQCfg_p.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h b/drivers/net/npe/include/IxQueueAssignments.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h
rename to drivers/net/npe/include/IxQueueAssignments.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxSspAcc.h b/drivers/net/npe/include/IxSspAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxSspAcc.h
rename to drivers/net/npe/include/IxSspAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h b/drivers/net/npe/include/IxTimeSyncAcc.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h
rename to drivers/net/npe/include/IxTimeSyncAcc.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h b/drivers/net/npe/include/IxTimerCtrl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h
rename to drivers/net/npe/include/IxTimerCtrl.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxTypes.h b/drivers/net/npe/include/IxTypes.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxTypes.h
rename to drivers/net/npe/include/IxTypes.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxUART.h b/drivers/net/npe/include/IxUART.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxUART.h
rename to drivers/net/npe/include/IxUART.h
diff --git a/arch/arm/cpu/ixp/npe/include/IxVersionId.h b/drivers/net/npe/include/IxVersionId.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/IxVersionId.h
rename to drivers/net/npe/include/IxVersionId.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_error.h b/drivers/net/npe/include/ix_error.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_error.h
rename to drivers/net/npe/include/ix_error.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_macros.h b/drivers/net/npe/include/ix_macros.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_macros.h
rename to drivers/net/npe/include/ix_macros.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_os_type.h b/drivers/net/npe/include/ix_os_type.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_os_type.h
rename to drivers/net/npe/include/ix_os_type.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_ossl.h b/drivers/net/npe/include/ix_ossl.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_ossl.h
rename to drivers/net/npe/include/ix_ossl.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_symbols.h b/drivers/net/npe/include/ix_symbols.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_symbols.h
rename to drivers/net/npe/include/ix_symbols.h
diff --git a/arch/arm/cpu/ixp/npe/include/ix_types.h b/drivers/net/npe/include/ix_types.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/ix_types.h
rename to drivers/net/npe/include/ix_types.h
diff --git a/arch/arm/cpu/ixp/npe/include/npe.h b/drivers/net/npe/include/npe.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/npe.h
rename to drivers/net/npe/include/npe.h
diff --git a/arch/arm/cpu/ixp/npe/include/os_datatypes.h b/drivers/net/npe/include/os_datatypes.h
similarity index 100%
rename from arch/arm/cpu/ixp/npe/include/os_datatypes.h
rename to drivers/net/npe/include/os_datatypes.h
diff --git a/arch/arm/cpu/ixp/npe/miiphy.c b/drivers/net/npe/miiphy.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/miiphy.c
rename to drivers/net/npe/miiphy.c
diff --git a/arch/arm/cpu/ixp/npe/npe.c b/drivers/net/npe/npe.c
similarity index 100%
rename from arch/arm/cpu/ixp/npe/npe.c
rename to drivers/net/npe/npe.c
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index feced39..5e90d70 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -27,6 +27,7 @@
 
 COBJS-$(CONFIG_BITBANGMII) += miiphybb.o
 COBJS-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o
+COBJS-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o
 
 COBJS-$(CONFIG_PHYLIB) += phy.o
 COBJS-$(CONFIG_PHYLIB_10G) += generic_10g.o
diff --git a/drivers/net/phy/mv88e6352.c b/drivers/net/phy/mv88e6352.c
new file mode 100644
index 0000000..7269a6a
--- /dev/null
+++ b/drivers/net/phy/mv88e6352.c
@@ -0,0 +1,318 @@
+/*
+ * (C) Copyright 2012
+ * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <asm/errno.h>
+#include <mv88e6352.h>
+
+#define SMI_HDR		((0x8 | 0x1) << 12)
+#define SMI_BUSY_MASK	(0x8000)
+#define SMIRD_OP	(0x2 << 10)
+#define SMIWR_OP	(0x1 << 10)
+#define SMI_MASK	0x1f
+#define PORT_SHIFT	5
+
+#define COMMAND_REG	0
+#define DATA_REG	1
+
+/* global registers */
+#define GLOBAL		0x1b
+
+#define GLOBAL_STATUS	0x00
+#define PPU_STATE	0x8000
+
+#define GLOBAL_CTRL	0x04
+#define SW_RESET	0x8000
+#define PPU_ENABLE	0x4000
+
+static int sw_wait_rdy(const char *devname, u8 phy_addr)
+{
+	u16 command;
+	u32 timeout = 100;
+	int ret;
+
+	/* wait till the SMI is not busy */
+	do {
+		/* read command register */
+		ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command);
+		if (ret < 0) {
+			printf("%s: Error reading command register\n",
+				__func__);
+			return ret;
+		}
+		if (timeout-- == 0) {
+			printf("Err..(%s) SMI busy timeout\n", __func__);
+			return -EFAULT;
+		}
+	} while (command & SMI_BUSY_MASK);
+
+	return 0;
+}
+
+static int sw_reg_read(const char *devname, u8 phy_addr, u8 port,
+	u8 reg, u16 *data)
+{
+	int ret;
+	u16 command;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) |
+			(reg & SMI_MASK);
+	debug("%s: write to command: %#x\n", __func__, command);
+	ret = miiphy_write(devname, phy_addr, COMMAND_REG, command);
+	if (ret)
+		return ret;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	ret = miiphy_read(devname, phy_addr, DATA_REG, data);
+
+	return ret;
+}
+
+static int sw_reg_write(const char *devname, u8 phy_addr, u8 port,
+	u8 reg, u16 data)
+{
+	int ret;
+	u16 value;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	debug("%s: write to data: %#x\n", __func__, data);
+	ret = miiphy_write(devname, phy_addr, DATA_REG, data);
+	if (ret)
+		return ret;
+
+	value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) |
+			(reg & SMI_MASK);
+	debug("%s: write to command: %#x\n", __func__, value);
+	ret = miiphy_write(devname, phy_addr, COMMAND_REG, value);
+	if (ret)
+		return ret;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ppu_enable(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg |= PPU_ENABLE;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc000) == 0xc000)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int ppu_disable(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg &= ~PPU_ENABLE;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc000) != 0xc000)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int mv88e_sw_program(const char *devname, u8 phy_addr,
+	struct mv88e_sw_reg *regs, int regs_nb)
+{
+	int i, ret = 0;
+
+	/* first we need to disable the PPU */
+	ret = ppu_disable(devname, phy_addr);
+	if (ret) {
+		printf("%s: Error disabling PPU\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < regs_nb; i++) {
+		ret = sw_reg_write(devname, phy_addr, regs[i].port,
+			regs[i].reg, regs[i].value);
+		if (ret) {
+			printf("%s: Error configuring switch\n", __func__);
+			ppu_enable(devname, phy_addr);
+			return ret;
+		}
+	}
+
+	/* re-enable the PPU */
+	ret = ppu_enable(devname, phy_addr);
+	if (ret) {
+		printf("%s: Error enabling PPU\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+int mv88e_sw_reset(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg = SW_RESET | PPU_ENABLE | 0x0400;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc800) != 0xc800)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int do_mvsw_reg_read(const char *name, int argc, char * const argv[])
+{
+	u16 value = 0, phyaddr, reg, port;
+	int ret;
+
+	phyaddr = simple_strtoul(argv[1], NULL, 10);
+	port = simple_strtoul(argv[2], NULL, 10);
+	reg = simple_strtoul(argv[3], NULL, 10);
+
+	ret = sw_reg_read(name, phyaddr, port, reg, &value);
+	printf("%#x\n", value);
+
+	return ret;
+}
+
+int do_mvsw_reg_write(const char *name, int argc, char * const argv[])
+{
+	u16 value = 0, phyaddr, reg, port;
+	int ret;
+
+	phyaddr = simple_strtoul(argv[1], NULL, 10);
+	port = simple_strtoul(argv[2], NULL, 10);
+	reg = simple_strtoul(argv[3], NULL, 10);
+	value = simple_strtoul(argv[4], NULL, 16);
+
+	ret = sw_reg_write(name, phyaddr, port, reg, value);
+
+	return ret;
+}
+
+
+int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret;
+	const char *cmd, *ethname;
+
+	if (argc < 2)
+		return cmd_usage(cmdtp);
+
+	cmd = argv[1];
+	--argc;
+	++argv;
+
+	if (strcmp(cmd, "read") == 0) {
+		if (argc < 5)
+			return cmd_usage(cmdtp);
+		ethname = argv[1];
+		--argc;
+		++argv;
+		ret = do_mvsw_reg_read(ethname, argc, argv);
+	} else if (strcmp(cmd, "write") == 0) {
+		if (argc < 6)
+			return cmd_usage(cmdtp);
+		ethname = argv[1];
+		--argc;
+		++argv;
+		ret = do_mvsw_reg_write(ethname, argc, argv);
+	} else
+		return cmd_usage(cmdtp);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	mvsw_reg,	7,	1,	do_mvsw_reg,
+	"marvell 88e6352 switch register access",
+	"write ethname phyaddr port reg value\n"
+	"mvsw_reg read  ethname phyaddr port reg\n"
+	);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index d48d4fe..0a0f40d 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -1,6 +1,9 @@
 /*
  * Vitesse PHY drivers
  *
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
+ * Author: Andy Fleming
+ * Add vsc8662 phy support - Priyanka Jain
  * 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
@@ -15,10 +18,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- *
- * Copyright 2010-2011 Freescale Semiconductor, Inc.
- * author Andy Fleming
- *
  */
 #include <miiphy.h>
 
@@ -206,6 +205,16 @@
 	.shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver VSC8662_driver = {
+	.name = "Vitesse VSC8662",
+	.uid = 0x70660,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
 /* Vitesse bought Cicada, so we'll put these here */
 static struct phy_driver cis8201_driver = {
 	.name = "CIS8201",
@@ -235,6 +244,7 @@
 	phy_register(&VSC8244_driver);
 	phy_register(&VSC8211_driver);
 	phy_register(&VSC8221_driver);
+	phy_register(&VSC8662_driver);
 	phy_register(&cis8201_driver);
 	phy_register(&cis8204_driver);
 
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 09af860..2d9cc32 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -394,7 +394,7 @@
 	sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER);
 #endif
 
-#if defined(CONFIG_CPU_SH7734)
+#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740)
 	sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII);
 #endif
 	/* Configure phy */
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 3703c55..61d2df9 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -1,8 +1,8 @@
 /*
  * sh_eth.h - Driver for Renesas SuperH ethernet controler.
  *
- * Copyright (C) 2008, 2011 Renesas Solutions Corp.
- * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu
+ * Copyright (C) 2008 - 2012 Renesas Solutions Corp.
+ * Copyright (c) 2008 - 2012 Nobuhiro Iwamatsu
  * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 
 #define SHETHER_NAME "sh_eth"
 
+#if defined(CONFIG_SH)
 /* Malloc returns addresses in the P1 area (cacheable). However we need to
    use area P2 (non-cacheable) */
 #define ADDR_TO_P2(addr)	((((int)(addr) & ~0xe0000000) | 0xa0000000))
@@ -35,6 +36,12 @@
 #else
 #define ADDR_TO_PHY(addr)	((int)(addr) & ~0xe0000000)
 #endif
+#elif defined(CONFIG_ARM)
+#define inl		readl
+#define outl	writel
+#define ADDR_TO_PHY(addr)	((int)(addr))
+#define ADDR_TO_P2(addr)	(addr)
+#endif /* defined(CONFIG_SH) */
 
 /* Number of supported ports */
 #define MAX_PORT_NUM	2
@@ -292,6 +299,9 @@
 #elif defined(CONFIG_CPU_SH7724)
 #define SH_ETH_TYPE_ETHER
 #define BASE_IO_ADDR	0xA4600000
+#elif defined(CONFIG_R8A7740)
+#define SH_ETH_TYPE_GETHER
+#define BASE_IO_ADDR	0xE9A00000
 #endif
 
 /*
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index d5bd737..d890d60 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -28,6 +28,9 @@
 #include <config.h>
 #include <malloc.h>
 #include <asm/io.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #undef DEBUG
 
@@ -375,3 +378,30 @@
 
 	return 1;
 }
+
+#ifdef CONFIG_OF_CONTROL
+int xilinx_emaclite_init(bd_t *bis)
+{
+	int offset = 0;
+	u32 ret = 0;
+	u32 reg;
+
+	do {
+		offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
+					"xlnx,xps-ethernetlite-1.00.a");
+		if (offset != -1) {
+			reg = fdtdec_get_addr(gd->fdt_blob, offset, "reg");
+			if (reg != FDT_ADDR_T_NONE) {
+				u32 rxpp = fdtdec_get_int(gd->fdt_blob, offset,
+							"xlnx,rx-ping-pong", 0);
+				u32 txpp = fdtdec_get_int(gd->fdt_blob, offset,
+							"xlnx,tx-ping-pong", 0);
+				ret |= xilinx_emaclite_initialize(bis, reg,
+								txpp, rxpp);
+			}
+		}
+	} while (offset != -1);
+
+	return ret;
+}
+#endif
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
new file mode 100644
index 0000000..3596065
--- /dev/null
+++ b/drivers/net/zynq_gem.c
@@ -0,0 +1,440 @@
+/*
+ * (C) Copyright 2011 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * Based on Xilinx gmac driver:
+ * (C) Copyright 2011 Xilinx
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <net.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <phy.h>
+#include <miiphy.h>
+#include <watchdog.h>
+
+#if !defined(CONFIG_PHYLIB)
+# error XILINX_GEM_ETHERNET requires PHYLIB
+#endif
+
+/* Bit/mask specification */
+#define ZYNQ_GEM_PHYMNTNC_OP_MASK	0x40020000 /* operation mask bits */
+#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK	0x20000000 /* read operation */
+#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK	0x10000000 /* write operation */
+#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK	23 /* Shift bits for PHYAD */
+#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK	18 /* Shift bits for PHREG */
+
+#define ZYNQ_GEM_RXBUF_EOF_MASK		0x00008000 /* End of frame. */
+#define ZYNQ_GEM_RXBUF_SOF_MASK		0x00004000 /* Start of frame. */
+#define ZYNQ_GEM_RXBUF_LEN_MASK		0x00003FFF /* Mask for length field */
+
+#define ZYNQ_GEM_RXBUF_WRAP_MASK	0x00000002 /* Wrap bit, last BD */
+#define ZYNQ_GEM_RXBUF_NEW_MASK		0x00000001 /* Used bit.. */
+#define ZYNQ_GEM_RXBUF_ADD_MASK		0xFFFFFFFC /* Mask for address */
+
+/* Wrap bit, last descriptor */
+#define ZYNQ_GEM_TXBUF_WRAP_MASK	0x40000000
+#define ZYNQ_GEM_TXBUF_LAST_MASK	0x00008000 /* Last buffer */
+
+#define ZYNQ_GEM_TXSR_HRESPNOK_MASK	0x00000100 /* Transmit hresp not OK */
+#define ZYNQ_GEM_TXSR_URUN_MASK		0x00000040 /* Transmit underrun */
+/* Transmit buffs exhausted mid frame */
+#define ZYNQ_GEM_TXSR_BUFEXH_MASK	0x00000010
+
+#define ZYNQ_GEM_NWCTRL_TXEN_MASK	0x00000008 /* Enable transmit */
+#define ZYNQ_GEM_NWCTRL_RXEN_MASK	0x00000004 /* Enable receive */
+#define ZYNQ_GEM_NWCTRL_MDEN_MASK	0x00000010 /* Enable MDIO port */
+#define ZYNQ_GEM_NWCTRL_STARTTX_MASK	0x00000200 /* Start tx (tx_go) */
+
+#define ZYNQ_GEM_NWCFG_SPEED		0x00000001 /* 100 Mbps operation */
+#define ZYNQ_GEM_NWCFG_FDEN		0x00000002 /* Full Duplex mode */
+#define ZYNQ_GEM_NWCFG_FSREM		0x00020000 /* FCS removal */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV	0x000080000 /* Div pclk by 32, 80MHz */
+
+#define ZYNQ_GEM_NWCFG_INIT		(ZYNQ_GEM_NWCFG_SPEED | \
+					ZYNQ_GEM_NWCFG_FDEN | \
+					ZYNQ_GEM_NWCFG_FSREM | \
+					ZYNQ_GEM_NWCFG_MDCCLKDIV)
+
+#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK	0x00000004 /* PHY management idle */
+
+#define ZYNQ_GEM_DMACR_BLENGTH		0x00000004 /* INCR4 AHB bursts */
+/* Use full configured addressable space (8 Kb) */
+#define ZYNQ_GEM_DMACR_RXSIZE		0x00000300
+/* Use full configured addressable space (4 Kb) */
+#define ZYNQ_GEM_DMACR_TXSIZE		0x00000400
+/* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
+#define ZYNQ_GEM_DMACR_RXBUF		0x00180000
+
+#define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
+					ZYNQ_GEM_DMACR_RXSIZE | \
+					ZYNQ_GEM_DMACR_TXSIZE | \
+					ZYNQ_GEM_DMACR_RXBUF)
+
+/* Device registers */
+struct zynq_gem_regs {
+	u32 nwctrl; /* Network Control reg */
+	u32 nwcfg; /* Network Config reg */
+	u32 nwsr; /* Network Status reg */
+	u32 reserved1;
+	u32 dmacr; /* DMA Control reg */
+	u32 txsr; /* TX Status reg */
+	u32 rxqbase; /* RX Q Base address reg */
+	u32 txqbase; /* TX Q Base address reg */
+	u32 rxsr; /* RX Status reg */
+	u32 reserved2[2];
+	u32 idr; /* Interrupt Disable reg */
+	u32 reserved3;
+	u32 phymntnc; /* Phy Maintaince reg */
+	u32 reserved4[18];
+	u32 hashl; /* Hash Low address reg */
+	u32 hashh; /* Hash High address reg */
+#define LADDR_LOW	0
+#define LADDR_HIGH	1
+	u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */
+	u32 match[4]; /* Type ID1 Match reg */
+	u32 reserved6[18];
+	u32 stat[44]; /* Octects transmitted Low reg - stat start */
+};
+
+/* BD descriptors */
+struct emac_bd {
+	u32 addr; /* Next descriptor pointer */
+	u32 status;
+};
+
+#define RX_BUF 3
+
+/* Initialized, rxbd_current, rx_first_buf must be 0 after init */
+struct zynq_gem_priv {
+	struct emac_bd tx_bd;
+	struct emac_bd rx_bd[RX_BUF];
+	char rxbuffers[RX_BUF * PKTSIZE_ALIGN];
+	u32 rxbd_current;
+	u32 rx_first_buf;
+	int phyaddr;
+	struct phy_device *phydev;
+	struct mii_dev *bus;
+};
+
+static inline int mdio_wait(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/* Wait till MDIO interface is ready to accept a new transaction. */
+	while (--timeout) {
+		if (readl(&regs->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK)
+			break;
+		WATCHDOG_RESET();
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	return 0;
+}
+
+static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum,
+							u32 op, u16 *data)
+{
+	u32 mgtcr;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	if (mdio_wait(dev))
+		return 1;
+
+	/* Construct mgtcr mask for the operation */
+	mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op |
+		(phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) |
+		(regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data;
+
+	/* Write mgtcr and wait for completion */
+	writel(mgtcr, &regs->phymntnc);
+
+	if (mdio_wait(dev))
+		return 1;
+
+	if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK)
+		*data = readl(&regs->phymntnc);
+
+	return 0;
+}
+
+static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val)
+{
+	return phy_setup_op(dev, phy_addr, regnum,
+				ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val);
+}
+
+static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data)
+{
+	return phy_setup_op(dev, phy_addr, regnum,
+				ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
+}
+
+static int zynq_gem_setup_mac(struct eth_device *dev)
+{
+	u32 i, macaddrlow, macaddrhigh;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	/* Set the MAC bits [31:0] in BOT */
+	macaddrlow = dev->enetaddr[0];
+	macaddrlow |= dev->enetaddr[1] << 8;
+	macaddrlow |= dev->enetaddr[2] << 16;
+	macaddrlow |= dev->enetaddr[3] << 24;
+
+	/* Set MAC bits [47:32] in TOP */
+	macaddrhigh = dev->enetaddr[4];
+	macaddrhigh |= dev->enetaddr[5] << 8;
+
+	for (i = 0; i < 4; i++) {
+		writel(0, &regs->laddr[i][LADDR_LOW]);
+		writel(0, &regs->laddr[i][LADDR_HIGH]);
+		/* Do not use MATCHx register */
+		writel(0, &regs->match[i]);
+	}
+
+	writel(macaddrlow, &regs->laddr[0][LADDR_LOW]);
+	writel(macaddrhigh, &regs->laddr[0][LADDR_HIGH]);
+
+	return 0;
+}
+
+static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
+{
+	u32 i;
+	struct phy_device *phydev;
+	const u32 stat_size = (sizeof(struct zynq_gem_regs) -
+				offsetof(struct zynq_gem_regs, stat)) / 4;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	struct zynq_gem_priv *priv = dev->priv;
+	const u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_1000baseT_Full;
+
+	/* Disable all interrupts */
+	writel(0xFFFFFFFF, &regs->idr);
+
+	/* Disable the receiver & transmitter */
+	writel(0, &regs->nwctrl);
+	writel(0, &regs->txsr);
+	writel(0, &regs->rxsr);
+	writel(0, &regs->phymntnc);
+
+	/* Clear the Hash registers for the mac address pointed by AddressPtr */
+	writel(0x0, &regs->hashl);
+	/* Write bits [63:32] in TOP */
+	writel(0x0, &regs->hashh);
+
+	/* Clear all counters */
+	for (i = 0; i <= stat_size; i++)
+		readl(&regs->stat[i]);
+
+	/* Setup RxBD space */
+	memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
+	/* Create the RxBD ring */
+	memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+
+	for (i = 0; i < RX_BUF; i++) {
+		priv->rx_bd[i].status = 0xF0000000;
+		priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) +
+							(i * PKTSIZE_ALIGN));
+	}
+	/* WRAP bit to last BD */
+	priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+	/* Write RxBDs to IP */
+	writel((u32) &(priv->rx_bd), &regs->rxqbase);
+
+	/* MAC Setup */
+	/* Setup Network Configuration register */
+	writel(ZYNQ_GEM_NWCFG_INIT, &regs->nwcfg);
+
+	/* Setup for DMA Configuration register */
+	writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
+
+	/* Setup for Network Control register, MDIO, Rx and Tx enable */
+	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK |
+			ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK);
+
+	/* interface - look at tsec */
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	phy_config(phydev);
+	phy_startup(phydev);
+
+	return 0;
+}
+
+static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
+{
+	u32 status;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \
+			ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK;
+
+	/* setup BD */
+	writel((u32)&(priv->tx_bd), &regs->txqbase);
+
+	/* Setup Tx BD */
+	memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd));
+
+	priv->tx_bd.addr = (u32)ptr;
+	priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK |
+						ZYNQ_GEM_TXBUF_WRAP_MASK;
+
+	/* Start transmit */
+	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
+
+	/* Read the stat register to know if the packet has been transmitted */
+	status = readl(&regs->txsr);
+	if (status & mask)
+		printf("Something has gone wrong here!? Status is 0x%x.\n",
+		       status);
+
+	/* Clear Tx status register before leaving . */
+	writel(status, &regs->txsr);
+	return 0;
+}
+
+/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
+static int zynq_gem_recv(struct eth_device *dev)
+{
+	int frame_len;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
+	struct emac_bd *first_bd;
+
+	if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK))
+		return 0;
+
+	if (!(current_bd->status &
+			(ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) {
+		printf("GEM: SOF or EOF not set for last buffer received!\n");
+		return 0;
+	}
+
+	frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK;
+	if (frame_len) {
+		NetReceive((u8 *) (current_bd->addr &
+					ZYNQ_GEM_RXBUF_ADD_MASK), frame_len);
+
+		if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK)
+			priv->rx_first_buf = priv->rxbd_current;
+		else {
+			current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
+			current_bd->status = 0xF0000000; /* FIXME */
+		}
+
+		if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) {
+			first_bd = &priv->rx_bd[priv->rx_first_buf];
+			first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
+			first_bd->status = 0xF0000000;
+		}
+
+		if ((++priv->rxbd_current) >= RX_BUF)
+			priv->rxbd_current = 0;
+
+		return frame_len;
+	}
+
+	return 0;
+}
+
+static void zynq_gem_halt(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	/* Disable the receiver & transmitter */
+	writel(0, &regs->nwctrl);
+}
+
+static int zynq_gem_miiphyread(const char *devname, uchar addr,
+							uchar reg, ushort *val)
+{
+	struct eth_device *dev = eth_get_dev();
+	int ret;
+
+	ret = phyread(dev, addr, reg, val);
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val);
+	return ret;
+}
+
+static int zynq_gem_miiphy_write(const char *devname, uchar addr,
+							uchar reg, ushort val)
+{
+	struct eth_device *dev = eth_get_dev();
+
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val);
+	return phywrite(dev, addr, reg, val);
+}
+
+int zynq_gem_initialize(bd_t *bis, int base_addr)
+{
+	struct eth_device *dev;
+	struct zynq_gem_priv *priv;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	dev->priv = calloc(1, sizeof(struct zynq_gem_priv));
+	if (dev->priv == NULL) {
+		free(dev);
+		return -1;
+	}
+	priv = dev->priv;
+
+#ifdef CONFIG_PHY_ADDR
+	priv->phyaddr = CONFIG_PHY_ADDR;
+#else
+	priv->phyaddr = -1;
+#endif
+
+	sprintf(dev->name, "Gem.%x", base_addr);
+
+	dev->iobase = base_addr;
+
+	dev->init = zynq_gem_init;
+	dev->halt = zynq_gem_halt;
+	dev->send = zynq_gem_send;
+	dev->recv = zynq_gem_recv;
+	dev->write_hwaddr = zynq_gem_setup_mac;
+
+	eth_register(dev);
+
+	miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write);
+	priv->bus = miiphy_get_dev_by_name(dev->name);
+
+	return 1;
+}
diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c
index 8fb7fc8..75ec8f7 100644
--- a/drivers/usb/eth/asix.c
+++ b/drivers/usb/eth/asix.c
@@ -23,6 +23,7 @@
 #include <usb.h>
 #include <linux/mii.h>
 #include "usb_ether.h"
+#include <malloc.h>
 
 
 /* ASIX AX8817X based USB 2.0 Ethernet Devices */
@@ -31,10 +32,12 @@
 #define AX_CMD_READ_MII_REG		0x07
 #define AX_CMD_WRITE_MII_REG		0x08
 #define AX_CMD_SET_HW_MII		0x0a
+#define AX_CMD_READ_EEPROM		0x0b
 #define AX_CMD_READ_RX_CTL		0x0f
 #define AX_CMD_WRITE_RX_CTL		0x10
 #define AX_CMD_WRITE_IPG0		0x12
 #define AX_CMD_READ_NODE_ID		0x13
+#define AX_CMD_WRITE_NODE_ID	0x14
 #define AX_CMD_READ_PHY_ID		0x19
 #define AX_CMD_WRITE_MEDIUM_MODE	0x1b
 #define AX_CMD_WRITE_GPIOS		0x1f
@@ -97,9 +100,21 @@
 #define AX_RX_URB_SIZE 2048
 #define PHY_CONNECT_TIMEOUT 5000
 
+/* asix_flags defines */
+#define FLAG_NONE			0
+#define FLAG_TYPE_AX88172	(1U << 0)
+#define FLAG_TYPE_AX88772	(1U << 1)
+#define FLAG_TYPE_AX88772B	(1U << 2)
+#define FLAG_EEPROM_MAC		(1U << 3) /* initial mac address in eeprom */
+
 /* local vars */
 static int curr_eth_dev; /* index for name of next device detected */
 
+/* driver private */
+struct asix_private {
+	int flags;
+};
+
 /*
  * Asix infrastructure commands
  */
@@ -284,6 +299,21 @@
 	return ret;
 }
 
+static int asix_write_hwaddr(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	int ret;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
+
+	memcpy(buf, eth->enetaddr, ETH_ALEN);
+
+	ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf);
+	if (ret < 0)
+		debug("Failed to set MAC address: %02x\n", ret);
+
+	return ret;
+}
+
 /*
  * mii commands
  */
@@ -310,66 +340,87 @@
 	return r;
 }
 
-/*
- * Asix callbacks
- */
-static int asix_init(struct eth_device *eth, bd_t *bd)
+static int asix_read_mac(struct eth_device *eth)
+{
+	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct asix_private *priv = (struct asix_private *)dev->dev_priv;
+	int i;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
+
+	if (priv->flags & FLAG_EEPROM_MAC) {
+		for (i = 0; i < (ETH_ALEN >> 1); i++) {
+			if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
+					  0x04 + i, 0, 2, buf) < 0) {
+				debug("Failed to read SROM address 04h.\n");
+				return -1;
+			}
+			memcpy((eth->enetaddr + i * 2), buf, 2);
+		}
+	} else {
+		if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)
+		     < 0) {
+			debug("Failed to read MAC address.\n");
+			return -1;
+		}
+		memcpy(eth->enetaddr, buf, ETH_ALEN);
+	}
+
+	return 0;
+}
+
+static int asix_basic_reset(struct ueth_data *dev)
 {
 	int embd_phy;
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
 	u16 rx_ctl;
-	struct ueth_data	*dev = (struct ueth_data *)eth->priv;
-	int timeout = 0;
-#define TIMEOUT_RESOLUTION 50	/* ms */
-	int link_detected;
-
-	debug("** %s()\n", __func__);
 
 	if (asix_write_gpio(dev,
 			AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0)
-		goto out_err;
+		return -1;
 
 	/* 0x10 is the phy id of the embedded 10/100 ethernet phy */
 	embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
 	if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
 				embd_phy, 0, 0, NULL) < 0) {
 		debug("Select PHY #1 failed\n");
-		goto out_err;
+		return -1;
 	}
 
 	if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0)
-		goto out_err;
+		return -1;
 
 	if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0)
-		goto out_err;
+		return -1;
 
 	if (embd_phy) {
 		if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0)
-			goto out_err;
+			return -1;
 	} else {
 		if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0)
-			goto out_err;
+			return -1;
 	}
 
 	rx_ctl = asix_read_rx_ctl(dev);
 	debug("RX_CTL is 0x%04x after software reset\n", rx_ctl);
 	if (asix_write_rx_ctl(dev, 0x0000) < 0)
-		goto out_err;
+		return -1;
 
 	rx_ctl = asix_read_rx_ctl(dev);
 	debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 
-	/* Get the MAC address */
-	if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
-				0, 0, ETH_ALEN, buf) < 0) {
-		debug("Failed to read MAC address.\n");
-		goto out_err;
-	}
-	memcpy(eth->enetaddr, buf, ETH_ALEN);
-	debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-		eth->enetaddr[0], eth->enetaddr[1],
-		eth->enetaddr[2], eth->enetaddr[3],
-		eth->enetaddr[4], eth->enetaddr[5]);
+	return 0;
+}
+
+/*
+ * Asix callbacks
+ */
+static int asix_init(struct eth_device *eth, bd_t *bd)
+{
+	struct ueth_data	*dev = (struct ueth_data *)eth->priv;
+	int timeout = 0;
+#define TIMEOUT_RESOLUTION 50	/* ms */
+	int link_detected;
+
+	debug("** %s()\n", __func__);
 
 	dev->phy_id = asix_get_phy_addr(dev);
 	if (dev->phy_id < 0)
@@ -493,13 +544,13 @@
 		}
 		memcpy(&packet_len, buf_ptr, sizeof(packet_len));
 		le32_to_cpus(&packet_len);
-		if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) {
+		if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
 			debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
-			      packet_len, (packet_len >> 16) ^ 0xffff,
-			      packet_len & 0xffff);
+			      packet_len, (~packet_len >> 16) & 0x7ff,
+			      packet_len & 0x7ff);
 			return -1;
 		}
-		packet_len = packet_len & 0xffff;
+		packet_len = packet_len & 0x7ff;
 		if (packet_len > actual_len - sizeof(packet_len)) {
 			debug("Rx: too large packet: %d\n", packet_len);
 			return -1;
@@ -534,19 +585,24 @@
 struct asix_dongle {
 	unsigned short vendor;
 	unsigned short product;
+	int flags;
 };
 
-static struct asix_dongle asix_dongles[] = {
-	{ 0x05ac, 0x1402 },	/* Apple USB Ethernet Adapter */
-	{ 0x07d1, 0x3c05 },	/* D-Link DUB-E100 H/W Ver B1 */
-	{ 0x0b95, 0x772a },	/* Cables-to-Go USB Ethernet Adapter */
-	{ 0x0b95, 0x7720 },	/* Trendnet TU2-ET100 V3.0R */
-	{ 0x0b95, 0x1720 },	/* SMC */
-	{ 0x0db0, 0xa877 },	/* MSI - ASIX 88772a */
-	{ 0x13b1, 0x0018 },	/* Linksys 200M v2.1 */
-	{ 0x1557, 0x7720 },	/* 0Q0 cable ethernet */
-	{ 0x2001, 0x3c05 },	/* DLink DUB-E100 H/W Ver B1 Alternate */
-	{ 0x0000, 0x0000 }	/* END - Do not remove */
+static const struct asix_dongle const asix_dongles[] = {
+	{ 0x05ac, 0x1402, FLAG_TYPE_AX88772 },	/* Apple USB Ethernet Adapter */
+	{ 0x07d1, 0x3c05, FLAG_TYPE_AX88772 },	/* D-Link DUB-E100 H/W Ver B1 */
+	/* Cables-to-Go USB Ethernet Adapter */
+	{ 0x0b95, 0x772a, FLAG_TYPE_AX88772 },
+	{ 0x0b95, 0x7720, FLAG_TYPE_AX88772 },	/* Trendnet TU2-ET100 V3.0R */
+	{ 0x0b95, 0x1720, FLAG_TYPE_AX88172 },	/* SMC */
+	{ 0x0db0, 0xa877, FLAG_TYPE_AX88772 },	/* MSI - ASIX 88772a */
+	{ 0x13b1, 0x0018, FLAG_TYPE_AX88172 },	/* Linksys 200M v2.1 */
+	{ 0x1557, 0x7720, FLAG_TYPE_AX88772 },	/* 0Q0 cable ethernet */
+	/* DLink DUB-E100 H/W Ver B1 Alternate */
+	{ 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
+	/* ASIX 88772B */
+	{ 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+	{ 0x0000, 0x0000, FLAG_NONE }	/* END - Do not remove */
 };
 
 /* Probe to see if a new device is actually an asix device */
@@ -555,6 +611,7 @@
 {
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *iface_desc;
+	int ep_in_found = 0, ep_out_found = 0;
 	int i;
 
 	/* let's examine the device now */
@@ -583,6 +640,13 @@
 	ss->subclass = iface_desc->bInterfaceSubClass;
 	ss->protocol = iface_desc->bInterfaceProtocol;
 
+	/* alloc driver private */
+	ss->dev_priv = calloc(1, sizeof(struct asix_private));
+	if (!ss->dev_priv)
+		return 0;
+
+	((struct asix_private *)ss->dev_priv)->flags = asix_dongles[i].flags;
+
 	/*
 	 * We are expecting a minimum of 3 endpoints - in, out (bulk), and
 	 * int. We will ignore any others.
@@ -591,13 +655,20 @@
 		/* is it an BULK endpoint? */
 		if ((iface->ep_desc[i].bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
-			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
-				ss->ep_in = iface->ep_desc[i].bEndpointAddress &
-					USB_ENDPOINT_NUMBER_MASK;
-			else
-				ss->ep_out =
-					iface->ep_desc[i].bEndpointAddress &
-					USB_ENDPOINT_NUMBER_MASK;
+			u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
+			if (ep_addr & USB_DIR_IN) {
+				if (!ep_in_found) {
+					ss->ep_in = ep_addr &
+						USB_ENDPOINT_NUMBER_MASK;
+					ep_in_found = 1;
+				}
+			} else {
+				if (!ep_out_found) {
+					ss->ep_out = ep_addr &
+						USB_ENDPOINT_NUMBER_MASK;
+					ep_out_found = 1;
+				}
+			}
 		}
 
 		/* is it an interrupt endpoint? */
@@ -624,6 +695,8 @@
 int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
 				struct eth_device *eth)
 {
+	struct asix_private *priv = (struct asix_private *)ss->dev_priv;
+
 	if (!eth) {
 		debug("%s: missing parameter.\n", __func__);
 		return 0;
@@ -633,7 +706,17 @@
 	eth->send = asix_send;
 	eth->recv = asix_recv;
 	eth->halt = asix_halt;
+	if (!(priv->flags & FLAG_TYPE_AX88172))
+		eth->write_hwaddr = asix_write_hwaddr;
 	eth->priv = ss;
 
+	if (asix_basic_reset(ss))
+		return 0;
+
+	/* Get the MAC address */
+	if (asix_read_mac(eth))
+		return 0;
+	debug("MAC %pM\n", eth->enetaddr);
+
 	return 1;
 }
diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index c62a8c1..dc5ca65 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -25,6 +25,7 @@
 #include <usb.h>
 #include <linux/mii.h>
 #include "usb_ether.h"
+#include <malloc.h>
 
 /* SMSC LAN95xx based USB 2.0 Ethernet Devices */
 
@@ -146,6 +147,12 @@
 /* local vars */
 static int curr_eth_dev; /* index for name of next device detected */
 
+/* driver private */
+struct smsc95xx_private {
+	size_t rx_urb_size;  /* maximum USB URB size */
+	u32 mac_cr;  /* MAC control register value */
+	int have_hwaddr;  /* 1 if we have a hardware MAC address */
+};
 
 /*
  * Smsc95xx infrastructure commands
@@ -377,6 +384,7 @@
 static int smsc95xx_write_hwaddr(struct eth_device *eth)
 {
 	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct smsc95xx_private *priv = dev->dev_priv;
 	u32 addr_lo = __get_unaligned_le32(&eth->enetaddr[0]);
 	u32 addr_hi = __get_unaligned_le16(&eth->enetaddr[4]);
 	int ret;
@@ -392,7 +400,7 @@
 		return ret;
 
 	debug("MAC %pM\n", eth->enetaddr);
-	dev->have_hwaddr = 1;
+	priv->have_hwaddr = 1;
 	return 0;
 }
 
@@ -425,19 +433,22 @@
 
 static void smsc95xx_set_multicast(struct ueth_data *dev)
 {
+	struct smsc95xx_private *priv = dev->dev_priv;
+
 	/* No multicast in u-boot */
-	dev->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
+	priv->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
 }
 
 /* starts the TX path */
 static void smsc95xx_start_tx_path(struct ueth_data *dev)
 {
+	struct smsc95xx_private *priv = dev->dev_priv;
 	u32 reg_val;
 
 	/* Enable Tx at MAC */
-	dev->mac_cr |= MAC_CR_TXEN_;
+	priv->mac_cr |= MAC_CR_TXEN_;
 
-	smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr);
+	smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr);
 
 	/* Enable Tx at SCSRs */
 	reg_val = TX_CFG_ON_;
@@ -447,8 +458,10 @@
 /* Starts the Receive path */
 static void smsc95xx_start_rx_path(struct ueth_data *dev)
 {
-	dev->mac_cr |= MAC_CR_RXEN_;
-	smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr);
+	struct smsc95xx_private *priv = dev->dev_priv;
+
+	priv->mac_cr |= MAC_CR_RXEN_;
+	smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr);
 }
 
 /*
@@ -462,6 +475,8 @@
 	u32 burst_cap;
 	int timeout;
 	struct ueth_data *dev = (struct ueth_data *)eth->priv;
+	struct smsc95xx_private *priv =
+		(struct smsc95xx_private *)dev->dev_priv;
 #define TIMEOUT_RESOLUTION 50	/* ms */
 	int link_detected;
 
@@ -504,9 +519,9 @@
 		debug("timeout waiting for PHY Reset\n");
 		return -1;
 	}
-	if (!dev->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0)
-		dev->have_hwaddr = 1;
-	if (!dev->have_hwaddr) {
+	if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0)
+		priv->have_hwaddr = 1;
+	if (!priv->have_hwaddr) {
 		puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n");
 		return -1;
 	}
@@ -532,16 +547,16 @@
 #ifdef TURBO_MODE
 	if (dev->pusb_dev->speed == USB_SPEED_HIGH) {
 		burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
-		dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+		priv->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
 	} else {
 		burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
-		dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+		priv->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
 	}
 #else
 	burst_cap = 0;
-	dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+	priv->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
 #endif
-	debug("rx_urb_size=%ld\n", (ulong)dev->rx_urb_size);
+	debug("rx_urb_size=%ld\n", (ulong)priv->rx_urb_size);
 
 	ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
 	if (ret < 0)
@@ -606,7 +621,7 @@
 	if (ret < 0)
 		return ret;
 
-	ret = smsc95xx_read_reg(dev, MAC_CR, &dev->mac_cr);
+	ret = smsc95xx_read_reg(dev, MAC_CR, &priv->mac_cr);
 	if (ret < 0)
 		return ret;
 
@@ -857,6 +872,12 @@
 		return 0;
 	}
 	dev->privptr = (void *)ss;
+
+	/* alloc driver private */
+	ss->dev_priv = calloc(1, sizeof(struct smsc95xx_private));
+	if (!ss->dev_priv)
+		return 0;
+
 	return 1;
 }
 
diff --git a/include/mv88e6352.h b/include/mv88e6352.h
new file mode 100644
index 0000000..cdc4db7
--- /dev/null
+++ b/include/mv88e6352.h
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2012
+ * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __MV886352_H
+#define __MV886352_H
+
+#include <common.h>
+
+/* PHY registers */
+#define PHY(itf)	(itf)
+
+#define PHY_CTRL	0x00
+#define PHY_100_MBPS	0x2000
+#define PHY_1_GBPS	0x0040
+#define AUTONEG_EN	0x1000
+#define AUTONEG_RST	0x0200
+#define FULL_DUPLEX	0x0100
+#define PHY_PWR_DOWN	0x0800
+
+#define PHY_STATUS	0x01
+#define AN1000FIX	0x0001
+
+#define PHY_SPEC_CTRL	0x10
+#define SPEC_PWR_DOWN	0x0004
+#define AUTO_MDIX_EN	0x0060
+
+#define PHY_1000_CTRL	0x9
+
+#define NO_ADV		0x0000
+#define ADV_1000_FDPX	0x0200
+#define ADV_1000_HDPX	0x0100
+
+#define PHY_PAGE	0x16
+
+#define AN1000FIX_PAGE	0x00fc
+
+/* PORT or MAC registers */
+#define PORT(itf)	(itf+0x10)
+
+#define PORT_STATUS	0x00
+#define NO_PHY_DETECT	0x0000
+
+#define PORT_PHY	0x01
+#define RX_RGMII_TIM	0x8000
+#define TX_RGMII_TIM	0x4000
+#define FLOW_CTRL_EN	0x0080
+#define FLOW_CTRL_FOR	0x0040
+#define LINK_VAL	0x0020
+#define LINK_FOR	0x0010
+#define FULL_DPX	0x0008
+#define FULL_DPX_FOR	0x0004
+#define NO_SPEED_FOR	0x0003
+#define SPEED_1000_FOR	0x0002
+#define SPEED_100_FOR	0x0001
+#define SPEED_10_FOR	0x0000
+
+#define PORT_CTRL	0x04
+#define FORWARDING	0x0003
+#define EGRS_FLD_ALL	0x000c
+#define PORT_DIS	0x0000
+
+struct mv88e_sw_reg {
+	u8 port;
+	u8 reg;
+	u16 value;
+};
+
+int mv88e_sw_reset(const char *devname, u8 phy_addr);
+int mv88e_sw_program(const char *devname, u8 phy_addr,
+	struct mv88e_sw_reg *regs, int regs_nb);
+
+#endif
diff --git a/include/net.h b/include/net.h
index 6d2d6cd..3539336 100644
--- a/include/net.h
+++ b/include/net.h
@@ -102,7 +102,14 @@
 extern int eth_unregister(struct eth_device *dev);/* Remove network device */
 extern void eth_try_another(int first_restart);	/* Change the device */
 extern void eth_set_current(void);		/* set nterface to ethcur var */
-extern struct eth_device *eth_get_dev(void);	/* get the current device MAC */
+/* get the current device MAC */
+static inline __attribute__((always_inline))
+struct eth_device *eth_get_dev(void)
+{
+	extern struct eth_device *eth_current;
+
+	return eth_current;
+}
 extern struct eth_device *eth_get_dev_by_name(const char *devname);
 extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
 extern int eth_get_dev_index(void);		/* get the device index */
@@ -151,6 +158,19 @@
 extern void eth_halt(void);			/* stop SCC */
 extern char *eth_get_name(void);		/* get name of current device */
 
+/* Set active state */
+static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis)
+{
+	eth_get_dev()->state = ETH_STATE_ACTIVE;
+
+	return 0;
+}
+/* Set passive state */
+static inline __attribute__((always_inline)) void eth_halt_state_only(void)
+{
+	eth_get_dev()->state = ETH_STATE_PASSIVE;
+}
+
 /*
  * Set the hardware address for an ethernet interface based on 'eth%daddr'
  * environment variable (or just 'ethaddr' if eth_number is 0).
@@ -529,9 +549,30 @@
 
 #ifdef CONFIG_NETCONSOLE
 void NcStart(void);
-int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
+int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
+	unsigned src_port, unsigned len);
 #endif
 
+static inline __attribute__((always_inline)) int eth_is_on_demand_init(void)
+{
+#ifdef CONFIG_NETCONSOLE
+	extern enum proto_t net_loop_last_protocol;
+
+	return net_loop_last_protocol != NETCONS;
+#else
+	return 1;
+#endif
+}
+
+static inline void eth_set_last_protocol(int protocol)
+{
+#ifdef CONFIG_NETCONSOLE
+	extern enum proto_t net_loop_last_protocol;
+
+	net_loop_last_protocol = protocol;
+#endif
+}
+
 /*
  * Check if autoload is enabled. If so, use either NFS or TFTP to download
  * the boot file.
diff --git a/include/netdev.h b/include/netdev.h
index d1aaf0c..b8d303d 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -104,7 +104,7 @@
 							int txpp, int rxpp);
 int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
 						unsigned long ctrl_addr);
-
+int zynq_gem_initialize(bd_t *bis, int base_addr);
 /*
  * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
  * exported by a public hader file, we need a global definition at this point.
diff --git a/include/usb_ether.h b/include/usb_ether.h
index a7fb26b..7c7aecb 100644
--- a/include/usb_ether.h
+++ b/include/usb_ether.h
@@ -50,12 +50,8 @@
 	unsigned char	protocol;		/* .............. */
 	unsigned char	irqinterval;	/* Intervall for IRQ Pipe */
 
-	/* private fields for each driver can go here if needed */
-#ifdef CONFIG_USB_ETHER_SMSC95XX
-	size_t rx_urb_size;  /* maximum USB URB size */
-	u32 mac_cr;  /* MAC control register value */
-	int have_hwaddr;  /* 1 if we have a hardware MAC address */
-#endif
+	/* driver private */
+	void *dev_priv;
 };
 
 /*
diff --git a/net/bootp.c b/net/bootp.c
index c9b8349..661e371 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -728,6 +728,8 @@
 			memcpy(&NetOurRootPath, popt + 2, size);
 			NetOurRootPath[size] = 0;
 			break;
+		case 28:	/* Ignore Broadcast Address Option */
+			break;
 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
 		case 42:	/* NTP server IP */
 			NetCopyIP(&NetNtpServerIP, (popt + 2));
diff --git a/net/eth.c b/net/eth.c
index 1a11ce1..321d5b1 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -121,12 +121,8 @@
 static unsigned int eth_rcv_current, eth_rcv_last;
 #endif
 
-static struct eth_device *eth_devices, *eth_current;
-
-struct eth_device *eth_get_dev(void)
-{
-	return eth_current;
-}
+static struct eth_device *eth_devices;
+struct eth_device *eth_current;
 
 struct eth_device *eth_get_dev_by_name(const char *devname)
 {
@@ -222,9 +218,12 @@
 	}
 
 	if (dev->write_hwaddr &&
-			!eth_mac_skip(eth_number) &&
-			is_valid_ether_addr(dev->enetaddr))
+			!eth_mac_skip(eth_number)) {
+		if (!is_valid_ether_addr(dev->enetaddr))
+			return -1;
+
 		ret = dev->write_hwaddr(dev);
+	}
 
 	return ret;
 }
@@ -500,10 +499,7 @@
 			return -1;
 	}
 
-	if (length < eth_rcv_bufs[eth_rcv_current].length)
-		return -1;
-
-	length = eth_rcv_bufs[eth_rcv_current].length;
+	length = min(eth_rcv_bufs[eth_rcv_current].length, length);
 
 	for (i = 0; i < length; i++)
 		p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
diff --git a/net/net.c b/net/net.c
index e8ff066..809fb14 100644
--- a/net/net.c
+++ b/net/net.c
@@ -315,12 +315,15 @@
 
 	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
 	net_init();
-	eth_halt();
-	eth_set_current();
-	if (eth_init(bd) < 0) {
+	if (eth_is_on_demand_init() || protocol != NETCONS) {
 		eth_halt();
-		return -1;
-	}
+		eth_set_current();
+		if (eth_init(bd) < 0) {
+			eth_halt();
+			return -1;
+		}
+	} else
+		eth_init_state_only(bd);
 
 restart:
 	net_set_state(NETLOOP_CONTINUE);
@@ -460,6 +463,9 @@
 
 			net_cleanup_loop();
 			eth_halt();
+			/* Invalidate the last protocol */
+			eth_set_last_protocol(BOOTP);
+
 			puts("\nAbort\n");
 			/* include a debug print as well incase the debug
 			   messages are directed to stderr */
@@ -517,13 +523,21 @@
 				sprintf(buf, "%lX", (unsigned long)load_addr);
 				setenv("fileaddr", buf);
 			}
-			eth_halt();
+			if (protocol != NETCONS)
+				eth_halt();
+			else
+				eth_halt_state_only();
+
+			eth_set_last_protocol(protocol);
+
 			ret = NetBootFileXferSize;
 			debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
 			goto done;
 
 		case NETLOOP_FAIL:
 			net_cleanup_loop();
+			/* Invalidate the last protocol */
+			eth_set_last_protocol(BOOTP);
 			debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
 			goto done;
 
@@ -652,7 +666,7 @@
 			"--- NetLoop timeout handler set (%p)\n", f);
 		timeHandler = f;
 		timeStart = get_timer(0);
-		timeDelta = iv;
+		timeDelta = iv * CONFIG_SYS_HZ / 1000;
 	}
 }
 
@@ -1147,6 +1161,7 @@
 
 #ifdef CONFIG_NETCONSOLE
 		nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
+					ntohl(ip->ip_src),
 					ntohs(ip->udp_dst),
 					ntohs(ip->udp_src),
 					ntohs(ip->udp_len) - UDP_HDR_SIZE);
diff --git a/tools/netconsole b/tools/netconsole
index c8109bb..1a0ef22 100755
--- a/tools/netconsole
+++ b/tools/netconsole
@@ -2,7 +2,7 @@
 
 usage() {
 	(
-	echo "Usage: $0 <board IP> [board port]"
+	echo "Usage: $0 <board-IP> [board-port [board-in-port]]"
 	echo ""
 	echo "If port is not specified, '6666' will be used"
 	[ -z "$*" ] && exit 0
@@ -24,9 +24,13 @@
 done
 
 ip=$1
-port=${2:-6666}
+board_out_port=${2:-6666}
+board_in_port=${3:-${board_out_port}}
 
-if [ -z "${ip}" ] || [ -n "$3" ] ; then
+echo Board out port: ${board_out_port}
+echo Board in port: ${board_in_port}
+
+if [ -z "${ip}" ] || [ -n "$4" ] ; then
 	usage "Invalid number of arguments"
 fi
 
@@ -41,19 +45,19 @@
 (
 if type ncb 2>/dev/null ; then
 	# see if ncb is in $PATH
-	exec ncb ${port}
+	exec ncb ${board_out_port}
 
 elif [ -x ${0%/*}/ncb ] ; then
 	# maybe it's in the same dir as the netconsole script
-	exec ${0%/*}/ncb ${port}
+	exec ${0%/*}/ncb ${board_out_port}
 
 else
 	# blah, just use regular netcat
-	while ${nc} -u -l -p ${port} < /dev/null ; do
+	while ${nc} -u -l -p ${board_out_port} < /dev/null ; do
 		:
 	done
 fi
 ) &
 pid=$!
-${nc} -u ${ip} ${port}
+${nc} -u ${ip} ${board_in_port}
 kill ${pid} 2>/dev/null