Merge branch 'master' of git://git.denx.de/u-boot-i2c
diff --git a/Makefile b/Makefile
index aadd1ec..d03504e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 VERSION = 2018
 PATCHLEVEL = 11
 SUBLEVEL =
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME =
 
 # *DOCUMENTATION*
diff --git a/arch/arc/config.mk b/arch/arc/config.mk
index d255c90..18005d9 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -43,7 +43,7 @@
 endif
 
 PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 -mno-sdata
-PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
+PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -fno-common
 
 # Needed for relocation
 LDFLAGS_FINAL += -pie --gc-sections
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c
index 50cd7cd..a969a16 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -60,7 +60,7 @@
 	}
 }
 
-int print_cpuinfo(void)
+__weak int print_cpuinfo(void)
 {
 	printf("CPU:   %s\n", decode_identity());
 	return 0;
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c
index 6b94cf3..5da90a2 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c
@@ -299,6 +299,8 @@
 
 	/* Put all DRAM-related blocks to reset state */
 	clrbits_le32(&ccm->mbus_cfg, MBUS_ENABLE | MBUS_RESET);
+	clrbits_le32(&ccm->dram_gate_reset, BIT(0));
+	udelay(5);
 	writel(0, &ccm->dram_gate_reset);
 	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
 	clrbits_le32(&ccm->dram_clk_cfg, DRAM_MOD_RESET);
@@ -313,7 +315,9 @@
 	/* Configure DRAM mod clock */
 	writel(DRAM_CLK_SRC_PLL5, &ccm->dram_clk_cfg);
 	setbits_le32(&ccm->dram_clk_cfg, DRAM_CLK_UPDATE);
-	writel(BIT(0) | BIT(RESET_SHIFT), &ccm->dram_gate_reset);
+	writel(BIT(RESET_SHIFT), &ccm->dram_gate_reset);
+	udelay(5);
+	setbits_le32(&ccm->dram_gate_reset, BIT(0));
 
 	/* Disable all channels */
 	writel(0, &mctl_com->maer0);
diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h
index bfcd11b..477fa00 100644
--- a/arch/sandbox/include/asm/eth.h
+++ b/arch/sandbox/include/asm/eth.h
@@ -13,4 +13,97 @@
 
 void sandbox_eth_skip_timeout(void);
 
+/*
+ * sandbox_eth_arp_req_to_reply()
+ *
+ * Check for an arp request to be sent. If so, inject a reply
+ *
+ * @dev: device that received the packet
+ * @packet: pointer to the received pacaket buffer
+ * @len: length of received packet
+ * @return 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
+				 unsigned int len);
+
+/*
+ * sandbox_eth_ping_req_to_reply()
+ *
+ * Check for a ping request to be sent. If so, inject a reply
+ *
+ * @dev: device that received the packet
+ * @packet: pointer to the received pacaket buffer
+ * @len: length of received packet
+ * @return 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
+				  unsigned int len);
+
+/*
+ * sandbox_eth_recv_arp_req()
+ *
+ * Inject an ARP request for this target
+ *
+ * @dev: device that received the packet
+ * @return 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_arp_req(struct udevice *dev);
+
+/*
+ * sandbox_eth_recv_ping_req()
+ *
+ * Inject a ping request for this target
+ *
+ * @dev: device that received the packet
+ * @return 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_ping_req(struct udevice *dev);
+
+/**
+ * A packet handler
+ *
+ * dev - device pointer
+ * pkt - pointer to the "sent" packet
+ * len - packet length
+ */
+typedef int sandbox_eth_tx_hand_f(struct udevice *dev, void *pkt,
+				   unsigned int len);
+
+/**
+ * struct eth_sandbox_priv - memory for sandbox mock driver
+ *
+ * fake_host_hwaddr - MAC address of mocked machine
+ * fake_host_ipaddr - IP address of mocked machine
+ * disabled - Will not respond
+ * recv_packet_buffer - buffers of the packet returned as received
+ * recv_packet_length - lengths of the packet returned as received
+ * recv_packets - number of packets returned
+ * tx_handler - function to generate responses to sent packets
+ * priv - a pointer to some structure a test may want to keep track of
+ */
+struct eth_sandbox_priv {
+	uchar fake_host_hwaddr[ARP_HLEN];
+	struct in_addr fake_host_ipaddr;
+	bool disabled;
+	uchar * recv_packet_buffer[PKTBUFSRX];
+	int recv_packet_length[PKTBUFSRX];
+	int recv_packets;
+	sandbox_eth_tx_hand_f *tx_handler;
+	void *priv;
+};
+
+/*
+ * Set packet handler
+ *
+ * handler - The func ptr to call on send. If NULL, set to default handler
+ */
+void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler);
+
+/*
+ * Set priv ptr
+ *
+ * priv - priv void ptr to store in the device
+ */
+void sandbox_eth_set_priv(int index, void *priv);
+
 #endif /* __ETH_H */
diff --git a/board/Synology/ds414/cmd_syno.c b/board/Synology/ds414/cmd_syno.c
index 34643ff..59e6fe0 100644
--- a/board/Synology/ds414/cmd_syno.c
+++ b/board/Synology/ds414/cmd_syno.c
@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include "../drivers/ddr/marvell/axp/ddr3_init.h"
 
-#define ETH_ALEN		6
 #define ETHADDR_MAX		4
 #define SYNO_SN_TAG		"SN="
 #define SYNO_CHKSUM_TAG		"CHK="
diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index e8ec553..b0b29b3 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -49,6 +49,33 @@
 
 #define CFG_MAC_ADDR_OFFSET	(flash->size - SZ_64K)
 
+#ifdef CONFIG_SPL_BUILD
+#include <ns16550.h>
+#include <dm/platform_data/spi_davinci.h>
+
+static const struct ns16550_platdata da850evm_serial = {
+	.base = DAVINCI_UART2_BASE,
+	.reg_shift = 2,
+	.clock = 150000000,
+	.fcr = UART_FCR_DEFVAL,
+};
+
+U_BOOT_DEVICE(da850evm_uart) = {
+	.name = "ns16550_serial",
+	.platdata = &da850evm_serial,
+};
+
+static const struct davinci_spi_platdata davinci_spi_data = {
+        .regs = (struct davinci_spi_regs *)0x01f0e000,
+        .num_cs = 4,
+};
+
+U_BOOT_DEVICE(davinci_spi) = {
+        .name = "davinci_spi",
+        .platdata = &davinci_spi_data,
+};
+#endif
+
 #ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
 static int get_mac_addr(u8 *addr)
 {
diff --git a/board/freescale/ls1088a/eth_ls1088aqds.c b/board/freescale/ls1088a/eth_ls1088aqds.c
index 40b1a0e..f16b78c 100644
--- a/board/freescale/ls1088a/eth_ls1088aqds.c
+++ b/board/freescale/ls1088a/eth_ls1088aqds.c
@@ -487,16 +487,16 @@
 	case 0x3A:
 		switch (dpmac_id) {
 		case 1:
-			wriop_set_phy_address(dpmac_id, riser_phy_addr[1]);
+			wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[1]);
 			break;
 		case 2:
-			wriop_set_phy_address(dpmac_id, riser_phy_addr[0]);
+			wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[0]);
 			break;
 		case 3:
-			wriop_set_phy_address(dpmac_id, riser_phy_addr[3]);
+			wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[3]);
 			break;
 		case 7:
-			wriop_set_phy_address(dpmac_id, riser_phy_addr[2]);
+			wriop_set_phy_address(dpmac_id, 0, riser_phy_addr[2]);
 			break;
 		default:
 			printf("WRIOP: Wrong DPMAC%d set to SGMII", dpmac_id);
@@ -532,13 +532,13 @@
 		case 4:
 		case 5:
 		case 6:
-			wriop_set_phy_address(dpmac_id, dpmac_id + 9);
+			wriop_set_phy_address(dpmac_id, 0, dpmac_id + 9);
 			break;
 		case 7:
 		case 8:
 		case 9:
 		case 10:
-			wriop_set_phy_address(dpmac_id, dpmac_id + 1);
+			wriop_set_phy_address(dpmac_id, 0, dpmac_id + 1);
 			break;
 		}
 
@@ -567,7 +567,7 @@
 	case 0x15:
 	case 0x1D:
 	case 0x1E:
-		wriop_set_phy_address(i, i + 26);
+		wriop_set_phy_address(i, 0, i + 26);
 		ls1088a_qds_enable_SFP_TX(SFP_TX);
 		break;
 	default:
@@ -590,13 +590,13 @@
 
 	switch (dpmac_id) {
 	case 4:
-		wriop_set_phy_address(dpmac_id, RGMII_PHY1_ADDR);
+		wriop_set_phy_address(dpmac_id, 0, RGMII_PHY1_ADDR);
 		dpmac_info[dpmac_id].board_mux = EMI1_RGMII1;
 		bus = mii_dev_for_muxval(EMI1_RGMII1);
 		wriop_set_mdio(dpmac_id, bus);
 		break;
 	case 5:
-		wriop_set_phy_address(dpmac_id, RGMII_PHY2_ADDR);
+		wriop_set_phy_address(dpmac_id, 0, RGMII_PHY2_ADDR);
 		dpmac_info[dpmac_id].board_mux = EMI1_RGMII2;
 		bus = mii_dev_for_muxval(EMI1_RGMII2);
 		wriop_set_mdio(dpmac_id, bus);
diff --git a/board/freescale/ls1088a/eth_ls1088ardb.c b/board/freescale/ls1088a/eth_ls1088ardb.c
index 418f362..a2b52a8 100644
--- a/board/freescale/ls1088a/eth_ls1088ardb.c
+++ b/board/freescale/ls1088a/eth_ls1088ardb.c
@@ -55,16 +55,17 @@
 		 * a MAC has no PHY address, we give a PHY address to XFI
 		 * MAC error.
 		 */
-		wriop_set_phy_address(WRIOP1_DPMAC1, 0x0a);
-		wriop_set_phy_address(WRIOP1_DPMAC2, AQ_PHY_ADDR1);
-		wriop_set_phy_address(WRIOP1_DPMAC3, QSGMII1_PORT1_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC4, QSGMII1_PORT2_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC5, QSGMII1_PORT3_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC6, QSGMII1_PORT4_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC7, QSGMII2_PORT1_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC8, QSGMII2_PORT2_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC9, QSGMII2_PORT3_PHY_ADDR);
-		wriop_set_phy_address(WRIOP1_DPMAC10, QSGMII2_PORT4_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC1, 0, 0x0a);
+		wriop_set_phy_address(WRIOP1_DPMAC2, 0, AQ_PHY_ADDR1);
+		wriop_set_phy_address(WRIOP1_DPMAC3, 0, QSGMII1_PORT1_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC4, 0, QSGMII1_PORT2_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC5, 0, QSGMII1_PORT3_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC6, 0, QSGMII1_PORT4_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC7, 0, QSGMII2_PORT1_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC8, 0, QSGMII2_PORT2_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC9, 0, QSGMII2_PORT3_PHY_ADDR);
+		wriop_set_phy_address(WRIOP1_DPMAC10, 0,
+				      QSGMII2_PORT4_PHY_ADDR);
 
 		break;
 	default:
diff --git a/board/freescale/ls2080aqds/eth.c b/board/freescale/ls2080aqds/eth.c
index 989d57e..f706fd4 100644
--- a/board/freescale/ls2080aqds/eth.c
+++ b/board/freescale/ls2080aqds/eth.c
@@ -623,7 +623,7 @@
 		switch (++slot) {
 		case 1:
 			/* Slot housing a SGMII riser card? */
-			wriop_set_phy_address(dpmac_id,
+			wriop_set_phy_address(dpmac_id, 0,
 					      riser_phy_addr[dpmac_id - 1]);
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
 			bus = mii_dev_for_muxval(EMI1_SLOT1);
@@ -631,7 +631,7 @@
 			break;
 		case 2:
 			/* Slot housing a SGMII riser card? */
-			wriop_set_phy_address(dpmac_id,
+			wriop_set_phy_address(dpmac_id, 0,
 					      riser_phy_addr[dpmac_id - 1]);
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
 			bus = mii_dev_for_muxval(EMI1_SLOT2);
@@ -641,18 +641,18 @@
 			if (slot == EMI_NONE)
 				return;
 			if (serdes1_prtcl == 0x39) {
-				wriop_set_phy_address(dpmac_id,
+				wriop_set_phy_address(dpmac_id, 0,
 					riser_phy_addr[dpmac_id - 2]);
 				if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
 								env_hwconfig))
-					wriop_set_phy_address(dpmac_id,
+					wriop_set_phy_address(dpmac_id, 0,
 						riser_phy_addr[dpmac_id - 3]);
 			} else {
-				wriop_set_phy_address(dpmac_id,
+				wriop_set_phy_address(dpmac_id, 0,
 					riser_phy_addr[dpmac_id - 2]);
 				if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
 								env_hwconfig))
-					wriop_set_phy_address(dpmac_id,
+					wriop_set_phy_address(dpmac_id, 0,
 						riser_phy_addr[dpmac_id - 3]);
 			}
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
@@ -691,7 +691,7 @@
 			break;
 		case 4:
 			/* Slot housing a SGMII riser card? */
-			wriop_set_phy_address(dpmac_id,
+			wriop_set_phy_address(dpmac_id, 0,
 					      riser_phy_addr[dpmac_id - 9]);
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
 			bus = mii_dev_for_muxval(EMI1_SLOT4);
@@ -701,14 +701,14 @@
 			if (slot == EMI_NONE)
 				return;
 			if (serdes2_prtcl == 0x47) {
-				wriop_set_phy_address(dpmac_id,
+				wriop_set_phy_address(dpmac_id, 0,
 					      riser_phy_addr[dpmac_id - 10]);
 				if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
 								 env_hwconfig))
-					wriop_set_phy_address(dpmac_id,
+					wriop_set_phy_address(dpmac_id, 0,
 						riser_phy_addr[dpmac_id - 11]);
 			} else {
-				wriop_set_phy_address(dpmac_id,
+				wriop_set_phy_address(dpmac_id, 0,
 					riser_phy_addr[dpmac_id - 11]);
 			}
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
@@ -717,7 +717,7 @@
 			break;
 		case 6:
 			/* Slot housing a SGMII riser card? */
-			wriop_set_phy_address(dpmac_id,
+			wriop_set_phy_address(dpmac_id, 0,
 					      riser_phy_addr[dpmac_id - 13]);
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
 			bus = mii_dev_for_muxval(EMI1_SLOT6);
@@ -775,7 +775,7 @@
 		switch (++slot) {
 		case 1:
 			/* Slot housing a QSGMII riser card? */
-			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
+			wriop_set_phy_address(dpmac_id, 0, dpmac_id - 1);
 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
 			bus = mii_dev_for_muxval(EMI1_SLOT1);
 			wriop_set_mdio(dpmac_id, bus);
@@ -819,7 +819,7 @@
 		 * the XAUI card is used for the XFI MAC, which will cause
 		 * error.
 		 */
-		wriop_set_phy_address(i, i + 4);
+		wriop_set_phy_address(i, 0, i + 4);
 		ls2080a_qds_enable_SFP_TX(SFP_TX);
 
 		break;
diff --git a/board/freescale/ls2080ardb/eth_ls2080rdb.c b/board/freescale/ls2080ardb/eth_ls2080rdb.c
index 45f1d60..62c7a7a 100644
--- a/board/freescale/ls2080ardb/eth_ls2080rdb.c
+++ b/board/freescale/ls2080ardb/eth_ls2080rdb.c
@@ -50,21 +50,21 @@
 
 	switch (srds_s1) {
 	case 0x2A:
-		wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
-		wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
-		wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
-		wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
-		wriop_set_phy_address(WRIOP1_DPMAC5, AQ_PHY_ADDR1);
-		wriop_set_phy_address(WRIOP1_DPMAC6, AQ_PHY_ADDR2);
-		wriop_set_phy_address(WRIOP1_DPMAC7, AQ_PHY_ADDR3);
-		wriop_set_phy_address(WRIOP1_DPMAC8, AQ_PHY_ADDR4);
+		wriop_set_phy_address(WRIOP1_DPMAC1, 0, CORTINA_PHY_ADDR1);
+		wriop_set_phy_address(WRIOP1_DPMAC2, 0, CORTINA_PHY_ADDR2);
+		wriop_set_phy_address(WRIOP1_DPMAC3, 0, CORTINA_PHY_ADDR3);
+		wriop_set_phy_address(WRIOP1_DPMAC4, 0, CORTINA_PHY_ADDR4);
+		wriop_set_phy_address(WRIOP1_DPMAC5, 0, AQ_PHY_ADDR1);
+		wriop_set_phy_address(WRIOP1_DPMAC6, 0, AQ_PHY_ADDR2);
+		wriop_set_phy_address(WRIOP1_DPMAC7, 0, AQ_PHY_ADDR3);
+		wriop_set_phy_address(WRIOP1_DPMAC8, 0, AQ_PHY_ADDR4);
 
 		break;
 	case 0x4B:
-		wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
-		wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
-		wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
-		wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
+		wriop_set_phy_address(WRIOP1_DPMAC1, 0, CORTINA_PHY_ADDR1);
+		wriop_set_phy_address(WRIOP1_DPMAC2, 0, CORTINA_PHY_ADDR2);
+		wriop_set_phy_address(WRIOP1_DPMAC3, 0, CORTINA_PHY_ADDR3);
+		wriop_set_phy_address(WRIOP1_DPMAC4, 0, CORTINA_PHY_ADDR4);
 
 		break;
 	default:
diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c
index af78127..c95f7af 100644
--- a/board/synopsys/axs10x/axs10x.c
+++ b/board/synopsys/axs10x/axs10x.c
@@ -33,6 +33,13 @@
 	return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct dwmci_host *host = mmc->priv;
+
+	return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 #define AXS_MB_CREG	0xE0011000
 
 int board_early_init_f(void)
diff --git a/board/synopsys/emdk/emdk.c b/board/synopsys/emdk/emdk.c
index bbb946a..79cafef 100644
--- a/board/synopsys/emdk/emdk.c
+++ b/board/synopsys/emdk/emdk.c
@@ -34,6 +34,13 @@
 	return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct dwmci_host *host = mmc->priv;
+
+	return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 #define CREG_BASE		0xF0001000
 #define CREG_BOOT_OFFSET	0
 #define CREG_BOOT_WP_OFFSET	8
diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c
index fb4286f..b6aefdb 100644
--- a/board/synopsys/hsdk/hsdk.c
+++ b/board/synopsys/hsdk/hsdk.c
@@ -1019,6 +1019,13 @@
 	return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct dwmci_host *host = mmc->priv;
+
+	return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
 int board_mmc_init(bd_t *bis)
 {
 	struct dwmci_host *host = NULL;
@@ -1046,3 +1053,11 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	printf("CPU:   ARC HS38 v2.1c\n");
+	return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
index c185d5c..f8838fb 100644
--- a/board/synopsys/iot_devkit/iot_devkit.c
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -17,6 +17,7 @@
 #define AHBCKDIV	(void *)(SYSCON_BASE + 0x04)
 #define APBCKDIV	(void *)(SYSCON_BASE + 0x08)
 #define APBCKEN		(void *)(SYSCON_BASE + 0x0C)
+#define RESET_REG	(void *)(SYSCON_BASE + 0x18)
 #define CLKSEL		(void *)(SYSCON_BASE + 0x24)
 #define CLKSTAT		(void *)(SYSCON_BASE + 0x28)
 #define PLLCON		(void *)(SYSCON_BASE + 0x2C)
@@ -67,6 +68,14 @@
 		writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON);
 		break;
 
+	case 136:
+		writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+		/* pll_off=1, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
+		writel((readl(PLLCON) & PLL_MASK_1) | 0x100111, PLLCON);
+		/* pll_off=0, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
+		writel((readl(PLLCON) & PLL_MASK_2) | 0x100111, PLLCON);
+		break;
+
 	case 144:
 		writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
 		/* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
@@ -99,7 +108,7 @@
  */
 int mach_cpu_init(void)
 {
-	int offset, freq;
+	int offset;
 
 	/* Don't relocate U-Boot */
 	gd->flags |= GD_FLG_SKIP_RELOC;
@@ -120,12 +129,12 @@
 	if (offset < 0)
 		return offset;
 
-	freq = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
-	if (!freq)
+	gd->cpu_clk = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
+	if (!gd->cpu_clk)
 		return -EINVAL;
 
 	/* If CPU freq > 100 MHz, divide eFLASH clock by 2 */
-	if (freq > 100000000) {
+	if (gd->cpu_clk > 100000000) {
 		u32 reg = readl(AHBCKDIV);
 
 		reg &= ~(0xF << 8);
@@ -133,7 +142,7 @@
 		writel(reg, AHBCKDIV);
 	}
 
-	return set_cpu_freq(freq);
+	return set_cpu_freq(gd->cpu_clk);
 }
 
 #define ARC_PERIPHERAL_BASE	0xF0000000
@@ -161,8 +170,32 @@
 	return 0;
 }
 
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct dwmci_host *host = mmc->priv;
+
+	return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
+}
+
+#define IOTDK_RESET_SEQ		0x55AA6699
+
+void reset_cpu(ulong addr)
+{
+	writel(IOTDK_RESET_SEQ, RESET_REG);
+}
+
 int checkboard(void)
 {
 	puts("Board: Synopsys IoT Development Kit\n");
 	return 0;
 };
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	char mhz[8];
+
+	printf("CPU:   ARC EM9D at %s MHz\n", strmhz(mhz, gd->cpu_clk));
+	return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/configs/da850_am18xxevm_defconfig b/configs/da850_am18xxevm_defconfig
index 6745cd1..8487509 100644
--- a/configs/da850_am18xxevm_defconfig
+++ b/configs/da850_am18xxevm_defconfig
@@ -8,6 +8,7 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
@@ -35,6 +36,8 @@
 CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DM=y
 CONFIG_DA8XX_GPIO=y
diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig
index 6dc70dd..5df45ae 100644
--- a/configs/da850evm_defconfig
+++ b/configs/da850evm_defconfig
@@ -7,6 +7,7 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
@@ -37,6 +38,8 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:512k(u-boot.ais),64k(u-boot-env),7552k(kernel-spare),64k(MAC-Address)"
 CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DM=y
diff --git a/configs/da850evm_nand_defconfig b/configs/da850evm_nand_defconfig
index d13d832..20f8e0a 100644
--- a/configs/da850evm_nand_defconfig
+++ b/configs/da850evm_nand_defconfig
@@ -7,9 +7,12 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
+CONFIG_SPL_DM=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_OF_PLATDATA=y
 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
 CONFIG_BOOTDELAY=3
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig
index 1f0f9c3..1b6dd9e 100644
--- a/configs/iot_devkit_defconfig
+++ b/configs/iot_devkit_defconfig
@@ -4,8 +4,9 @@
 CONFIG_SYS_ICACHE_OFF=y
 CONFIG_SYS_DCACHE_OFF=y
 CONFIG_TARGET_IOT_DEVKIT=y
-CONFIG_SYS_TEXT_BASE=0x20000000
+CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_SYS_CLK_FREQ=16000000
+CONFIG_LOCALVERSION="-iotdk-1.0"
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_SYS_PROMPT="IoTDK# "
 # CONFIG_CMD_BOOTD is not set
@@ -17,7 +18,6 @@
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
@@ -25,6 +25,7 @@
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+# CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt
index cb77fdf..034146f 100644
--- a/doc/device-tree-bindings/net/ti,dp83867.txt
+++ b/doc/device-tree-bindings/net/ti,dp83867.txt
@@ -8,6 +8,12 @@
 		for applicable values
 	- ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
 		for applicable values
+	- enet-phy-lane-swap - Indicates that PHY will swap the TX/RX lanes to
+		compensate for the board being designed with the lanes swapped.
+	- enet-phy-no-lane-swap - Indicates that PHY will disable swap of the
+		TX/RX lanes.
+	- ti,clk-output-sel - Clock output select - see dt-bindings/net/ti-dp83867.h
+		for applicable values
 
 Default child nodes are standard Ethernet PHY device
 nodes as described in doc/devicetree/bindings/net/ethernet.txt
@@ -19,6 +25,8 @@
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
 		ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
 		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		enet-phy-lane-no-swap;
+		ti,clk-output-sel = <DP83867_CLK_O_SEL_CHN_A_TCLK>;
 	};
 
 Datasheet can be found:
diff --git a/drivers/mtd/mtd_uboot.c b/drivers/mtd/mtd_uboot.c
index 6a211d5..7d7a11c 100644
--- a/drivers/mtd/mtd_uboot.c
+++ b/drivers/mtd/mtd_uboot.c
@@ -104,7 +104,10 @@
 	mtd_probe_uclass_mtd_devs();
 
 	/* Check if mtdparts/mtdids changed since last call, otherwise: exit */
-	if (!strcmp(mtdparts, old_mtdparts) && !strcmp(mtdids, old_mtdids))
+	if ((!mtdparts && !old_mtdparts && !mtdids && !old_mtdids) ||
+	    (mtdparts && old_mtdparts && mtdids && old_mtdids &&
+	     !strcmp(mtdparts, old_mtdparts) &&
+	     !strcmp(mtdids, old_mtdids)))
 		return 0;
 
 	/* Update the local copy of mtdparts */
@@ -140,6 +143,10 @@
 		}
 	}
 
+	/* If either mtdparts or mtdids is empty, then exit */
+	if (!mtdparts || !mtdids)
+		return 0;
+
 	/* Start the parsing by ignoring the extra 'mtdparts=' prefix, if any */
 	if (strstr(mtdparts, "mtdparts="))
 		mtdparts += 9;
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 4f63cac..26f5c7c 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -32,6 +32,7 @@
 /* CFI Manufacture ID's */
 #define SPI_FLASH_CFI_MFR_SPANSION	0x01
 #define SPI_FLASH_CFI_MFR_STMICRO	0x20
+#define SPI_FLASH_CFI_MFR_MICRON	0x2C
 #define SPI_FLASH_CFI_MFR_MACRONIX	0xc2
 #define SPI_FLASH_CFI_MFR_SST		0xbf
 #define SPI_FLASH_CFI_MFR_WINBOND	0xef
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 9230060..a87bacd 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -1091,6 +1091,7 @@
 #endif
 #ifdef CONFIG_SPI_FLASH_STMICRO
 	case SPI_FLASH_CFI_MFR_STMICRO:
+	case SPI_FLASH_CFI_MFR_MICRON:
 		debug("SF: QEB is volatile for %02x flash\n", JEDEC_MFR(info));
 		return 0;
 #endif
@@ -1178,6 +1179,7 @@
 #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST)
 	/* NOR protection support for STmicro/Micron chips and similar */
 	if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_STMICRO ||
+	    JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_MICRON ||
 	    JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST) {
 		flash->flash_lock = stm_lock;
 		flash->flash_unlock = stm_unlock;
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 8d7c271..e3c403c 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -123,7 +123,6 @@
 #define TOUT_LOOP   1000000
 
 #define SETUP_FRAME_LEN 192
-#define ETH_ALEN	6
 
 struct de4x5_desc {
 	volatile s32 status;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index ae65b64..2fe0ba6 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -193,8 +193,6 @@
 
 #define TOUT_LOOP		1000000
 
-#define ETH_ALEN		6
-
 static struct RxFD rx_ring[NUM_RX_DESC];	/* RX descriptor ring	      */
 static struct TxFD tx_ring[NUM_TX_DESC];	/* TX descriptor ring	      */
 static int rx_next;			/* RX descriptor ring pointer */
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index d9a897d..b245fbc 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -363,8 +363,7 @@
 
 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
 		/* port not enabled */
-		if ((wriop_is_enabled_dpmac(i) != 1) ||
-		    (wriop_get_phy_address(i) == -1))
+		if (wriop_is_enabled_dpmac(i) != 1)
 			continue;
 
 		snprintf(ethname, ETH_NAME_LEN, "DPMAC%d@%s", i,
@@ -886,8 +885,7 @@
 	int i;
 
 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++)
-		if ((wriop_is_enabled_dpmac(i) == 1) &&
-		    (wriop_get_phy_address(i) != -1))
+		if (wriop_is_enabled_dpmac(i) == 1)
 			ldpaa_eth_init(i, wriop_get_enet_if(i));
 	return 0;
 }
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index a25b7cd..73b7ba2 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -23,21 +23,43 @@
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
 	struct phy_device *phydev = NULL;
 	struct mii_dev *bus;
+	int phy_addr, phy_num;
+	int ret = 0;
 
 	bus = wriop_get_mdio(priv->dpmac_id);
 	if (bus == NULL)
 		return 0;
 
-	phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
-			     dev, wriop_get_enet_if(priv->dpmac_id));
-	if (!phydev) {
-		printf("Failed to connect\n");
-		return -1;
+	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+		phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num);
+		if (phy_addr < 0)
+			continue;
+
+		phydev = phy_connect(bus, phy_addr, dev,
+				     wriop_get_enet_if(priv->dpmac_id));
+		if (!phydev) {
+			printf("Failed to connect\n");
+			ret = -ENODEV;
+			break;
+		}
+		wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev);
+		ret = phy_config(phydev);
+		if (ret)
+			break;
 	}
 
+	if (ret) {
+		for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+			phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+			if (!phydev)
+				continue;
+
-	priv->phydev = phydev;
+			free(phydev);
+			wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
+		}
+	}
 
-	return phy_config(phydev);
+	return ret;
 }
 #endif
 
@@ -377,6 +399,70 @@
 	return err;
 }
 
+static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
+				 struct dpmac_link_state *state)
+{
+	phy_interface_t enet_if;
+	int phys_detected;
+#ifdef CONFIG_PHYLIB
+	struct phy_device *phydev = NULL;
+	int err, phy_num;
+#endif
+
+	/* let's start off with maximum capabilities */
+	enet_if = wriop_get_enet_if(priv->dpmac_id);
+	switch (enet_if) {
+	case PHY_INTERFACE_MODE_XGMII:
+		state->rate = SPEED_10000;
+		break;
+	default:
+		state->rate = SPEED_1000;
+		break;
+	}
+	state->up = 1;
+
+	phys_detected = 0;
+#ifdef CONFIG_PHYLIB
+	state->options |= DPMAC_LINK_OPT_AUTONEG;
+
+	/* start the phy devices one by one and update the dpmac state */
+	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+		phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+		if (!phydev)
+			continue;
+
+		phys_detected++;
+		err = phy_startup(phydev);
+		if (err) {
+			printf("%s: Could not initialize\n", phydev->dev->name);
+			state->up = 0;
+			break;
+		}
+		if (phydev->link) {
+			state->rate = min(state->rate, (uint32_t)phydev->speed);
+			if (!phydev->duplex)
+				state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
+			if (!phydev->autoneg)
+				state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+		} else {
+			/* break out of loop even if one phy is down */
+			state->up = 0;
+			break;
+		}
+	}
+#endif
+	if (!phys_detected)
+		state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+
+	if (!state->up) {
+		state->rate = 0;
+		state->options = 0;
+		return -ENOLINK;
+	}
+
+	return 0;
+}
+
 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 {
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
@@ -385,8 +471,6 @@
 	struct dpni_link_state link_state;
 #endif
 	int err = 0;
-	struct mii_dev *bus;
-	phy_interface_t enet_if;
 	struct dpni_queue d_queue;
 
 	if (net_dev->state == ETH_STATE_ACTIVE)
@@ -407,47 +491,14 @@
 	if (err < 0)
 		goto err_dpmac_setup;
 
-#ifdef CONFIG_PHYLIB
-	if (priv->phydev) {
-		err = phy_startup(priv->phydev);
-		if (err) {
-			printf("%s: Could not initialize\n",
-			       priv->phydev->dev->name);
-			goto err_dpamc_bind;
-		}
-	}
-#else
-	priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
-	memset(priv->phydev, 0, sizeof(struct phy_device));
-
-	priv->phydev->speed = SPEED_1000;
-	priv->phydev->link = 1;
-	priv->phydev->duplex = DUPLEX_FULL;
-#endif
-
-	bus = wriop_get_mdio(priv->dpmac_id);
-	enet_if = wriop_get_enet_if(priv->dpmac_id);
-	if ((bus == NULL) &&
-	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
-		priv->phydev = (struct phy_device *)
-				malloc(sizeof(struct phy_device));
-		memset(priv->phydev, 0, sizeof(struct phy_device));
-
-		priv->phydev->speed = SPEED_10000;
-		priv->phydev->link = 1;
-		priv->phydev->duplex = DUPLEX_FULL;
-	}
-
-	if (!priv->phydev->link) {
-		printf("%s: No link.\n", priv->phydev->dev->name);
-		err = -1;
-		goto err_dpamc_bind;
-	}
+	err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
+	if (err < 0)
+		goto err_dpmac_bind;
 
 	/* DPMAC binding DPNI */
 	err = ldpaa_dpmac_bind(priv);
 	if (err)
-		goto err_dpamc_bind;
+		goto err_dpmac_bind;
 
 	/* DPNI initialization */
 	err = ldpaa_dpni_setup(priv);
@@ -476,18 +527,6 @@
 		return err;
 	}
 
-	dpmac_link_state.rate = priv->phydev->speed;
-
-	if (priv->phydev->autoneg == AUTONEG_DISABLE)
-		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
-	else
-		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
-
-	if (priv->phydev->duplex == DUPLEX_HALF)
-		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
-
-	dpmac_link_state.up = priv->phydev->link;
-
 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 				  priv->dpmac_handle, &dpmac_link_state);
 	if (err < 0) {
@@ -530,7 +569,7 @@
 		goto err_qdid;
 	}
 
-	return priv->phydev->link;
+	return dpmac_link_state.up;
 
 err_qdid:
 err_get_queue:
@@ -540,7 +579,7 @@
 err_dpbp_setup:
 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 err_dpni_setup:
-err_dpamc_bind:
+err_dpmac_bind:
 	dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
 	dpmac_destroy(dflt_mc_io,
 		      dflt_dprc_handle,
@@ -554,7 +593,8 @@
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 	int err = 0;
 #ifdef CONFIG_PHYLIB
-	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
+	struct phy_device *phydev = NULL;
+	int phy_num;
 #endif
 
 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
@@ -588,11 +628,10 @@
 		printf("dpni_disable() failed\n");
 
 #ifdef CONFIG_PHYLIB
-	if (priv->phydev && bus != NULL)
-		phy_shutdown(priv->phydev);
-	else {
-		free(priv->phydev);
-		priv->phydev = NULL;
+	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+		phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+		if (phydev)
+			phy_shutdown(phydev);
 	}
 #endif
 
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
index ee784a5..3f9154b 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.h
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -127,7 +127,6 @@
 	uint16_t tx_flow_id;
 
 	enum ldpaa_eth_type type;	/* 1G or 10G ethernet */
-	struct phy_device *phydev;
 };
 
 struct dprc_endpoint dpmac_endpoint;
diff --git a/drivers/net/ldpaa_eth/ldpaa_wriop.c b/drivers/net/ldpaa_eth/ldpaa_wriop.c
index 0731a79..06a284a 100644
--- a/drivers/net/ldpaa_eth/ldpaa_wriop.c
+++ b/drivers/net/ldpaa_eth/ldpaa_wriop.c
@@ -22,10 +22,10 @@
 void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
 {
 	phy_interface_t enet_if;
+	int phy_num;
 
 	dpmac_info[dpmac_id].enabled = 0;
 	dpmac_info[dpmac_id].id = 0;
-	dpmac_info[dpmac_id].phy_addr = -1;
 	dpmac_info[dpmac_id].enet_if = PHY_INTERFACE_MODE_NONE;
 
 	enet_if = wriop_dpmac_enet_if(dpmac_id, lane_prtcl);
@@ -34,14 +34,23 @@
 		dpmac_info[dpmac_id].id = dpmac_id;
 		dpmac_info[dpmac_id].enet_if = enet_if;
 	}
+	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+		dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+		dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+	}
 }
 
 void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if)
 {
+	int phy_num;
+
 	dpmac_info[dpmac_id].enabled = 1;
 	dpmac_info[dpmac_id].id = dpmac_id;
-	dpmac_info[dpmac_id].phy_addr = -1;
 	dpmac_info[dpmac_id].enet_if = enet_if;
+	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+		dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+		dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+	}
 }
 
 
@@ -58,47 +67,53 @@
 	return -1;
 }
 
-void wriop_disable_dpmac(int dpmac_id)
+int wriop_disable_dpmac(int dpmac_id)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return;
+		return -ENODEV;
 
 	dpmac_info[i].enabled = 0;
 	wriop_dpmac_disable(dpmac_id);
+
+	return 0;
 }
 
-void wriop_enable_dpmac(int dpmac_id)
+int wriop_enable_dpmac(int dpmac_id)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return;
+		return -ENODEV;
 
 	dpmac_info[i].enabled = 1;
 	wriop_dpmac_enable(dpmac_id);
+
+	return 0;
 }
 
-u8 wriop_is_enabled_dpmac(int dpmac_id)
+int wriop_is_enabled_dpmac(int dpmac_id)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return -1;
+		return -ENODEV;
 
 	return dpmac_info[i].enabled;
 }
 
 
-void wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
+int wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return;
+		return -ENODEV;
 
 	dpmac_info[i].bus = bus;
+
+	return 0;
 }
 
 struct mii_dev *wriop_get_mdio(int dpmac_id)
@@ -111,44 +126,56 @@
 	return dpmac_info[i].bus;
 }
 
-void wriop_set_phy_address(int dpmac_id, int address)
+int wriop_set_phy_address(int dpmac_id, int phy_num, int address)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return;
+		return -ENODEV;
+	if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+		return -EINVAL;
+
+	dpmac_info[i].phy_addr[phy_num] = address;
 
-	dpmac_info[i].phy_addr = address;
+	return 0;
 }
 
-int wriop_get_phy_address(int dpmac_id)
+int wriop_get_phy_address(int dpmac_id, int phy_num)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return -1;
+		return -ENODEV;
+	if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+		return -EINVAL;
 
-	return dpmac_info[i].phy_addr;
+	return dpmac_info[i].phy_addr[phy_num];
 }
 
-void wriop_set_phy_dev(int dpmac_id, struct phy_device *phydev)
+int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
-		return;
+		return -ENODEV;
+	if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+		return -EINVAL;
 
-	dpmac_info[i].phydev = phydev;
+	dpmac_info[i].phydev[phy_num] = phydev;
+
+	return 0;
 }
 
-struct phy_device *wriop_get_phy_dev(int dpmac_id)
+struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num)
 {
 	int i = wriop_dpmac_to_index(dpmac_id);
 
 	if (i == -1)
 		return NULL;
+	if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+		return NULL;
 
-	return dpmac_info[i].phydev;
+	return dpmac_info[i].phydev[phy_num];
 }
 
 phy_interface_t wriop_get_enet_if(int dpmac_id)
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index ab697b9..8cb04b5 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -34,14 +34,6 @@
 # error Marvell mvneta requires PHYLIB
 #endif
 
-/* Some linux -> U-Boot compatibility stuff */
-#define netdev_err(dev, fmt, args...)		\
-	printf(fmt, ##args)
-#define netdev_warn(dev, fmt, args...)		\
-	printf(fmt, ##args)
-#define netdev_info(dev, fmt, args...)		\
-	printf(fmt, ##args)
-
 #define CONFIG_NR_CPUS		1
 #define ETH_HLEN		14	/* Total octets in header */
 
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 62c0c2b..f34245b 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -35,18 +35,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Some linux -> U-Boot compatibility stuff */
-#define netdev_err(dev, fmt, args...)		\
-	printf(fmt, ##args)
-#define netdev_warn(dev, fmt, args...)		\
-	printf(fmt, ##args)
-#define netdev_info(dev, fmt, args...)		\
-	printf(fmt, ##args)
-#define netdev_dbg(dev, fmt, args...)		\
-	printf(fmt, ##args)
-
-#define ETH_ALEN	6		/* Octets in one ethernet addr	*/
-
 #define __verify_pcpu_ptr(ptr)						\
 do {									\
 	const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL;	\
@@ -68,7 +56,6 @@
 #define NET_SKB_PAD	max(32, MVPP2_CPU_D_CACHE_LINE_SIZE)
 
 #define CONFIG_NR_CPUS		1
-#define ETH_HLEN		ETHER_HDR_SIZE	/* Total octets in header */
 
 /* 2(HW hdr) 14(MAC hdr) 4(CRC) 32(extra for cache prefetch) */
 #define WRAP			(2 + ETH_HLEN + 4 + 32)
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 0ed9bb5..86f6898 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -61,7 +61,6 @@
 #define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
 
 #define DSIZE		0x00000FFF
-#define ETH_ALEN	6
 #define CRC_SIZE	4
 #define TOUT_LOOP	500000
 #define TX_BUF_SIZE	1536
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index f941c15..ea7ece5 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -59,7 +59,6 @@
 
 /* defines */
 #define DSIZE     0x00000FFF
-#define ETH_ALEN		6
 #define CRC_SIZE  4
 #define TOUT_LOOP   500000
 #define TX_BUF_SIZE    1536
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index d31c45f..2286dd0 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -429,7 +429,7 @@
 	return 0;
 }
 
-int pch_gbe_probe(struct udevice *dev)
+static int pch_gbe_probe(struct udevice *dev)
 {
 	struct pch_gbe_priv *priv;
 	struct eth_pdata *plat = dev_get_platdata(dev);
@@ -464,7 +464,7 @@
 	return pch_gbe_phy_init(dev);
 }
 
-int pch_gbe_remove(struct udevice *dev)
+static int pch_gbe_remove(struct udevice *dev)
 {
 	struct pch_gbe_priv *priv = dev_get_priv(dev);
 
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index f870e6d..6db6edd 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -24,6 +24,7 @@
 /* Extended Registers */
 #define DP83867_CFG4		0x0031
 #define DP83867_RGMIICTL	0x0032
+#define DP83867_STRAP_STS1	0x006E
 #define DP83867_RGMIIDCTL	0x0086
 #define DP83867_IO_MUX_CFG	0x0170
 
@@ -48,8 +49,12 @@
 #define DP83867_RGMII_TX_CLK_DELAY_EN		BIT(1)
 #define DP83867_RGMII_RX_CLK_DELAY_EN		BIT(0)
 
+/* STRAP_STS1 bits */
+#define DP83867_STRAP_STS1_RESERVED		BIT(11)
+
 /* PHY CTRL bits */
 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT		14
+#define DP83867_PHYCR_RESERVED_MASK	BIT(11)
 #define DP83867_MDI_CROSSOVER		5
 #define DP83867_MDI_CROSSOVER_AUTO	2
 #define DP83867_MDI_CROSSOVER_MDIX	2
@@ -88,6 +93,18 @@
 
 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX	0x0
 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN	0x1f
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT	8
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK	\
+		GENMASK(0x1f, DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT)
+
+/* CFG4 bits */
+#define DP83867_CFG4_PORT_MIRROR_EN		BIT(0)
+
+enum {
+	DP83867_PORT_MIRRORING_KEEP,
+	DP83867_PORT_MIRRORING_EN,
+	DP83867_PORT_MIRRORING_DIS,
+};
 
 struct dp83867_private {
 	int rx_id_delay;
@@ -95,6 +112,8 @@
 	int fifo_depth;
 	int io_impedance;
 	bool rxctrl_strap_quirk;
+	int port_mirroring;
+	int clk_output_sel;
 };
 
 /**
@@ -163,6 +182,26 @@
 	phy_write(phydev, addr, MII_MMD_DATA, data);
 }
 
+static int dp83867_config_port_mirroring(struct phy_device *phydev)
+{
+	struct dp83867_private *dp83867 =
+		(struct dp83867_private *)phydev->priv;
+	u16 val;
+
+	val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+				    phydev->addr);
+
+	if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN)
+		val |= DP83867_CFG4_PORT_MIRROR_EN;
+	else
+		val &= ~DP83867_CFG4_PORT_MIRROR_EN;
+
+	phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
+			       phydev->addr, val);
+
+	return 0;
+}
+
 #if defined(CONFIG_DM_ETH)
 /**
  * dp83867_data_init - Convenience function for setting PHY specific data
@@ -173,6 +212,18 @@
 {
 	struct dp83867_private *dp83867 = phydev->priv;
 	ofnode node;
+	u16 val;
+
+	/* Optional configuration */
+
+	/*
+	 * Keep the default value if ti,clk-output-sel is not set
+	 * or to high
+	 */
+
+	dp83867->clk_output_sel =
+		ofnode_read_u32_default(node, "ti,clk-output-sel",
+					DP83867_CLK_O_SEL_REF_CLK);
 
 	node = phy_get_ofnode(phydev);
 	if (!ofnode_valid(node))
@@ -197,6 +248,23 @@
 
 	dp83867->fifo_depth = ofnode_read_u32_default(node, "ti,fifo-depth",
 						      -1);
+	if (ofnode_read_bool(node, "enet-phy-lane-swap"))
+		dp83867->port_mirroring = DP83867_PORT_MIRRORING_EN;
+
+	if (ofnode_read_bool(node, "enet-phy-lane-no-swap"))
+		dp83867->port_mirroring = DP83867_PORT_MIRRORING_DIS;
+
+
+	/* Clock output selection if muxing property is set */
+	if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
+		val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+					    DP83867_DEVADDR, phydev->addr);
+		val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
+		val |= (dp83867->clk_output_sel <<
+			DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
+		phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+				       DP83867_DEVADDR, phydev->addr, val);
+	}
 
 	return 0;
 }
@@ -218,7 +286,7 @@
 {
 	struct dp83867_private *dp83867;
 	unsigned int val, delay, cfg2;
-	int ret;
+	int ret, bs;
 
 	if (!phydev->priv) {
 		dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL);
@@ -253,6 +321,26 @@
 			(dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
 		if (ret)
 			goto err_out;
+
+		/* The code below checks if "port mirroring" N/A MODE4 has been
+		 * enabled during power on bootstrap.
+		 *
+		 * Such N/A mode enabled by mistake can put PHY IC in some
+		 * internal testing mode and disable RGMII transmission.
+		 *
+		 * In this particular case one needs to check STRAP_STS1
+		 * register's bit 11 (marked as RESERVED).
+		 */
+
+		bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1,
+					   DP83867_DEVADDR, phydev->addr);
+		val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL);
+		if (bs & DP83867_STRAP_STS1_RESERVED) {
+			val &= ~DP83867_PHYCR_RESERVED_MASK;
+			phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
+				  val);
+		}
+
 	} else if (phy_interface_is_sgmii(phydev)) {
 		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
 			  (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
@@ -315,6 +403,9 @@
 		}
 	}
 
+	if (dp83867->port_mirroring != DP83867_PORT_MIRRORING_KEEP)
+		dp83867_config_port_mirroring(phydev);
+
 	genphy_config_aneg(phydev);
 	return 0;
 
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index ea52343..590f8ce 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -80,10 +80,6 @@
 
 #define RTL_TIMEOUT	100000
 
-#define ETH_FRAME_LEN		1514
-#define ETH_ALEN		6
-#define ETH_ZLEN		60
-
 /* PCI Tuning Parameters
    Threshold is bytes transferred to chip before transmission starts. */
 #define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index e0e3a6d..a78f3d2 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -102,10 +102,6 @@
 #define RTL_R16(reg)		readw(ioaddr + (reg))
 #define RTL_R32(reg)		readl(ioaddr + (reg))
 
-#define ETH_FRAME_LEN	MAX_ETH_FRAME_SIZE
-#define ETH_ALEN	MAC_ADDR_LEN
-#define ETH_ZLEN	60
-
 #define bus_to_phys(a)	pci_mem_to_phys((pci_dev_t)(unsigned long)dev->priv, \
 	(pci_addr_t)(unsigned long)a)
 #define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)(unsigned long)dev->priv, \
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index b71c8f8..decce2f 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -10,26 +10,11 @@
 #include <dm.h>
 #include <malloc.h>
 #include <net.h>
+#include <asm/eth.h>
 #include <asm/test.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/**
- * struct eth_sandbox_priv - memory for sandbox mock driver
- *
- * fake_host_hwaddr: MAC address of mocked machine
- * fake_host_ipaddr: IP address of mocked machine
- * recv_packet_buffer: buffer of the packet returned as received
- * recv_packet_length: length of the packet returned as received
- */
-struct eth_sandbox_priv {
-	uchar fake_host_hwaddr[ARP_HLEN];
-	struct in_addr fake_host_ipaddr;
-	uchar *recv_packet_buffer;
-	int recv_packet_length;
-};
-
-static bool disabled[8] = {false};
 static bool skip_timeout;
 
 /*
@@ -40,7 +25,16 @@
  */
 void sandbox_eth_disable_response(int index, bool disable)
 {
-	disabled[index] = disable;
+	struct udevice *dev;
+	struct eth_sandbox_priv *priv;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_ETH, index, &dev);
+	if (ret)
+		return;
+
+	priv = dev_get_priv(dev);
+	priv->disabled = disable;
 }
 
 /*
@@ -53,103 +47,304 @@
 	skip_timeout = true;
 }
 
-static int sb_eth_start(struct udevice *dev)
+/*
+ * sandbox_eth_arp_req_to_reply()
+ *
+ * Check for an arp request to be sent. If so, inject a reply
+ *
+ * returns 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
+				 unsigned int len)
 {
 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth = packet;
+	struct arp_hdr *arp;
+	struct ethernet_hdr *eth_recv;
+	struct arp_hdr *arp_recv;
 
-	debug("eth_sandbox: Start\n");
+	if (ntohs(eth->et_protlen) != PROT_ARP)
+		return -EAGAIN;
 
-	priv->recv_packet_buffer = net_rx_packets[0];
+	arp = packet + ETHER_HDR_SIZE;
+
+	if (ntohs(arp->ar_op) != ARPOP_REQUEST)
+		return -EAGAIN;
+
+	/* Don't allow the buffer to overrun */
+	if (priv->recv_packets >= PKTBUFSRX)
+		return 0;
+
+	/* store this as the assumed IP of the fake host */
+	priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
+
+	/* Formulate a fake response */
+	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+	memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
+	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+	eth_recv->et_protlen = htons(PROT_ARP);
+
+	arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
+	arp_recv->ar_hrd = htons(ARP_ETHER);
+	arp_recv->ar_pro = htons(PROT_IP);
+	arp_recv->ar_hln = ARP_HLEN;
+	arp_recv->ar_pln = ARP_PLEN;
+	arp_recv->ar_op = htons(ARPOP_REPLY);
+	memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
+	net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
+	memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
+	net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
+
+	priv->recv_packet_length[priv->recv_packets] =
+		ETHER_HDR_SIZE + ARP_HDR_SIZE;
+	++priv->recv_packets;
 
 	return 0;
 }
 
-static int sb_eth_send(struct udevice *dev, void *packet, int length)
+/*
+ * sandbox_eth_ping_req_to_reply()
+ *
+ * Check for a ping request to be sent. If so, inject a reply
+ *
+ * returns 0 if injected, -EAGAIN if not
+ */
+int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
+				  unsigned int len)
 {
 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
 	struct ethernet_hdr *eth = packet;
+	struct ip_udp_hdr *ip;
+	struct icmp_hdr *icmp;
+	struct ethernet_hdr *eth_recv;
+	struct ip_udp_hdr *ipr;
+	struct icmp_hdr *icmpr;
 
-	debug("eth_sandbox: Send packet %d\n", length);
+	if (ntohs(eth->et_protlen) != PROT_IP)
+		return -EAGAIN;
 
-	if (dev->seq >= 0 && dev->seq < ARRAY_SIZE(disabled) &&
-	    disabled[dev->seq])
+	ip = packet + ETHER_HDR_SIZE;
+
+	if (ip->ip_p != IPPROTO_ICMP)
+		return -EAGAIN;
+
+	icmp = (struct icmp_hdr *)&ip->udp_src;
+
+	if (icmp->type != ICMP_ECHO_REQUEST)
+		return -EAGAIN;
+
+	/* Don't allow the buffer to overrun */
+	if (priv->recv_packets >= PKTBUFSRX)
 		return 0;
 
+	/* reply to the ping */
+	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+	memcpy(eth_recv, packet, len);
+	ipr = (void *)eth_recv + ETHER_HDR_SIZE;
+	icmpr = (struct icmp_hdr *)&ipr->udp_src;
+	memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
+	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+	ipr->ip_sum = 0;
+	ipr->ip_off = 0;
+	net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
+	net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr);
+	ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
+
+	icmpr->type = ICMP_ECHO_REPLY;
+	icmpr->checksum = 0;
+	icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
+
+	priv->recv_packet_length[priv->recv_packets] = len;
+	++priv->recv_packets;
+
+	return 0;
+}
+
+/*
+ * sandbox_eth_recv_arp_req()
+ *
+ * Inject an ARP request for this target
+ *
+ * returns 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_arp_req(struct udevice *dev)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth_recv;
+	struct arp_hdr *arp_recv;
+
-	if (ntohs(eth->et_protlen) == PROT_ARP) {
-		struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+	/* Don't allow the buffer to overrun */
+	if (priv->recv_packets >= PKTBUFSRX)
+		return -EOVERFLOW;
 
-		if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
-			struct ethernet_hdr *eth_recv;
-			struct arp_hdr *arp_recv;
+	/* Formulate a fake request */
+	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
+	memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN);
+	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+	eth_recv->et_protlen = htons(PROT_ARP);
 
-			/* store this as the assumed IP of the fake host */
-			priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
-			/* Formulate a fake response */
-			eth_recv = (void *)priv->recv_packet_buffer;
-			memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
-			memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
-			       ARP_HLEN);
-			eth_recv->et_protlen = htons(PROT_ARP);
+	arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
+	arp_recv->ar_hrd = htons(ARP_ETHER);
+	arp_recv->ar_pro = htons(PROT_IP);
+	arp_recv->ar_hln = ARP_HLEN;
+	arp_recv->ar_pln = ARP_PLEN;
+	arp_recv->ar_op = htons(ARPOP_REQUEST);
+	memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
+	net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
+	memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN);
+	net_write_ip(&arp_recv->ar_tpa, net_ip);
 
-			arp_recv = (void *)priv->recv_packet_buffer +
-				ETHER_HDR_SIZE;
-			arp_recv->ar_hrd = htons(ARP_ETHER);
-			arp_recv->ar_pro = htons(PROT_IP);
-			arp_recv->ar_hln = ARP_HLEN;
-			arp_recv->ar_pln = ARP_PLEN;
-			arp_recv->ar_op = htons(ARPOP_REPLY);
-			memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr,
-			       ARP_HLEN);
-			net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
-			memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
-			net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
+	priv->recv_packet_length[priv->recv_packets] =
+		ETHER_HDR_SIZE + ARP_HDR_SIZE;
+	++priv->recv_packets;
 
-			priv->recv_packet_length = ETHER_HDR_SIZE +
-				ARP_HDR_SIZE;
-		}
-	} else if (ntohs(eth->et_protlen) == PROT_IP) {
-		struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
+	return 0;
+}
+
+/*
+ * sandbox_eth_recv_ping_req()
+ *
+ * Inject a ping request for this target
+ *
+ * returns 0 if injected, -EOVERFLOW if not
+ */
+int sandbox_eth_recv_ping_req(struct udevice *dev)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth_recv;
+	struct ip_udp_hdr *ipr;
+	struct icmp_hdr *icmpr;
+
+	/* Don't allow the buffer to overrun */
+	if (priv->recv_packets >= PKTBUFSRX)
+		return -EOVERFLOW;
+
+	/* Formulate a fake ping */
+	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
 
-		if (ip->ip_p == IPPROTO_ICMP) {
-			struct icmp_hdr *icmp = (struct icmp_hdr *)&ip->udp_src;
+	memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN);
+	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+	eth_recv->et_protlen = htons(PROT_IP);
 
-			if (icmp->type == ICMP_ECHO_REQUEST) {
-				struct ethernet_hdr *eth_recv;
-				struct ip_udp_hdr *ipr;
-				struct icmp_hdr *icmpr;
+	ipr = (void *)eth_recv + ETHER_HDR_SIZE;
+	ipr->ip_hl_v = 0x45;
+	ipr->ip_len = htons(IP_ICMP_HDR_SIZE);
+	ipr->ip_off = htons(IP_FLAGS_DFRAG);
+	ipr->ip_p = IPPROTO_ICMP;
+	ipr->ip_sum = 0;
+	net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr);
+	net_write_ip(&ipr->ip_dst, net_ip);
+	ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
 
-				/* reply to the ping */
-				memcpy(priv->recv_packet_buffer, packet,
-				       length);
-				eth_recv = (void *)priv->recv_packet_buffer;
-				ipr = (void *)priv->recv_packet_buffer +
-					ETHER_HDR_SIZE;
-				icmpr = (struct icmp_hdr *)&ipr->udp_src;
-				memcpy(eth_recv->et_dest, eth->et_src,
-				       ARP_HLEN);
-				memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
-				       ARP_HLEN);
-				ipr->ip_sum = 0;
-				ipr->ip_off = 0;
-				net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
-				net_write_ip((void *)&ipr->ip_src,
-					     priv->fake_host_ipaddr);
-				ipr->ip_sum = compute_ip_checksum(ipr,
-					IP_HDR_SIZE);
+	icmpr = (struct icmp_hdr *)&ipr->udp_src;
 
-				icmpr->type = ICMP_ECHO_REPLY;
-				icmpr->checksum = 0;
-				icmpr->checksum = compute_ip_checksum(icmpr,
-					ICMP_HDR_SIZE);
+	icmpr->type = ICMP_ECHO_REQUEST;
+	icmpr->code = 0;
+	icmpr->checksum = 0;
+	icmpr->un.echo.id = 0;
+	icmpr->un.echo.sequence = htons(1);
+	icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
 
-				priv->recv_packet_length = length;
-			}
-		}
+	priv->recv_packet_length[priv->recv_packets] =
+		ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE;
+	++priv->recv_packets;
+
+	return 0;
+}
+
+/*
+ * sb_default_handler()
+ *
+ * perform typical responses to simple ping
+ *
+ * dev - device pointer
+ * pkt - "sent" packet buffer
+ * len - length of packet
+ */
+static int sb_default_handler(struct udevice *dev, void *packet,
+			      unsigned int len)
+{
+	if (!sandbox_eth_arp_req_to_reply(dev, packet, len))
+		return 0;
+	if (!sandbox_eth_ping_req_to_reply(dev, packet, len))
+		return 0;
+
+	return 0;
+}
+
+/*
+ * sandbox_eth_set_tx_handler()
+ *
+ * Set a custom response to a packet being sent through the sandbox eth test
+ *	driver
+ *
+ * index - interface to set the handler for
+ * handler - The func ptr to call on send. If NULL, set to default handler
+ */
+void sandbox_eth_set_tx_handler(int index, sandbox_eth_tx_hand_f *handler)
+{
+	struct udevice *dev;
+	struct eth_sandbox_priv *priv;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_ETH, index, &dev);
+	if (ret)
+		return;
+
+	priv = dev_get_priv(dev);
+	if (handler)
+		priv->tx_handler = handler;
+	else
+		priv->tx_handler = sb_default_handler;
+}
+
+/*
+ * Set priv ptr
+ *
+ * priv - priv void ptr to store in the device
+ */
+void sandbox_eth_set_priv(int index, void *priv)
+{
+	struct udevice *dev;
+	struct eth_sandbox_priv *dev_priv;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_ETH, index, &dev);
+	if (ret)
+		return;
+
+	dev_priv = dev_get_priv(dev);
+
+	dev_priv->priv = priv;
+}
+
+static int sb_eth_start(struct udevice *dev)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+	debug("eth_sandbox: Start\n");
+
+	priv->recv_packets = 0;
+	for (int i = 0; i < PKTBUFSRX; i++) {
+		priv->recv_packet_buffer[i] = net_rx_packets[i];
+		priv->recv_packet_length[i] = 0;
 	}
 
 	return 0;
 }
 
+static int sb_eth_send(struct udevice *dev, void *packet, int length)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+	debug("eth_sandbox: Send packet %d\n", length);
+
+	if (priv->disabled)
+		return 0;
+
+	return priv->tx_handler(dev, packet, length);
+}
+
 static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 {
 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
@@ -159,15 +354,34 @@
 		skip_timeout = false;
 	}
 
-	if (priv->recv_packet_length) {
-		int lcl_recv_packet_length = priv->recv_packet_length;
+	if (priv->recv_packets) {
+		int lcl_recv_packet_length = priv->recv_packet_length[0];
 
-		debug("eth_sandbox: received packet %d\n",
-		      priv->recv_packet_length);
-		priv->recv_packet_length = 0;
-		*packetp = priv->recv_packet_buffer;
+		debug("eth_sandbox: received packet[%d], %d waiting\n",
+		      lcl_recv_packet_length, priv->recv_packets - 1);
+		*packetp = priv->recv_packet_buffer[0];
 		return lcl_recv_packet_length;
 	}
+	return 0;
+}
+
+static int sb_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	int i;
+
+	if (!priv->recv_packets)
+		return 0;
+
+	--priv->recv_packets;
+	for (i = 0; i < priv->recv_packets; i++) {
+		priv->recv_packet_length[i] = priv->recv_packet_length[i + 1];
+		memcpy(priv->recv_packet_buffer[i],
+		       priv->recv_packet_buffer[i + 1],
+		       priv->recv_packet_length[i + 1]);
+	}
+	priv->recv_packet_length[priv->recv_packets] = 0;
+
 	return 0;
 }
 
@@ -189,6 +403,7 @@
 	.start			= sb_eth_start,
 	.send			= sb_eth_send,
 	.recv			= sb_eth_recv,
+	.free_pkt		= sb_eth_free_pkt,
 	.stop			= sb_eth_stop,
 	.write_hwaddr		= sb_eth_write_hwaddr,
 };
@@ -212,6 +427,8 @@
 		return -EINVAL;
 	}
 	memcpy(priv->fake_host_hwaddr, mac, ARP_HLEN);
+	priv->disabled = false;
+	priv->tx_handler = sb_default_handler;
 
 	return 0;
 }
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index a822858..07fa5e3 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -14,6 +14,7 @@
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <dm.h>
+#include <dm/platform_data/spi_davinci.h>
 
 /* SPIGCR0 */
 #define SPIGCR0_SPIENA_MASK	0x1
@@ -529,50 +530,58 @@
 	return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
 }
 
+static const struct dm_spi_ops davinci_spi_ops = {
+	.claim_bus	= davinci_spi_claim_bus,
+	.release_bus	= davinci_spi_release_bus,
+	.xfer		= davinci_spi_xfer,
+	.set_speed	= davinci_spi_set_speed,
+	.set_mode	= davinci_spi_set_mode,
+};
+
 static int davinci_spi_probe(struct udevice *bus)
 {
-	/* Nothing to do */
+	struct davinci_spi_slave *ds = dev_get_priv(bus);
+	struct davinci_spi_platdata *plat = bus->platdata;
+	ds->regs = plat->regs;
+	ds->num_cs = plat->num_cs;
+
 	return 0;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 static int davinci_ofdata_to_platadata(struct udevice *bus)
 {
-	struct davinci_spi_slave *ds = dev_get_priv(bus);
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(bus);
+	struct davinci_spi_platdata *plat = bus->platdata;
+	fdt_addr_t addr;
 
-	ds->regs = devfdt_map_physmem(bus, sizeof(struct davinci_spi_regs));
-	if (!ds->regs) {
-		printf("%s: could not map device address\n", __func__);
+	addr = devfdt_get_addr(bus);
+	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
-	}
-	ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
+	plat->regs = (struct davinci_spi_regs *)addr;
+	plat->num_cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), "num-cs", 4);
 
 	return 0;
 }
 
-static const struct dm_spi_ops davinci_spi_ops = {
-	.claim_bus	= davinci_spi_claim_bus,
-	.release_bus	= davinci_spi_release_bus,
-	.xfer		= davinci_spi_xfer,
-	.set_speed	= davinci_spi_set_speed,
-	.set_mode	= davinci_spi_set_mode,
-};
-
 static const struct udevice_id davinci_spi_ids[] = {
 	{ .compatible = "ti,keystone-spi" },
 	{ .compatible = "ti,dm6441-spi" },
 	{ .compatible = "ti,da830-spi" },
 	{ }
 };
+#endif
 
 U_BOOT_DRIVER(davinci_spi) = {
 	.name = "davinci_spi",
 	.id = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.of_match = davinci_spi_ids,
-	.ops = &davinci_spi_ops,
 	.ofdata_to_platdata = davinci_ofdata_to_platadata,
-	.priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
+        .platdata_auto_alloc_size = sizeof(struct davinci_spi_platdata),
+#endif
 	.probe = davinci_spi_probe,
+	.ops = &davinci_spi_ops,
+	.priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
 };
 #endif
diff --git a/drivers/usb/eth/lan7x.h b/drivers/usb/eth/lan7x.h
index d1b1047..7af610b 100644
--- a/drivers/usb/eth/lan7x.h
+++ b/drivers/usb/eth/lan7x.h
@@ -94,7 +94,7 @@
 #define LAN7X_MAC_RX_MAX_SIZE(mtu) \
 	((mtu) << 16)			/* Max frame size */
 #define LAN7X_MAC_RX_MAX_SIZE_DEFAULT \
-	LAN7X_MAC_RX_MAX_SIZE(ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */)
+	LAN7X_MAC_RX_MAX_SIZE(PKTSIZE_ALIGN + 4 /* VLAN */ + 4 /* CRC */)
 
 /* Timeouts */
 #define USB_CTRL_SET_TIMEOUT_MS		5000
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8ab9b9f..90ef1f0 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -71,11 +71,6 @@
  * RNDIS specs are ambiguous and appear to be incomplete, and are also
  * needlessly complex.  They borrow more from CDC ACM than CDC ECM.
  */
-#define ETH_ALEN	6		/* Octets in one ethernet addr	 */
-#define ETH_HLEN	14		/* Total octets in header.	 */
-#define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
-#define ETH_FRAME_LEN	PKTSIZE_ALIGN	/* Max. octets in frame sans FCS */
 
 #define DRIVER_DESC		"Ethernet Gadget"
 /* Based on linux 2.6.27 version */
@@ -529,7 +524,7 @@
 	/* this descriptor actually adds value, surprise! */
 	.iMACAddress =		STRING_ETHADDR,
 	.bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
-	.wMaxSegmentSize =	__constant_cpu_to_le16(ETH_FRAME_LEN),
+	.wMaxSegmentSize =	__constant_cpu_to_le16(PKTSIZE_ALIGN),
 	.wNumberMCFilters =	__constant_cpu_to_le16(0),
 	.bNumberPowerFilters =	0,
 };
@@ -1575,7 +1570,7 @@
 			req->length -= length;
 			req->actual -= length;
 		}
-		if (req->actual < ETH_HLEN || ETH_FRAME_LEN < req->actual) {
+		if (req->actual < ETH_HLEN || PKTSIZE_ALIGN < req->actual) {
 length_err:
 			dev->stats.rx_errors++;
 			dev->stats.rx_length_errors++;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index d47e29e..eec639f 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -35,12 +35,6 @@
 
 #include "rndis.h"
 
-#define ETH_ALEN	6		/* Octets in one ethernet addr	 */
-#define ETH_HLEN	14		/* Total octets in header.	 */
-#define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
-#define ETH_FRAME_LEN	PKTSIZE_ALIGN	/* Max. octets in frame sans FCS */
-
 /*
  * The driver for your USB chip needs to support ep0 OUT to work with
  * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index 319f6aa..e685db1 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -23,8 +23,6 @@
 * DM support in SPL
 */
 #ifdef CONFIG_SPL_BUILD
-#undef CONFIG_DM_SPI
-#undef CONFIG_DM_SPI_FLASH
 #undef CONFIG_DM_I2C
 #undef CONFIG_DM_I2C_COMPAT
 #endif
@@ -118,7 +116,6 @@
 
 #if !CONFIG_IS_ENABLED(DM_SERIAL)
 #define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE	-4	/* NS16550 register size */
 #define CONFIG_SYS_NS16550_COM1	DAVINCI_UART2_BASE /* Base address of UART2 */
 #endif
 #define CONFIG_SYS_NS16550_CLK	clk_get(DAVINCI_UART2_CLKID)
diff --git a/include/dm/platform_data/spi_davinci.h b/include/dm/platform_data/spi_davinci.h
new file mode 100644
index 0000000..fbc62c2
--- /dev/null
+++ b/include/dm/platform_data/spi_davinci.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __spi_davinci_h
+#define __spi_davinci_h
+
+struct davinci_spi_platdata {
+	struct davinci_spi_regs *regs;
+	u8 num_cs;	   /* total no. of CS available */
+};
+
+#endif /* __spi_davinci_h */
diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h
index b8e5df6..85d08f6 100644
--- a/include/dt-bindings/net/ti-dp83867.h
+++ b/include/dt-bindings/net/ti-dp83867.h
@@ -31,4 +31,19 @@
 #define DP83867_RGMIIDCTL_3_75_NS	0xe
 #define DP83867_RGMIIDCTL_4_00_NS	0xf
 
+/* IO_MUX_CFG - Clock output selection */
+#define DP83867_CLK_O_SEL_CHN_A_RCLK		0x0
+#define DP83867_CLK_O_SEL_CHN_B_RCLK		0x1
+#define DP83867_CLK_O_SEL_CHN_C_RCLK		0x2
+#define DP83867_CLK_O_SEL_CHN_D_RCLK		0x3
+#define DP83867_CLK_O_SEL_CHN_A_RCLK_DIV5	0x4
+#define DP83867_CLK_O_SEL_CHN_B_RCLK_DIV5	0x5
+#define DP83867_CLK_O_SEL_CHN_C_RCLK_DIV5	0x6
+#define DP83867_CLK_O_SEL_CHN_D_RCLK_DIV5	0x7
+#define DP83867_CLK_O_SEL_CHN_A_TCLK		0x8
+#define DP83867_CLK_O_SEL_CHN_B_TCLK		0x9
+#define DP83867_CLK_O_SEL_CHN_C_TCLK		0xA
+#define DP83867_CLK_O_SEL_CHN_D_TCLK		0xB
+#define DP83867_CLK_O_SEL_REF_CLK		0xC
+
 #endif
diff --git a/include/fsl-mc/ldpaa_wriop.h b/include/fsl-mc/ldpaa_wriop.h
index 07e5130..b55c39c 100644
--- a/include/fsl-mc/ldpaa_wriop.h
+++ b/include/fsl-mc/ldpaa_wriop.h
@@ -6,7 +6,11 @@
 #ifndef __LDPAA_WRIOP_H
 #define __LDPAA_WRIOP_H
 
- #include <phy.h>
+#include <phy.h>
+
+#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0"
+#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1"
+#define WRIOP_MAX_PHY_NUM        2
 
 enum wriop_port {
 	WRIOP1_DPMAC1 = 1,
@@ -40,34 +44,30 @@
 	u8 enabled;
 	u8 id;
 	u8 board_mux;
-	int phy_addr;
-	void *phy_regs;
+	int phy_addr[WRIOP_MAX_PHY_NUM];
 	phy_interface_t enet_if;
-	struct phy_device *phydev;
+	struct phy_device *phydev[WRIOP_MAX_PHY_NUM];
 	struct mii_dev *bus;
 };
 
 extern struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS];
 
-#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0"
-#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1"
-
-void wriop_init_dpmac(int, int, int);
-void wriop_disable_dpmac(int);
-void wriop_enable_dpmac(int);
-u8 wriop_is_enabled_dpmac(int dpmac_id);
-void wriop_set_mdio(int, struct mii_dev *);
-struct mii_dev *wriop_get_mdio(int);
-void wriop_set_phy_address(int, int);
-int wriop_get_phy_address(int);
-void wriop_set_phy_dev(int, struct phy_device *);
-struct phy_device *wriop_get_phy_dev(int);
-phy_interface_t wriop_get_enet_if(int);
+void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl);
+void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if);
+int wriop_disable_dpmac(int dpmac_id);
+int wriop_enable_dpmac(int dpmac_id);
+int wriop_is_enabled_dpmac(int dpmac_id);
+int wriop_set_mdio(int dpmac_id, struct mii_dev *bus);
+struct mii_dev *wriop_get_mdio(int dpmac_id);
+int wriop_set_phy_address(int dpmac_id, int phy_num, int address);
+int wriop_get_phy_address(int dpmac_id, int phy_num);
+int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev);
+struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num);
+phy_interface_t wriop_get_enet_if(int dpmac_id);
 
-void wriop_dpmac_disable(int);
-void wriop_dpmac_enable(int);
-phy_interface_t wriop_dpmac_enet_if(int, int);
-void wriop_init_dpmac_qsgmii(int, int);
+void wriop_dpmac_disable(int dpmac_id);
+void wriop_dpmac_enable(int dpmac_id);
+phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl);
+void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl);
 void wriop_init_rgmii(void);
-void wriop_init_dpmac_enet_if(int , phy_interface_t);
 #endif	/* __LDPAA_WRIOP_H */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e3feb6..d0f51ba 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -43,6 +43,25 @@
 #define dev_warn(dev, fmt, args...)		\
 	printf(fmt, ##args)
 
+#define netdev_emerg(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_alert(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_crit(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_err(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_warn(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_notice(dev, fmt, args...)	\
+	printf(fmt, ##args)
+#define netdev_info(dev, fmt, args...)		\
+	printf(fmt, ##args)
+#define netdev_dbg(dev, fmt, args...)		\
+	debug(fmt, ##args)
+#define netdev_vdbg(dev, fmt, args...)		\
+	debug(fmt, ##args)
+
 #define GFP_ATOMIC ((gfp_t) 0)
 #define GFP_KERNEL ((gfp_t) 0)
 #define GFP_NOFS ((gfp_t) 0)
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
new file mode 100644
index 0000000..0d62aef
--- /dev/null
+++ b/include/linux/if_ether.h
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		Global definitions for the Ethernet IEEE 802.3 interface.
+ *
+ * Version:	@(#)if_ether.h	1.0.1a	02/08/94
+ *
+ * Author:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *		Donald Becker, <becker@super.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *		Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ *
+ *		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.
+ */
+
+#ifndef _UAPI_LINUX_IF_ETHER_H
+#define _UAPI_LINUX_IF_ETHER_H
+
+#include <linux/types.h>
+
+/*
+ *	IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
+ *	and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN	6	/* Octets in one ethernet addr   */
+#define ETH_TLEN	2	/* Octets in ethernet type field */
+#define ETH_HLEN	14	/* Total octets in header.       */
+#define ETH_ZLEN	60	/* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN	1500	/* Max. octets in payload        */
+#define ETH_FRAME_LEN	1514	/* Max. octets in frame sans FCS */
+#define ETH_FCS_LEN	4	/* Octets in the FCS             */
+
+#define ETH_MIN_MTU	68	/* Min IPv4 MTU per RFC791       */
+#define ETH_MAX_MTU	0xFFFFU	/* 65535, same as IP_MAX_MTU     */
+
+/*
+ *	These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP	0x0060	/* Ethernet Loopback packet     */
+#define ETH_P_PUP	0x0200	/* Xerox PUP packet             */
+#define ETH_P_PUPAT	0x0201	/* Xerox PUP Addr Trans packet  */
+#define ETH_P_TSN	0x22F0	/* TSN (IEEE 1722) packet       */
+#define ETH_P_ERSPAN2	0x22EB	/* ERSPAN version 2 (type III)  */
+#define ETH_P_IP	0x0800	/* Internet Protocol packet     */
+#define ETH_P_X25	0x0805	/* CCITT X.25                   */
+#define ETH_P_ARP	0x0806	/* Address Resolution packet    */
+#define ETH_P_BPQ	0x08FF	/* G8BPQ AX.25 Ethernet Packet  */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IEEEPUP	0x0a00	/* Xerox IEEE802.3 PUP packet   */
+#define ETH_P_IEEEPUPAT	0x0a01	/* Xerox IEEE802.3 PUP Addr Trans packet */
+#define ETH_P_BATMAN	0x4305	/* B.A.T.M.A.N.-Advanced packet */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DEC	0x6000	/* DEC Assigned proto           */
+#define ETH_P_DNA_DL	0x6001	/* DEC DNA Dump/Load            */
+#define ETH_P_DNA_RC	0x6002	/* DEC DNA Remote Console       */
+#define ETH_P_DNA_RT	0x6003	/* DEC DNA Routing              */
+#define ETH_P_LAT	0x6004	/* DEC LAT                      */
+#define ETH_P_DIAG	0x6005	/* DEC Diagnostics              */
+#define ETH_P_CUST	0x6006	/* DEC Customer use             */
+#define ETH_P_SCA	0x6007	/* DEC Systems Comms Arch       */
+#define ETH_P_TEB	0x6558	/* Trans Ether Bridging         */
+#define ETH_P_RARP	0x8035	/* Reverse Addr Res packet      */
+#define ETH_P_ATALK	0x809B	/* Appletalk DDP                */
+#define ETH_P_AARP	0x80F3	/* Appletalk AARP               */
+#define ETH_P_8021Q	0x8100	/* 802.1Q VLAN Extended Header  */
+#define ETH_P_ERSPAN	0x88BE	/* ERSPAN type II               */
+#define ETH_P_IPX	0x8137	/* IPX over DIX                 */
+#define ETH_P_IPV6	0x86DD	/* IPv6 over bluebook           */
+#define ETH_P_PAUSE	0x8808	/* IEEE Pause frames. See 802.3 31B */
+#define ETH_P_SLOW	0x8809	/* Slow Protocol. See 802.3ad 43B */
+#define ETH_P_WCCP	0x883E	/* Web-cache coordination */
+				/* protocol defined in */
+				/* draft-wilson-wrec-wccp-v2-00.txt */
+#define ETH_P_MPLS_UC	0x8847	/* MPLS Unicast traffic         */
+#define ETH_P_MPLS_MC	0x8848	/* MPLS Multicast traffic       */
+#define ETH_P_ATMMPOA	0x884c	/* MultiProtocol Over ATM       */
+#define ETH_P_PPP_DISC	0x8863	/* PPPoE discovery messages     */
+#define ETH_P_PPP_SES	0x8864	/* PPPoE session messages       */
+#define ETH_P_LINK_CTL	0x886c	/* HPNA, wlan link local tunnel */
+#define ETH_P_ATMFATE	0x8884	/* Frame-based ATM Transport over Ethernet */
+#define ETH_P_PAE	0x888E	/* Port Access Entity (IEEE 802.1X) */
+#define ETH_P_AOE	0x88A2	/* ATA over Ethernet            */
+#define ETH_P_8021AD	0x88A8	/* 802.1ad Service VLAN         */
+#define ETH_P_802_EX1	0x88B5	/* 802.1 Local Experimental 1.  */
+#define ETH_P_PREAUTH	0x88C7	/* 802.11 Preauthentication     */
+#define ETH_P_TIPC	0x88CA	/* TIPC                         */
+#define ETH_P_MACSEC	0x88E5	/* 802.1ae MACsec               */
+#define ETH_P_8021AH	0x88E7	/* 802.1ah Backbone Service Tag */
+#define ETH_P_MVRP	0x88F5	/* 802.1Q MVRP                  */
+#define ETH_P_1588	0x88F7	/* IEEE 1588 Timesync           */
+#define ETH_P_NCSI	0x88F8	/* NCSI protocol                */
+#define ETH_P_PRP	0x88FB	/* IEC 62439-3 PRP/HSRv0        */
+#define ETH_P_FCOE	0x8906	/* Fibre Channel over Ethernet  */
+#define ETH_P_IBOE	0x8915	/* Infiniband over Ethernet     */
+#define ETH_P_TDLS	0x890D	/* TDLS                         */
+#define ETH_P_FIP	0x8914	/* FCoE Initialization Protocol */
+#define ETH_P_80221	0x8917	/* IEEE 802.21 Media Independent */
+				/* Handover Protocol            */
+#define ETH_P_HSR	0x892F	/* IEC 62439-3 HSRv1            */
+#define ETH_P_NSH	0x894F	/* Network Service Header       */
+#define ETH_P_LOOPBACK	0x9000	/* Ethernet loopback packet, per IEEE 802.3 */
+#define ETH_P_QINQ1	0x9100	/* deprecated QinQ VLAN         */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ2	0x9200	/* deprecated QinQ VLAN         */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ3	0x9300	/* deprecated QinQ VLAN]        */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_EDSA	0xDADA	/* Ethertype DSA                */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IFE	0xED3E	/* ForCES inter-FE LFB type     */
+#define ETH_P_AF_IUCV   0xFBFB	/* IBM af_iucv                  */
+				/* [ NOT AN OFFICIALLY REGISTERED ID ] */
+
+#define ETH_P_802_3_MIN	0x0600	/* If the value in the ethernet type is less */
+				/* than this value then the frame is Ethernet */
+				/* II. Else it is 802.3 */
+
+/*
+ *	Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3	0x0001	/* Dummy type for 802.3 frames  */
+#define ETH_P_AX25	0x0002	/* Dummy protocol id for AX.25  */
+#define ETH_P_ALL	0x0003	/* Every packet (be careful!!!) */
+#define ETH_P_802_2	0x0004	/* 802.2 frames                 */
+#define ETH_P_SNAP	0x0005	/* Internal only                */
+#define ETH_P_DDCMP	0x0006	/* DEC DDCMP: Internal only     */
+#define ETH_P_WAN_PPP	0x0007	/* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP	0x0008	/* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK	0x0009	/* Localtalk pseudo type        */
+#define ETH_P_CAN	0x000C	/* CAN: Controller Area Network */
+#define ETH_P_CANFD	0x000D	/* CANFD: CAN flexible data rate*/
+#define ETH_P_PPPTALK	0x0010	/* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2	0x0011	/* 802.2 frames                 */
+#define ETH_P_MOBITEX	0x0015	/* Mobitex (kaz@cafe.net)       */
+#define ETH_P_CONTROL	0x0016	/* Card specific control frames */
+#define ETH_P_IRDA	0x0017	/* Linux-IrDA                   */
+#define ETH_P_ECONET	0x0018	/* Acorn Econet                 */
+#define ETH_P_HDLC	0x0019	/* HDLC frames                  */
+#define ETH_P_ARCNET	0x001A	/* 1A for ArcNet :-)            */
+#define ETH_P_DSA	0x001B	/* Distributed Switch Arch      */
+#define ETH_P_TRAILER	0x001C	/* Trailer switch tagging       */
+#define ETH_P_PHONET	0x00F5	/* Nokia Phonet frames          */
+#define ETH_P_IEEE802154 0x00F6	/* IEEE802.15.4 frame           */
+#define ETH_P_CAIF	0x00F7	/* ST-Ericsson CAIF protocol    */
+#define ETH_P_XDSA	0x00F8	/* Multiplexed DSA protocol     */
+#define ETH_P_MAP	0x00F9	/* Qualcomm multiplexing and    */
+				/* aggregation protocol         */
+
+/* The following macros come from Linux kernel include/linux/if_vlan.h */
+
+#define VLAN_HLEN	4	/* The additional bytes required by VLAN */
+				/* (in addition to the Ethernet header)  */
+#define VLAN_ETH_HLEN	18	/* Total octets in header.               */
+#define VLAN_ETH_ZLEN	64	/* Min. octets in frame sans FCS         */
+
+/*
+ * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
+ */
+#define VLAN_ETH_DATA_LEN	1500	/* Max. octets in payload        */
+#define VLAN_ETH_FRAME_LEN	1518	/* Max. octets in frame sans FCS */
+
+#define VLAN_PRIO_MASK		0xe000	/* Priority Code Point           */
+#define VLAN_PRIO_SHIFT		13
+#define VLAN_CFI_MASK		0x1000	/* Canonical Format Indicator    */
+#define VLAN_TAG_PRESENT	VLAN_CFI_MASK
+#define VLAN_VID_MASK		0x0fff	/* VLAN Identifier               */
+#define VLAN_N_VID		4096
+
+#endif /* _UAPI_LINUX_IF_ETHER_H */
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index ea20608..6e821d9 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * linux/mdio.h: definitions for MDIO (clause 45) transceivers
  * Copyright 2006-2009 Solarflare Communications Inc.
@@ -42,7 +43,11 @@
 #define MDIO_PKGID2		15
 #define MDIO_AN_ADVERTISE	16	/* AN advertising (base page) */
 #define MDIO_AN_LPA		19	/* AN LP abilities (base page) */
+#define MDIO_PCS_EEE_ABLE	20	/* EEE Capability register */
+#define MDIO_PCS_EEE_WK_ERR	22	/* EEE wake error counter */
 #define MDIO_PHYXS_LNSTAT	24	/* PHY XGXS lane state */
+#define MDIO_AN_EEE_ADV		60	/* EEE advertisement */
+#define MDIO_AN_EEE_LPABLE	61	/* EEE link partner ability */
 
 /* Media-dependent registers. */
 #define MDIO_PMA_10GBT_SWAPPOL	130	/* 10GBASE-T pair swap & polarity */
@@ -55,7 +60,6 @@
 #define MDIO_PCS_10GBRT_STAT2	33	/* 10GBASE-R/-T PCS status 2 */
 #define MDIO_AN_10GBT_CTRL	32	/* 10GBASE-T auto-negotiation control */
 #define MDIO_AN_10GBT_STAT	33	/* 10GBASE-T auto-negotiation status */
-#define MDIO_AN_EEE_ADV		60	/* EEE advertisement */
 
 /* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
 #define MDIO_PMA_LASI_RXCTRL	0x9000	/* RX_ALARM control */
@@ -81,6 +85,7 @@
 #define MDIO_AN_CTRL1_RESTART		BMCR_ANRESTART
 #define MDIO_AN_CTRL1_ENABLE		BMCR_ANENABLE
 #define MDIO_AN_CTRL1_XNP		0x2000	/* Enable extended next page */
+#define MDIO_PCS_CTRL1_CLKSTOP_EN	0x400	/* Stop the clock during LPI */
 
 /* 10 Gb/s */
 #define MDIO_CTRL1_SPEED10G		(MDIO_CTRL1_SPEEDSELEXT | 0x00)
@@ -245,9 +250,25 @@
 #define MDIO_AN_10GBT_STAT_MS		0x4000	/* Master/slave config */
 #define MDIO_AN_10GBT_STAT_MSFLT	0x8000	/* Master/slave config fault */
 
-/* AN EEE Advertisement register. */
-#define MDIO_AN_EEE_ADV_100TX		0x0002	/* Advertise 100TX EEE cap */
-#define MDIO_AN_EEE_ADV_1000T		0x0004	/* Advertise 1000T EEE cap */
+/* EEE Supported/Advertisement/LP Advertisement registers.
+ *
+ * EEE capability Register (3.20), Advertisement (7.60) and
+ * Link partner ability (7.61) registers have and can use the same identical
+ * bit masks.
+ */
+#define MDIO_AN_EEE_ADV_100TX	0x0002	/* Advertise 100TX EEE cap */
+#define MDIO_AN_EEE_ADV_1000T	0x0004	/* Advertise 1000T EEE cap */
+/* Note: the two defines above can be potentially used by the user-land
+ * and cannot remove them now.
+ * So, we define the new generic MDIO_EEE_100TX and MDIO_EEE_1000T macros
+ * using the previous ones (that can be considered obsolete).
+ */
+#define MDIO_EEE_100TX		MDIO_AN_EEE_ADV_100TX	/* 100TX EEE cap */
+#define MDIO_EEE_1000T		MDIO_AN_EEE_ADV_1000T	/* 1000T EEE cap */
+#define MDIO_EEE_10GT		0x0008	/* 10GT EEE cap */
+#define MDIO_EEE_1000KX		0x0010	/* 1000KX EEE cap */
+#define MDIO_EEE_10GKX4		0x0020	/* 10G KX4 EEE cap */
+#define MDIO_EEE_10GKR		0x0040	/* 10G KR EEE cap */
 
 /* LASI RX_ALARM control/status registers. */
 #define MDIO_PMA_LASI_RX_PHYXSLFLT	0x0001	/* PHY XS RX local fault */
@@ -281,4 +302,9 @@
 #define MDIO_DEVAD_NONE			(-1)
 #define MDIO_EMULATE_C22		4
 
+static inline __u16 mdio_phy_id_c45(int prtad, int devad)
+{
+	return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
+}
+
 #endif /* __LINUX_MDIO_H__ */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 19afb74..21db032 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * linux/mii.h: definitions for MII-compatible transceivers
  * Originally drivers/net/sunhme.h.
@@ -9,53 +10,55 @@
 #define __LINUX_MII_H__
 
 /* Generic MII registers. */
-
-#define MII_BMCR	    0x00	/* Basic mode control register */
-#define MII_BMSR	    0x01	/* Basic mode status register  */
-#define MII_PHYSID1	    0x02	/* PHYS ID 1		       */
-#define MII_PHYSID2	    0x03	/* PHYS ID 2		       */
-#define MII_ADVERTISE	    0x04	/* Advertisement control reg   */
-#define MII_LPA		    0x05	/* Link partner ability reg    */
-#define MII_EXPANSION	    0x06	/* Expansion register	       */
-#define MII_CTRL1000	    0x09	/* 1000BASE-T control	       */
-#define MII_STAT1000	    0x0a	/* 1000BASE-T status	       */
-#define MII_ESTATUS	    0x0f	/* Extended Status */
-#define MII_DCOUNTER	    0x12	/* Disconnect counter	       */
-#define MII_FCSCOUNTER	    0x13	/* False carrier counter       */
-#define MII_NWAYTEST	    0x14	/* N-way auto-neg test reg     */
-#define MII_RERRCOUNTER     0x15	/* Receive error counter       */
-#define MII_SREVISION	    0x16	/* Silicon revision	       */
-#define MII_RESV1	    0x17	/* Reserved...		       */
-#define MII_LBRERROR	    0x18	/* Lpback, rx, bypass error    */
-#define MII_PHYADDR	    0x19	/* PHY address		       */
-#define MII_RESV2	    0x1a	/* Reserved...		       */
-#define MII_TPISTATUS	    0x1b	/* TPI status for 10mbps       */
-#define MII_NCONFIG	    0x1c	/* Network interface config    */
+#define MII_BMCR		0x00	/* Basic mode control register */
+#define MII_BMSR		0x01	/* Basic mode status register  */
+#define MII_PHYSID1		0x02	/* PHYS ID 1                   */
+#define MII_PHYSID2		0x03	/* PHYS ID 2                   */
+#define MII_ADVERTISE		0x04	/* Advertisement control reg   */
+#define MII_LPA			0x05	/* Link partner ability reg    */
+#define MII_EXPANSION		0x06	/* Expansion register          */
+#define MII_CTRL1000		0x09	/* 1000BASE-T control          */
+#define MII_STAT1000		0x0a	/* 1000BASE-T status           */
+#define MII_MMD_CTRL		0x0d	/* MMD Access Control Register */
+#define MII_MMD_DATA		0x0e	/* MMD Access Data Register */
+#define MII_ESTATUS		0x0f	/* Extended Status             */
+#define MII_DCOUNTER		0x12	/* Disconnect counter          */
+#define MII_FCSCOUNTER		0x13	/* False carrier counter       */
+#define MII_NWAYTEST		0x14	/* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER		0x15	/* Receive error counter       */
+#define MII_SREVISION		0x16	/* Silicon revision            */
+#define MII_RESV1		0x17	/* Reserved...                 */
+#define MII_LBRERROR		0x18	/* Lpback, rx, bypass error    */
+#define MII_PHYADDR		0x19	/* PHY address                 */
+#define MII_RESV2		0x1a	/* Reserved...                 */
+#define MII_TPISTATUS		0x1b	/* TPI status for 10mbps       */
+#define MII_NCONFIG		0x1c	/* Network interface config    */
 
 /* Basic mode control register. */
-#define BMCR_RESV		0x003f	/* Unused...		       */
-#define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)	       */
-#define BMCR_CTST		0x0080	/* Collision test	       */
-#define BMCR_FULLDPLX		0x0100	/* Full duplex		       */
+#define BMCR_RESV		0x003f	/* Unused...                   */
+#define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)         */
+#define BMCR_CTST		0x0080	/* Collision test              */
+#define BMCR_FULLDPLX		0x0100	/* Full duplex                 */
 #define BMCR_ANRESTART		0x0200	/* Auto negotiation restart    */
-#define BMCR_ISOLATE		0x0400	/* Disconnect DP83840 from MII */
-#define BMCR_PDOWN		0x0800	/* Powerdown the DP83840       */
+#define BMCR_ISOLATE		0x0400	/* Isolate data paths from MII */
+#define BMCR_PDOWN		0x0800	/* Enable low power state      */
 #define BMCR_ANENABLE		0x1000	/* Enable auto negotiation     */
-#define BMCR_SPEED100		0x2000	/* Select 100Mbps	       */
-#define BMCR_LOOPBACK		0x4000	/* TXD loopback bits	       */
-#define BMCR_RESET		0x8000	/* Reset the DP83840	       */
+#define BMCR_SPEED100		0x2000	/* Select 100Mbps              */
+#define BMCR_LOOPBACK		0x4000	/* TXD loopback bits           */
+#define BMCR_RESET		0x8000	/* Reset to default state      */
+#define BMCR_SPEED10		0x0000	/* Select 10Mbps               */
 
 /* Basic mode status register. */
-#define BMSR_ERCAP		0x0001	/* Ext-reg capability	       */
-#define BMSR_JCD		0x0002	/* Jabber detected	       */
-#define BMSR_LSTATUS		0x0004	/* Link status		       */
+#define BMSR_ERCAP		0x0001	/* Ext-reg capability          */
+#define BMSR_JCD		0x0002	/* Jabber detected             */
+#define BMSR_LSTATUS		0x0004	/* Link status                 */
 #define BMSR_ANEGCAPABLE	0x0008	/* Able to do auto-negotiation */
 #define BMSR_RFAULT		0x0010	/* Remote fault detected       */
 #define BMSR_ANEGCOMPLETE	0x0020	/* Auto-negotiation complete   */
-#define BMSR_RESV		0x00c0	/* Unused...		       */
-#define BMSR_ESTATEN		0x0100	/* Extended Status in R15 */
-#define BMSR_100HALF2		0x0200	/* Can do 100BASE-T2 HDX */
-#define BMSR_100FULL2		0x0400	/* Can do 100BASE-T2 FDX */
+#define BMSR_RESV		0x00c0	/* Unused...                   */
+#define BMSR_ESTATEN		0x0100	/* Extended Status in R15      */
+#define BMSR_100HALF2		0x0200	/* Can do 100BASE-T2 HDX       */
+#define BMSR_100FULL2		0x0400	/* Can do 100BASE-T2 FDX       */
 #define BMSR_10HALF		0x0800	/* Can do 10mbps, half-duplex  */
 #define BMSR_10FULL		0x1000	/* Can do 10mbps, full-duplex  */
 #define BMSR_100HALF		0x2000	/* Can do 100mbps, half-duplex */
@@ -63,7 +66,7 @@
 #define BMSR_100BASE4		0x8000	/* Can do 100mbps, 4k packets  */
 
 /* Advertisement control register. */
-#define ADVERTISE_SLCT		0x001f	/* Selector bits	       */
+#define ADVERTISE_SLCT		0x001f	/* Selector bits               */
 #define ADVERTISE_CSMA		0x0001	/* Only selector supported     */
 #define ADVERTISE_10HALF	0x0020	/* Try for 10mbps half-duplex  */
 #define ADVERTISE_1000XFULL	0x0020	/* Try for 1000BASE-X full-duplex */
@@ -72,19 +75,19 @@
 #define ADVERTISE_100HALF	0x0080	/* Try for 100mbps half-duplex */
 #define ADVERTISE_1000XPAUSE	0x0080	/* Try for 1000BASE-X pause    */
 #define ADVERTISE_100FULL	0x0100	/* Try for 100mbps full-duplex */
-#define ADVERTISE_1000XPSE_ASYM 0x0100	/* Try for 1000BASE-X asym pause */
+#define ADVERTISE_1000XPSE_ASYM	0x0100	/* Try for 1000BASE-X asym pause */
 #define ADVERTISE_100BASE4	0x0200	/* Try for 100mbps 4k packets  */
-#define ADVERTISE_PAUSE_CAP	0x0400	/* Try for pause	       */
+#define ADVERTISE_PAUSE_CAP	0x0400	/* Try for pause               */
 #define ADVERTISE_PAUSE_ASYM	0x0800	/* Try for asymetric pause     */
-#define ADVERTISE_RESV		0x1000	/* Unused...		       */
+#define ADVERTISE_RESV		0x1000	/* Unused...                   */
 #define ADVERTISE_RFAULT	0x2000	/* Say we can detect faults    */
 #define ADVERTISE_LPACK		0x4000	/* Ack link partners response  */
-#define ADVERTISE_NPAGE		0x8000	/* Next page bit	       */
+#define ADVERTISE_NPAGE		0x8000	/* Next page bit               */
 
-#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
-			ADVERTISE_CSMA)
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
-		       ADVERTISE_100HALF | ADVERTISE_100FULL)
+#define ADVERTISE_FULL		(ADVERTISE_100FULL | ADVERTISE_10FULL | \
+				 ADVERTISE_CSMA)
+#define ADVERTISE_ALL		(ADVERTISE_10HALF | ADVERTISE_10FULL | \
+				 ADVERTISE_100HALF | ADVERTISE_100FULL)
 
 /* Link partner ability register. */
 #define LPA_SLCT		0x001f	/* Same as advertise selector  */
@@ -97,12 +100,12 @@
 #define LPA_100FULL		0x0100	/* Can do 100mbps full-duplex  */
 #define LPA_1000XPAUSE_ASYM	0x0100	/* Can do 1000BASE-X pause asym*/
 #define LPA_100BASE4		0x0200	/* Can do 100mbps 4k packets   */
-#define LPA_PAUSE_CAP		0x0400	/* Can pause		       */
+#define LPA_PAUSE_CAP		0x0400	/* Can pause                   */
 #define LPA_PAUSE_ASYM		0x0800	/* Can pause asymetrically     */
-#define LPA_RESV		0x1000	/* Unused...		       */
+#define LPA_RESV		0x1000	/* Unused...                   */
 #define LPA_RFAULT		0x2000	/* Link partner faulted        */
 #define LPA_LPACK		0x4000	/* Link partner acked us       */
-#define LPA_NPAGE		0x8000	/* Next page bit	       */
+#define LPA_NPAGE		0x8000	/* Next page bit               */
 
 #define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
 #define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
@@ -113,21 +116,23 @@
 #define EXPANSION_ENABLENPAGE	0x0004	/* This enables npage words    */
 #define EXPANSION_NPCAPABLE	0x0008	/* Link partner supports npage */
 #define EXPANSION_MFAULTS	0x0010	/* Multiple faults detected    */
-#define EXPANSION_RESV		0xffe0	/* Unused...		       */
+#define EXPANSION_RESV		0xffe0	/* Unused...                   */
 
 #define ESTATUS_1000_XFULL	0x8000	/* Can do 1000BX Full */
 #define ESTATUS_1000_XHALF	0x4000	/* Can do 1000BX Half */
-#define ESTATUS_1000_TFULL	0x2000	/* Can do 1000BT Full */
-#define ESTATUS_1000_THALF	0x1000	/* Can do 1000BT Half */
+#define ESTATUS_1000_TFULL	0x2000	/* Can do 1000BT Full          */
+#define ESTATUS_1000_THALF	0x1000	/* Can do 1000BT Half          */
 
 /* N-way test register. */
-#define NWAYTEST_RESV1		0x00ff	/* Unused...		       */
+#define NWAYTEST_RESV1		0x00ff	/* Unused...                   */
 #define NWAYTEST_LOOPBACK	0x0100	/* Enable loopback for N-way   */
-#define NWAYTEST_RESV2		0xfe00	/* Unused...		       */
+#define NWAYTEST_RESV2		0xfe00	/* Unused...                   */
 
 /* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL	0x0200	/* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF	0x0100	/* Advertise 1000BASE-T half duplex */
+#define ADVERTISE_1000FULL	0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF	0x0100  /* Advertise 1000BASE-T half duplex */
+#define CTL1000_AS_MASTER	0x0800
+#define CTL1000_ENABLE_MASTER	0x1000
 
 /* 1000BASE-T Status register */
 #define LPA_1000LOCALRXOK	0x2000	/* Link partner local receiver status */
@@ -139,6 +144,13 @@
 #define FLOW_CTRL_TX		0x01
 #define FLOW_CTRL_RX		0x02
 
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK	0x1f	/* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_ADDR	0x0000	/* Address */
+#define MII_MMD_CTRL_NOINCR	0x4000	/* no post increment */
+#define MII_MMD_CTRL_INCR_RDWT	0x8000	/* post increment on reads & writes */
+#define MII_MMD_CTRL_INCR_ON_WT	0xC000	/* post increment on writes only */
+
 /**
  * mii_nway_result
  * @negotiated: value of MII ANAR and'd with ANLPAR
diff --git a/include/net.h b/include/net.h
index 2b2deb5..51c099d 100644
--- a/include/net.h
+++ b/include/net.h
@@ -14,6 +14,7 @@
 
 #include <asm/cache.h>
 #include <asm/byteorder.h>	/* for nton* / ntoh* stuff */
+#include <linux/if_ether.h>
 
 #define DEBUG_LL_STATE 0	/* Link local state machine changes */
 #define DEBUG_DEV_PKT 0		/* Packets or info directed to the device */
@@ -596,7 +597,8 @@
 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
 
 /* Set IP header */
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source);
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+		       u16 pkt_len, u8 proto);
 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
 				int sport, int len);
 
@@ -635,6 +637,7 @@
 void net_set_udp_handler(rxhand_f *);	/* Set UDP RX packet handler */
 rxhand_f *net_get_arp_handler(void);	/* Get ARP RX packet handler */
 void net_set_arp_handler(rxhand_f *);	/* Set ARP RX packet handler */
+bool arp_is_waiting(void);		/* Waiting for ARP reply? */
 void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
 void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
 
@@ -653,6 +656,14 @@
 	net_state = state;
 }
 
+/*
+ * net_get_async_tx_pkt_buf - Get a packet buffer that is not in use for
+ *			      sending an asynchronous reply
+ *
+ * returns - ptr to packet buffer
+ */
+uchar * net_get_async_tx_pkt_buf(void);
+
 /* Transmit a packet */
 static inline void net_send_packet(uchar *pkt, int len)
 {
@@ -670,6 +681,9 @@
  * @param sport Source UDP port
  * @param payload_len Length of data after the UDP header
  */
+int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
+		       int payload_len, int proto, u8 action, u32 tcp_seq_num,
+		       u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
 			int sport, int payload_len);
 
diff --git a/include/phy_interface.h b/include/phy_interface.h
index 0760d65..c682318 100644
--- a/include/phy_interface.h
+++ b/include/phy_interface.h
@@ -27,6 +27,10 @@
 	PHY_INTERFACE_MODE_RXAUI,
 	PHY_INTERFACE_MODE_SFI,
 	PHY_INTERFACE_MODE_INTERNAL,
+	PHY_INTERFACE_MODE_25G_AUI,
+	PHY_INTERFACE_MODE_XLAUI,
+	PHY_INTERFACE_MODE_CAUI2,
+	PHY_INTERFACE_MODE_CAUI4,
 	PHY_INTERFACE_MODE_NONE,	/* Must be last */
 
 	PHY_INTERFACE_MODE_COUNT,
@@ -50,6 +54,10 @@
 	[PHY_INTERFACE_MODE_RXAUI]		= "rxaui",
 	[PHY_INTERFACE_MODE_SFI]		= "sfi",
 	[PHY_INTERFACE_MODE_INTERNAL]		= "internal",
+	[PHY_INTERFACE_MODE_25G_AUI]		= "25g-aui",
+	[PHY_INTERFACE_MODE_XLAUI]		= "xlaui4",
+	[PHY_INTERFACE_MODE_CAUI2]		= "caui2",
+	[PHY_INTERFACE_MODE_CAUI4]		= "caui4",
 	[PHY_INTERFACE_MODE_NONE]		= "",
 };
 
diff --git a/include/usb_ether.h b/include/usb_ether.h
index 49f47d3..e85acad 100644
--- a/include/usb_ether.h
+++ b/include/usb_ether.h
@@ -8,16 +8,6 @@
 
 #include <net.h>
 
-/*
- *	IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
- *	and FCS/CRC (frame check sequence).
- */
-#define ETH_ALEN	6		/* Octets in one ethernet addr	 */
-#define ETH_HLEN	14		/* Total octets in header.	 */
-#define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
-#define ETH_FRAME_LEN	PKTSIZE_ALIGN	/* Max. octets in frame sans FCS */
-
 /* TODO(sjg@chromium.org): Remove @pusb_dev when all boards use CONFIG_DM_ETH */
 struct ueth_data {
 	/* eth info */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index b1b3925..a420ba1 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -15,7 +15,6 @@
 #include <serial.h>
 #include <asm/sections.h>
 #include <linux/ctype.h>
-#include <linux/ioport.h>
 #include <linux/lzo.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -1099,34 +1098,41 @@
 
 #if defined(CONFIG_NR_DRAM_BANKS)
 
-static ofnode get_next_memory_node(ofnode mem)
+static int get_next_memory_node(const void *blob, int mem)
 {
 	do {
-		mem = ofnode_by_prop_value(mem, "device_type", "memory", 7);
-	} while (ofnode_valid(mem) && !ofnode_is_available(mem));
+		mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
+						    "device_type", "memory", 7);
+	} while (!fdtdec_get_is_enabled(blob, mem));
 
 	return mem;
 }
 
 int fdtdec_setup_memory_banksize(void)
 {
-	int bank, reg = 0;
-	struct resource res;
-	ofnode mem;
+	int bank, ret, mem, reg = 0;
+	struct fdt_resource res;
 
-	mem = get_next_memory_node(ofnode_null());
-	if (!ofnode_valid(mem))
-		goto missing_node;
+	mem = get_next_memory_node(gd->fdt_blob, -1);
+	if (mem < 0) {
+		debug("%s: Missing /memory node\n", __func__);
+		return -EINVAL;
+	}
 
 	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
-		while (ofnode_read_resource(mem, reg++, &res)) {
+		ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+		if (ret == -FDT_ERR_NOTFOUND) {
 			reg = 0;
-			mem = get_next_memory_node(mem);
-			if (!ofnode_valid(mem)) {
-				if (bank)
-					return 0;
-				goto missing_node;
-			}
+			mem = get_next_memory_node(gd->fdt_blob, mem);
+			if (mem == -FDT_ERR_NOTFOUND)
+				break;
+
+			ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+			if (ret == -FDT_ERR_NOTFOUND)
+				break;
+		}
+		if (ret != 0) {
+			return -EINVAL;
 		}
 
 		gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
@@ -1140,10 +1146,6 @@
 	}
 
 	return 0;
-
-missing_node:
-	debug("%s: Missing /memory node\n", __func__);
-	return -EINVAL;
 }
 #endif
 
diff --git a/net/arp.c b/net/arp.c
index b8a7168..b49c3d3 100644
--- a/net/arp.c
+++ b/net/arp.c
@@ -34,8 +34,7 @@
 int		arp_wait_tx_packet_size;
 ulong		arp_wait_timer_start;
 int		arp_wait_try;
-
-static uchar   *arp_tx_packet;	/* THE ARP transmit packet */
+uchar	       *arp_tx_packet; /* THE ARP transmit packet */
 static uchar	arp_tx_packet_buf[PKTSIZE_ALIGN + PKTALIGN];
 
 void arp_init(void)
@@ -100,7 +99,7 @@
 {
 	ulong t;
 
-	if (!net_arp_wait_packet_ip.s_addr)
+	if (!arp_is_waiting())
 		return 0;
 
 	t = get_timer(0);
@@ -126,6 +125,7 @@
 	struct arp_hdr *arp;
 	struct in_addr reply_ip_addr;
 	int eth_hdr_size;
+	uchar *tx_packet;
 
 	/*
 	 * We have to deal with two types of ARP packets:
@@ -182,13 +182,14 @@
 		    (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr))
 			udelay(5000);
 #endif
-		memcpy(net_tx_packet, et, eth_hdr_size + ARP_HDR_SIZE);
-		net_send_packet(net_tx_packet, eth_hdr_size + ARP_HDR_SIZE);
+		tx_packet = net_get_async_tx_pkt_buf();
+		memcpy(tx_packet, et, eth_hdr_size + ARP_HDR_SIZE);
+		net_send_packet(tx_packet, eth_hdr_size + ARP_HDR_SIZE);
 		return;
 
 	case ARPOP_REPLY:		/* arp reply */
-		/* are we waiting for a reply */
-		if (!net_arp_wait_packet_ip.s_addr)
+		/* are we waiting for a reply? */
+		if (!arp_is_waiting())
 			break;
 
 #ifdef CONFIG_KEEP_SERVERADDR
@@ -233,3 +234,8 @@
 		return;
 	}
 }
+
+bool arp_is_waiting(void)
+{
+	return !!net_arp_wait_packet_ip.s_addr;
+}
diff --git a/net/arp.h b/net/arp.h
index afb8695..25b3c00 100644
--- a/net/arp.h
+++ b/net/arp.h
@@ -20,6 +20,7 @@
 extern int arp_wait_tx_packet_size;
 extern ulong arp_wait_timer_start;
 extern int arp_wait_try;
+extern uchar *arp_tx_packet;
 
 void arp_init(void);
 void arp_request(void);
diff --git a/net/net.c b/net/net.c
index 31cf306..a5a216c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -799,9 +799,25 @@
 	}
 }
 
+uchar *net_get_async_tx_pkt_buf(void)
+{
+	if (arp_is_waiting())
+		return arp_tx_packet; /* If we are waiting, we already sent */
+	else
+		return net_tx_packet;
+}
+
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
 		int payload_len)
 {
+	return net_send_ip_packet(ether, dest, dport, sport, payload_len,
+				  IPPROTO_UDP, 0, 0, 0);
+}
+
+int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
+		       int payload_len, int proto, u8 action, u32 tcp_seq_num,
+		       u32 tcp_ack_num)
+{
 	uchar *pkt;
 	int eth_hdr_size;
 	int pkt_hdr_size;
@@ -822,9 +838,16 @@
 	pkt = (uchar *)net_tx_packet;
 
 	eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
-	pkt += eth_hdr_size;
-	net_set_udp_header(pkt, dest, dport, sport, payload_len);
-	pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
+
+	switch (proto) {
+	case IPPROTO_UDP:
+		net_set_udp_header(pkt + eth_hdr_size, dest, dport, sport,
+				   payload_len);
+		pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	/* if MAC address was not discovered yet, do an ARP request */
 	if (memcmp(ether, net_null_ethaddr, 6) == 0) {
@@ -1455,7 +1478,8 @@
 	}
 }
 
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+		       u16 pkt_len, u8 proto)
 {
 	struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
 
@@ -1465,7 +1489,8 @@
 	/* IP_HDR_SIZE / 4 (not including UDP) */
 	ip->ip_hl_v  = 0x45;
 	ip->ip_tos   = 0;
-	ip->ip_len   = htons(IP_HDR_SIZE);
+	ip->ip_len   = htons(pkt_len);
+	ip->ip_p     = proto;
 	ip->ip_id    = htons(net_ip_id++);
 	ip->ip_off   = htons(IP_FLAGS_DFRAG);	/* Don't fragment */
 	ip->ip_ttl   = 255;
@@ -1474,6 +1499,8 @@
 	net_copy_ip((void *)&ip->ip_src, &source);
 	/* already in network byte order */
 	net_copy_ip((void *)&ip->ip_dst, &dest);
+
+	ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
 }
 
 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
@@ -1489,10 +1516,8 @@
 	if (len & 1)
 		pkt[IP_UDP_HDR_SIZE + len] = 0;
 
-	net_set_ip_header(pkt, dest, net_ip);
-	ip->ip_len   = htons(IP_UDP_HDR_SIZE + len);
-	ip->ip_p     = IPPROTO_UDP;
-	ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
+	net_set_ip_header(pkt, dest, net_ip, IP_UDP_HDR_SIZE + len,
+			  IPPROTO_UDP);
 
 	ip->udp_src  = htons(sport);
 	ip->udp_dst  = htons(dport);
diff --git a/net/ping.c b/net/ping.c
index 3e5461a..633c942 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -22,14 +22,9 @@
 	/*
 	 *	Construct an IP and ICMP header.
 	 */
-	struct ip_hdr *ip = (struct ip_hdr *)pkt;
 	struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
 
-	net_set_ip_header(pkt, dest, net_ip);
-
-	ip->ip_len   = htons(IP_ICMP_HDR_SIZE);
-	ip->ip_p     = IPPROTO_ICMP;
-	ip->ip_sum   = compute_ip_checksum(ip, IP_HDR_SIZE);
+	net_set_ip_header(pkt, dest, net_ip, IP_ICMP_HDR_SIZE, IPPROTO_ICMP);
 
 	icmp->type = ICMP_ECHO_REQUEST;
 	icmp->code = 0;
@@ -84,6 +79,7 @@
 	struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
 	struct in_addr src_ip;
 	int eth_hdr_size;
+	uchar *tx_packet;
 
 	switch (icmph->type) {
 	case ICMP_ECHO_REPLY:
@@ -107,8 +103,10 @@
 		icmph->type = ICMP_ECHO_REPLY;
 		icmph->checksum = 0;
 		icmph->checksum = compute_ip_checksum(icmph, len - IP_HDR_SIZE);
-		memcpy(net_tx_packet, et, eth_hdr_size + len);
-		net_send_packet(net_tx_packet, eth_hdr_size + len);
+
+		tx_packet = net_get_async_tx_pkt_buf();
+		memcpy(tx_packet, et, eth_hdr_size + len);
+		net_send_packet(tx_packet, eth_hdr_size + len);
 		return;
 /*	default:
 		return;*/
diff --git a/test/dm/eth.c b/test/dm/eth.c
index 1a7684a..850eabb 100644
--- a/test/dm/eth.c
+++ b/test/dm/eth.c
@@ -258,3 +258,173 @@
 	return retval;
 }
 DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
+
+static int sb_check_arp_reply(struct udevice *dev, void *packet,
+			      unsigned int len)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth = packet;
+	struct arp_hdr *arp;
+	/* Used by all of the ut_assert macros */
+	struct unit_test_state *uts = priv->priv;
+
+	if (ntohs(eth->et_protlen) != PROT_ARP)
+		return 0;
+
+	arp = packet + ETHER_HDR_SIZE;
+
+	if (ntohs(arp->ar_op) != ARPOP_REPLY)
+		return 0;
+
+	/* This test would be worthless if we are not waiting */
+	ut_assert(arp_is_waiting());
+
+	/* Validate response */
+	ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0);
+	ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+	ut_assert(eth->et_protlen == htons(PROT_ARP));
+
+	ut_assert(arp->ar_hrd == htons(ARP_ETHER));
+	ut_assert(arp->ar_pro == htons(PROT_IP));
+	ut_assert(arp->ar_hln == ARP_HLEN);
+	ut_assert(arp->ar_pln == ARP_PLEN);
+	ut_assert(memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) == 0);
+	ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
+	ut_assert(memcmp(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+	ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
+		  string_to_ip("1.1.2.4").s_addr);
+
+	return 0;
+}
+
+static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
+				     unsigned int len)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth = packet;
+	struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+	int ret;
+
+	/*
+	 * If we are about to generate a reply to ARP, first inject a request
+	 * from another host
+	 */
+	if (ntohs(eth->et_protlen) == PROT_ARP &&
+	    ntohs(arp->ar_op) == ARPOP_REQUEST) {
+		/* Make sure sandbox_eth_recv_arp_req() knows who is asking */
+		priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
+
+		ret = sandbox_eth_recv_arp_req(dev);
+		if (ret)
+			return ret;
+	}
+
+	sandbox_eth_arp_req_to_reply(dev, packet, len);
+	sandbox_eth_ping_req_to_reply(dev, packet, len);
+
+	return sb_check_arp_reply(dev, packet, len);
+}
+
+static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
+{
+	net_ping_ip = string_to_ip("1.1.2.2");
+
+	sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
+	/* Used by all of the ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, uts);
+
+	env_set("ethact", "eth@10002000");
+	ut_assertok(net_loop(PING));
+	ut_asserteq_str("eth@10002000", env_get("ethact"));
+
+	sandbox_eth_set_tx_handler(0, NULL);
+
+	return 0;
+}
+
+DM_TEST(dm_test_eth_async_arp_reply, DM_TESTF_SCAN_FDT);
+
+static int sb_check_ping_reply(struct udevice *dev, void *packet,
+			       unsigned int len)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth = packet;
+	struct ip_udp_hdr *ip;
+	struct icmp_hdr *icmp;
+	/* Used by all of the ut_assert macros */
+	struct unit_test_state *uts = priv->priv;
+
+	if (ntohs(eth->et_protlen) != PROT_IP)
+		return 0;
+
+	ip = packet + ETHER_HDR_SIZE;
+
+	if (ip->ip_p != IPPROTO_ICMP)
+		return 0;
+
+	icmp = (struct icmp_hdr *)&ip->udp_src;
+
+	if (icmp->type != ICMP_ECHO_REPLY)
+		return 0;
+
+	/* This test would be worthless if we are not waiting */
+	ut_assert(arp_is_waiting());
+
+	/* Validate response */
+	ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0);
+	ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0);
+	ut_assert(eth->et_protlen == htons(PROT_IP));
+
+	ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
+	ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
+		  string_to_ip("1.1.2.4").s_addr);
+
+	return 0;
+}
+
+static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
+				      unsigned int len)
+{
+	struct eth_sandbox_priv *priv = dev_get_priv(dev);
+	struct ethernet_hdr *eth = packet;
+	struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+	int ret;
+
+	/*
+	 * If we are about to generate a reply to ARP, first inject a request
+	 * from another host
+	 */
+	if (ntohs(eth->et_protlen) == PROT_ARP &&
+	    ntohs(arp->ar_op) == ARPOP_REQUEST) {
+		/* Make sure sandbox_eth_recv_arp_req() knows who is asking */
+		priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
+
+		ret = sandbox_eth_recv_ping_req(dev);
+		if (ret)
+			return ret;
+	}
+
+	sandbox_eth_arp_req_to_reply(dev, packet, len);
+	sandbox_eth_ping_req_to_reply(dev, packet, len);
+
+	return sb_check_ping_reply(dev, packet, len);
+}
+
+static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
+{
+	net_ping_ip = string_to_ip("1.1.2.2");
+
+	sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
+	/* Used by all of the ut_assert macros in the tx_handler */
+	sandbox_eth_set_priv(0, uts);
+
+	env_set("ethact", "eth@10002000");
+	ut_assertok(net_loop(PING));
+	ut_asserteq_str("eth@10002000", env_get("ethact"));
+
+	sandbox_eth_set_tx_handler(0, NULL);
+
+	return 0;
+}
+
+DM_TEST(dm_test_eth_async_ping_reply, DM_TESTF_SCAN_FDT);